@@ -788,37 +788,109 @@ void setErrorMessage(int strId)
788788
789789static int lscstatus = CONFIG_ALL ;
790790static int lscret = 0 ;
791+ static const char * configPathRedirectFile = "config.path" ;
792+
793+ static int readConfigPathRedirect (char * outPath , int outPathLen )
794+ {
795+ int fd ;
796+ int len ;
797+
798+ fd = open ((char * )configPathRedirectFile , O_RDONLY );
799+ if (fd < 0 )
800+ return 0 ;
801+
802+ len = read (fd , outPath , outPathLen - 1 );
803+ close (fd );
804+ if (len <= 0 )
805+ return 0 ;
806+
807+ while (len > 0 && (outPath [len - 1 ] == '\r' || outPath [len - 1 ] == '\n' || outPath [len - 1 ] == ' ' || outPath [len - 1 ] == '\t' ))
808+ len -- ;
809+ outPath [len ] = '\0' ;
810+
811+ return len > 0 ;
812+ }
813+
814+ static void writeConfigPathRedirect (const char * path )
815+ {
816+ int fd = open ((char * )configPathRedirectFile , O_WRONLY | O_CREAT | O_TRUNC , 0666 );
817+ if (fd >= 0 ) {
818+ write (fd , path , strlen (path ));
819+ write (fd , "\n" , 1 );
820+ close (fd );
821+ }
822+ }
791823
792824static int checkLoadConfigBDM (int types )
793825{
794826 char path [64 ];
795827 int value ;
796828 int bdm_result ;
797- int is_hdd = 0 ;
798829
799- // check USB
830+ // Check BDM devices first (mass:/massX:/mmce:/mx4sio: etc).
800831 bdm_result = bdmFindPartition (path , "conf_opl.cfg" , 0 );
801- // if not on USB, check BDM HDD
802- if (bdm_result == 0 ) {
803- // wait for up to 5 seconds for the HDD to spin up and become accessible...
804- if (hddLoadModules () >= 0 && bdmHDDIsPresent (5000 )) {
805- bdm_result = bdmFindPartition (path , "conf_opl.cfg" , 0 );
806- if (bdm_result )
807- is_hdd = 1 ;
808- }
809- }
810832
811833 if (bdm_result ) {
812834 configEnd ();
813835 configInit (path );
814836 value = configReadMulti (types );
815837 config_set_t * configOPL = configGetByType (CONFIG_OPL );
816838 configSetInt (configOPL , CONFIG_OPL_BDM_MODE , START_MODE_AUTO );
817- if (is_hdd != 0 ) {
839+ return value ;
840+ }
841+
842+ return 0 ;
843+ }
844+
845+ static int checkLoadConfigMMCE (int types )
846+ {
847+ int value ;
848+ DIR * dir = opendir ("mmce0:" );
849+ if (dir != NULL ) {
850+ closedir (dir );
851+ configEnd ();
852+ configInit ("mmce0:" );
853+ value = configReadMulti (types );
854+ if (value & CONFIG_OPL ) {
855+ config_set_t * configOPL = configGetByType (CONFIG_OPL );
856+ configSetInt (configOPL , CONFIG_OPL_MMCE_MODE , START_MODE_AUTO );
857+ return value ;
858+ }
859+ }
860+
861+ dir = opendir ("mmce1:" );
862+ if (dir != NULL ) {
863+ closedir (dir );
864+ configEnd ();
865+ configInit ("mmce1:" );
866+ value = configReadMulti (types );
867+ if (value & CONFIG_OPL ) {
868+ config_set_t * configOPL = configGetByType (CONFIG_OPL );
869+ configSetInt (configOPL , CONFIG_OPL_MMCE_MODE , START_MODE_AUTO );
870+ return value ;
871+ }
872+ }
873+
874+ return 0 ;
875+ }
876+
877+ static int checkLoadConfigBDMHDD (int types )
878+ {
879+ char path [64 ];
880+ int value ;
881+
882+ // Bounded wait so BDM-on-HDD can be detected without long black-screen stalls.
883+ if (hddLoadModules () >= 0 && bdmHDDIsPresent (500 )) {
884+ if (bdmFindPartition (path , "conf_opl.cfg" , 0 )) {
885+ configEnd ();
886+ configInit (path );
887+ value = configReadMulti (types );
888+ config_set_t * configOPL = configGetByType (CONFIG_OPL );
889+ configSetInt (configOPL , CONFIG_OPL_BDM_MODE , START_MODE_AUTO );
818890 gEnableBdmHDD = 1 ;
819891 configSetInt (configOPL , CONFIG_OPL_ENABLE_BDMHDD , gEnableBdmHDD );
892+ return value ;
820893 }
821- return value ;
822894 }
823895
824896 return 0 ;
@@ -851,11 +923,20 @@ static int checkLoadConfigHDD(int types)
851923static int tryAlternateDevice (int types )
852924{
853925 char pwd [8 ];
926+ char redirectPath [64 ];
854927 int value ;
855928 DIR * dir ;
856929
857930 getcwd (pwd , sizeof (pwd ));
858931
932+ if (readConfigPathRedirect (redirectPath , sizeof (redirectPath ))) {
933+ configEnd ();
934+ configInit (redirectPath );
935+ value = configReadMulti (types );
936+ if (value & CONFIG_OPL )
937+ return value ;
938+ }
939+
859940 // First, try the device that OPL booted from.
860941 if (!strncmp (pwd , "mass" , 4 ) && (pwd [4 ] == ':' || pwd [5 ] == ':' )) {
861942 if ((value = checkLoadConfigBDM (types )) != 0 )
@@ -866,9 +947,15 @@ static int tryAlternateDevice(int types)
866947 }
867948
868949 // Config was not found on the boot device. Check all supported devices.
869- // Check USB device
950+ // Check MMCE before BDM.
951+ if ((value = checkLoadConfigMMCE (types )) != 0 )
952+ return value ;
953+ // Check BDM devices.
870954 if ((value = checkLoadConfigBDM (types )) != 0 )
871955 return value ;
956+ // Check BDM HDD with a short bounded wait.
957+ if ((value = checkLoadConfigBDMHDD (types )) != 0 )
958+ return value ;
872959 // Check HDD
873960 if ((value = checkLoadConfigHDD (types )) != 0 )
874961 return value ;
@@ -906,6 +993,8 @@ static void _loadConfig()
906993 int value , themeID = -1 , langID = -1 ;
907994 const char * temp ;
908995 int result = configReadMulti (lscstatus );
996+ if ((lscstatus & CONFIG_OPL ) && !(result & CONFIG_OPL ))
997+ result = tryAlternateDevice (lscstatus );
909998
910999 if (lscstatus & CONFIG_OPL ) {
9111000 if (result & CONFIG_OPL ) {
@@ -1029,15 +1118,8 @@ static int trySaveConfigBDM(int types)
10291118 char path [64 ];
10301119 int bdm_result ;
10311120
1032- // check USB
1121+ // Check BDM devices first (mass:/massX:/mmce:/mx4sio: etc).
10331122 bdm_result = bdmFindPartition (path , "conf_opl.cfg" , 1 );
1034- // if not on USB, check BDM HDD
1035- if (bdm_result == 0 ) {
1036- // wait for up to 5 seconds for the HDD to spin up and become accessible...
1037- if (hddLoadModules () >= 0 && bdmHDDIsPresent (5000 )) {
1038- bdm_result = bdmFindPartition (path , "conf_opl.cfg" , 1 );
1039- }
1040- }
10411123
10421124 if (bdm_result ) {
10431125 configSetMove (path );
@@ -1047,6 +1129,40 @@ static int trySaveConfigBDM(int types)
10471129 return - ENOENT ;
10481130}
10491131
1132+ static int trySaveConfigMMCE (int types )
1133+ {
1134+ DIR * dir = opendir ("mmce0:" );
1135+ if (dir != NULL ) {
1136+ closedir (dir );
1137+ configSetMove ("mmce0:" );
1138+ return configWriteMulti (types );
1139+ }
1140+
1141+ dir = opendir ("mmce1:" );
1142+ if (dir != NULL ) {
1143+ closedir (dir );
1144+ configSetMove ("mmce1:" );
1145+ return configWriteMulti (types );
1146+ }
1147+
1148+ return - ENOENT ;
1149+ }
1150+
1151+ static int trySaveConfigBDMHDD (int types )
1152+ {
1153+ char path [64 ];
1154+
1155+ // Bounded wait so save can target BDM-on-HDD without long stalls.
1156+ if (hddLoadModules () >= 0 && bdmHDDIsPresent (500 )) {
1157+ if (bdmFindPartition (path , "conf_opl.cfg" , 1 )) {
1158+ configSetMove (path );
1159+ return configWriteMulti (types );
1160+ }
1161+ }
1162+
1163+ return - ENOENT ;
1164+ }
1165+
10501166static int trySaveConfigHDD (int types )
10511167{
10521168 hddLoadModules ();
@@ -1067,30 +1183,19 @@ static int trySaveConfigMC(int types)
10671183
10681184static int trySaveAlternateDevice (int types )
10691185{
1070- char pwd [8 ];
10711186 int value ;
10721187
1073- getcwd (pwd , sizeof (pwd ));
1074-
1075- // First, try the device that OPL booted from.
1076- if (!strncmp (pwd , "mass" , 4 ) && (pwd [4 ] == ':' || pwd [5 ] == ':' )) {
1077- if ((value = trySaveConfigBDM (types )) > 0 )
1078- return value ;
1079- } else if (!strncmp (pwd , "hdd" , 3 ) && (pwd [3 ] == ':' || pwd [4 ] == ':' )) {
1080- if ((value = trySaveConfigHDD (types )) > 0 )
1081- return value ;
1082- }
1083-
1084- // Config was not saved to the boot device. Try all supported devices.
1085- // Try memory cards
1188+ // Save in deterministic order: MC -> MMCE -> BDM -> BDM-HDD -> HDD.
10861189 if (sysCheckMC () >= 0 ) {
10871190 if ((value = trySaveConfigMC (types )) > 0 )
10881191 return value ;
10891192 }
1090- // Try a USB device
1193+ if ((value = trySaveConfigMMCE (types )) > 0 )
1194+ return value ;
10911195 if ((value = trySaveConfigBDM (types )) > 0 )
10921196 return value ;
1093- // Try the HDD
1197+ if ((value = trySaveConfigBDMHDD (types )) > 0 )
1198+ return value ;
10941199 if ((value = trySaveConfigHDD (types )) > 0 )
10951200 return value ;
10961201
@@ -1193,6 +1298,8 @@ static void _saveConfig()
11931298 }
11941299
11951300 lscret = configWriteMulti (lscstatus );
1301+ if (lscret > 0 )
1302+ writeConfigPathRedirect (configGetDir ());
11961303 lscstatus = 0 ;
11971304}
11981305
@@ -1667,6 +1774,12 @@ static void moduleCleanup(opl_io_module_t *mod, int exception, int modeSelected)
16671774
16681775void deinit (int exception , int modeSelected )
16691776{
1777+ /* Cut launch/exit latency by stopping queued art I/O before globally
1778+ * blocking the I/O worker. This avoids waiting for stale cover requests
1779+ * that are no longer needed once we are deinitializing. */
1780+ cacheAbortMmceImageLoadsTimed (0 );
1781+ (void )cacheCancelPendingImageLoadsTimed (0 );
1782+
16701783 // block all io ops, wait for the ones still running to finish
16711784 ioBlockOps (1 );
16721785 guiExecDeferredOps ();
0 commit comments