@@ -179,7 +179,7 @@ void loadUDPTTY()
179179 sleep (3 );
180180}
181181
182- inline void udptty_start ()
182+ void udptty_start ()
183183{
184184 if (loadDEV9 ())
185185 loadUDPTTY ();
@@ -264,7 +264,7 @@ int LoadIOX(void)
264264 return 0 ;
265265}
266266
267- inline void load_filexio ()
267+ void load_filexio ()
268268{
269269 if (LoadIOX () < 0 ) {
270270 GS_BGCOLOUR (BGR_BLUE );
@@ -273,7 +273,7 @@ inline void load_filexio()
273273}
274274#endif
275275
276- inline void bdm_usb ()
276+ void bdm_usb ()
277277{
278278 int j = LoadUSBIRX ();
279279 if (j != 0 ) {
@@ -284,4 +284,188 @@ inline void bdm_usb()
284284 sleep (1 );
285285#endif
286286 }
287- }
287+ }
288+
289+ #ifdef DEV9
290+ int dev9_loaded = 0 ;
291+ int loadDEV9 (void )
292+ {
293+ if (!dev9_loaded ) {
294+ int ID , RET ;
295+ ID = SifExecModuleBuffer (& ps2dev9_irx , size_ps2dev9_irx , 0 , NULL , & RET );
296+ DPRINTF ("[DEV9]: ret=%d, ID=%d\n" , RET , ID );
297+ if (ID < 0 && RET == 1 ) // ID smaller than 0: issue reported from modload | RET == 1: driver returned no resident end
298+ return 0 ;
299+ dev9_loaded = 1 ;
300+ }
301+ return 1 ;
302+ }
303+ #endif
304+
305+
306+ #ifdef HDD
307+ #include <hdd-ioctl.h>
308+ #include <io_common.h>
309+ #include <assert.h>
310+ #include <libpwroff.h>
311+ char PART [128 ] = "\0" ;
312+ int HDD_USABLE = 0 ;
313+
314+ static int CheckHDD (void )
315+ {
316+ int ret = fileXioDevctl ("hdd0:" , HDIOC_STATUS , NULL , 0 , NULL , 0 );
317+ /* 0 = HDD connected and formatted, 1 = not formatted, 2 = HDD not usable, 3 = HDD not connected. */
318+ DPRINTF ("%s: HDD status is %d\n" , __func__ , ret );
319+ if ((ret >= 3 ) || (ret < 0 ))
320+ return -1 ;
321+ return ret ;
322+ }
323+
324+ int LoadHDDIRX (void )
325+ {
326+ int ID , RET , HDDSTAT ;
327+ static const char hddarg [] = "-o"
328+ "\0"
329+ "4"
330+ "\0"
331+ "-n"
332+ "\0"
333+ "20" ;
334+ //static const char pfsarg[] = "-n\0" "24\0" "-o\0" "8";
335+
336+ if (!loadDEV9 ())
337+ return -1 ;
338+
339+ ID = SifExecModuleBuffer (& poweroff_irx , size_poweroff_irx , 0 , NULL , & RET );
340+ DPRINTF (" [POWEROFF]: ret=%d, ID=%d\n" , RET , ID );
341+ if (ID < 0 || RET == 1 )
342+ return -2 ;
343+
344+ poweroffInit ();
345+ poweroffSetCallback (& poweroffCallback , NULL );
346+ DPRINTF ("PowerOFF Callback installed...\n" );
347+
348+ ID = SifExecModuleBuffer (& ps2atad_irx , size_ps2atad_irx , 0 , NULL , & RET );
349+ DPRINTF (" [ATAD]: ret=%d, ID=%d\n" , RET , ID );
350+ if (ID < 0 || RET == 1 )
351+ return -3 ;
352+
353+ ID = SifExecModuleBuffer (& ps2hdd_irx , size_ps2hdd_irx , sizeof (hddarg ), hddarg , & RET );
354+ DPRINTF (" [PS2HDD]: ret=%d, ID=%d\n" , RET , ID );
355+ if (ID < 0 || RET == 1 )
356+ return -4 ;
357+
358+ HDDSTAT = CheckHDD ();
359+ HDD_USABLE = !(HDDSTAT < 0 );
360+
361+ /* PS2FS.IRX */
362+ if (HDD_USABLE ) {
363+ ID = SifExecModuleBuffer (& ps2fs_irx , size_ps2fs_irx , 0 , NULL , & RET );
364+ DPRINTF (" [PS2FS]: ret=%d, ID=%d\n" , RET , ID );
365+ if (ID < 0 || RET == 1 )
366+ return -5 ;
367+ }
368+
369+ return 0 ;
370+ }
371+
372+ int MountParty (const char * path )
373+ {
374+ int ret = -1 ;
375+ DPRINTF ("%s: %s\n" , __func__ , path );
376+ char * BUF = NULL ;
377+ BUF = strdup (path ); //use strdup, otherwise, path will become `hdd0:`
378+ char MountPoint [40 ];
379+ if (getMountInfo (BUF , NULL , MountPoint , NULL )) {
380+ mnt (MountPoint );
381+ if (BUF != NULL )
382+ free (BUF );
383+ strcpy (PART , MountPoint );
384+ strcat (PART , ":" );
385+ return 0 ;
386+ } else {
387+ DPRINTF ("ERROR: could not process path '%s'\n" , path );
388+ PART [0 ] = '\0' ;
389+ }
390+ if (BUF != NULL )
391+ free (BUF );
392+ return ret ;
393+ }
394+
395+ int mnt (const char * path )
396+ {
397+ DPRINTF ("Mounting '%s'\n" , path );
398+ if (fileXioMount ("pfs0:" , path , FIO_MT_RDONLY ) < 0 ) // mount
399+ {
400+ DPRINTF ("Mount failed. unmounting pfs0 and trying again...\n" );
401+ if (fileXioUmount ("pfs0:" ) < 0 ) //try to unmount then mount again in case it got mounted by something else
402+ {
403+ DPRINTF ("Unmount failed!!!\n" );
404+ }
405+ if (fileXioMount ("pfs0:" , path , FIO_MT_RDONLY ) < 0 ) {
406+ DPRINTF ("mount failed again!\n" );
407+ return -4 ;
408+ } else {
409+ DPRINTF ("Second mount succed!\n" );
410+ }
411+ } else
412+ DPRINTF ("mount successfull on first attemp\n" );
413+ return 0 ;
414+ }
415+
416+ void HDDChecker ()
417+ {
418+ char ErrorPartName [64 ];
419+ const char * HEADING = "HDD Diagnosis routine" ;
420+ int ret = -1 ;
421+ scr_clear ();
422+ scr_printf ("\n\n%*s%s\n" , ((80 - strlen (HEADING )) / 2 ), "" , HEADING );
423+ scr_setfontcolor (0x0000FF );
424+ ret = fileXioDevctl ("hdd0:" , HDIOC_STATUS , NULL , 0 , NULL , 0 );
425+ if (ret == 0 || ret == 1 )
426+ scr_setfontcolor (0x00FF00 );
427+ if (ret != 3 ) {
428+ scr_printf ("\t\t - HDD CONNECTION STATUS: %d\n" , ret );
429+ /* Check ATA device S.M.A.R.T. status. */
430+ ret = fileXioDevctl ("hdd0:" , HDIOC_SMARTSTAT , NULL , 0 , NULL , 0 );
431+ if (ret != 0 )
432+ scr_setfontcolor (0x0000ff );
433+ else
434+ scr_setfontcolor (0x00FF00 );
435+ scr_printf ("\t\t - S.M.A.R.T STATUS: %d\n" , ret );
436+ /* Check for unrecoverable I/O errors on sectors. */
437+ ret = fileXioDevctl ("hdd0:" , HDIOC_GETSECTORERROR , NULL , 0 , NULL , 0 );
438+ if (ret != 0 )
439+ scr_setfontcolor (0x0000ff );
440+ else
441+ scr_setfontcolor (0x00FF00 );
442+ scr_printf ("\t\t - SECTOR ERRORS: %d\n" , ret );
443+ /* Check for partitions that have errors. */
444+ ret = fileXioDevctl ("hdd0:" , HDIOC_GETERRORPARTNAME , NULL , 0 , ErrorPartName , sizeof (ErrorPartName ));
445+ if (ret != 0 )
446+ scr_setfontcolor (0x0000ff );
447+ else
448+ scr_setfontcolor (0x00FF00 );
449+ scr_printf ("\t\t - CORRUPTED PARTITIONS: %d\n" , ret );
450+ if (ret != 0 ) {
451+ scr_printf ("\t\tpartition: %s\n" , ErrorPartName );
452+ }
453+ } else
454+ scr_setfontcolor (0x00FFFF ), scr_printf ("Skipping test, HDD is not connected\n" );
455+ scr_setfontcolor (0xFFFFFF );
456+ scr_printf ("\t\tWaiting for 10 seconds...\n" );
457+ sleep (10 );
458+ }
459+ /// @brief poweroff callback function
460+ /// @note only expansion bay models will properly make use of this. the other models will run the callback but will poweroff themselves before reaching function end...
461+ void poweroffCallback (void * arg )
462+ {
463+ fileXioDevctl ("pfs:" , PDIOC_CLOSEALL , NULL , 0 , NULL , 0 );
464+ while (fileXioDevctl ("dev9x:" , DDIOC_OFF , NULL , 0 , NULL , 0 ) < 0 ) {};
465+ // As required by some (typically 2.5") HDDs, issue the SCSI STOP UNIT command to avoid causing an emergency park.
466+ fileXioDevctl ("mass:" , USBMASS_DEVCTL_STOP_ALL , NULL , 0 , NULL , 0 );
467+ /* Power-off the PlayStation 2. */
468+ poweroffShutdown ();
469+ }
470+
471+ #endif
0 commit comments