In accord with the El Torito specification[1], SeaBIOS now signals
failure (AH=1 and CF) whenever attempts are made to terminate disk
emulation (0x4B) for non-emulated drives. The prior behavior of always
returning success caused the Solaris 9 Device Configuration
Assistant (DCA) diskette (d1_image) to fail to boot as it was unable
to access the non-existent underlying drive.

References:

[1]:  "CF - Clear if system released
       CF - Set if system not in emulation mode"

     C. E. Stevens and S. Merkin, '"El Torito" Bootable CD-ROM Format
     Specification', Phoenix Technologies and IBM, 1994, p. 17.

Signed-off-by: Lev Kujawski <lku...@member.fsf.org>
---
 src/disk.c | 82 ++++++++++++++++++++++++++++++------------------------
 1 file changed, 46 insertions(+), 36 deletions(-)

diff --git a/src/disk.c b/src/disk.c
index 14a99db..6a25015 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -568,6 +568,33 @@ disk_1349(struct bregs *regs, struct drive_s *drive_fl)
     regs->ah = DISK_RET_ECHANGED;
 }
 
+// El Torito - Terminate disk emulation
+static void
+disk_134b(struct bregs *regs, struct drive_s *drive_fl)
+{
+    if (CONFIG_CDROM_BOOT && regs->dl == GET_LOW(CDEmu.emulated_drive)) {
+        if ((regs->dl >= EXTSTART_CD) ||
+            (CONFIG_CDROM_EMU && GET_LOW(CDEmu.media)))
+        {
+            memcpy_far(regs->ds, (void*)(regs->si+0),
+                       SEG_LOW, &CDEmu, sizeof(CDEmu));
+
+            // If we have to terminate emulation
+            if (regs->al == 0x00) {
+                // FIXME ElTorito Various. Should be handled accordingly to 
spec
+                SET_LOW(CDEmu.media, 0x00); // bye bye
+
+                // XXX - update floppy/hd count.
+            }
+
+            disk_ret(regs, DISK_RET_SUCCESS);
+            return;
+        }
+    }
+
+    disk_ret(regs, DISK_RET_EPARAM);
+}
+
 static void
 disk_134e01(struct bregs *regs, struct drive_s *drive_fl)
 {
@@ -650,6 +677,7 @@ disk_13(struct bregs *regs, struct drive_s *drive_fl)
     case 0x47: disk_1347(regs, drive_fl); break;
     case 0x48: disk_1348(regs, drive_fl); break;
     case 0x49: disk_1349(regs, drive_fl); break;
+    case 0x4b: disk_134b(regs, drive_fl); break;
     case 0x4e: disk_134e(regs, drive_fl); break;
     default:   disk_13XX(regs, drive_fl); break;
     }
@@ -675,23 +703,6 @@ floppy_13(struct bregs *regs, struct drive_s *drive_fl)
     }
 }
 
-// ElTorito - Terminate disk emu
-static void
-cdemu_134b(struct bregs *regs)
-{
-    memcpy_far(regs->ds, (void*)(regs->si+0), SEG_LOW, &CDEmu, sizeof(CDEmu));
-
-    // If we have to terminate emulation
-    if (regs->al == 0x00) {
-        // FIXME ElTorito Various. Should be handled accordingly to spec
-        SET_LOW(CDEmu.media, 0x00); // bye bye
-
-        // XXX - update floppy/hd count.
-    }
-
-    disk_ret(regs, DISK_RET_SUCCESS);
-}
-
 
 /****************************************************************
  * Entry points
@@ -743,27 +754,26 @@ handle_13(struct bregs *regs)
     debug_enter(regs, DEBUG_HDL_13);
     u8 extdrive = regs->dl;
 
-    if (CONFIG_CDROM_EMU) {
-        if (regs->ah == 0x4b) {
-            cdemu_134b(regs);
-            return;
-        }
-        if (GET_LOW(CDEmu.media)) {
-            u8 emudrive = GET_LOW(CDEmu.emulated_drive);
-            if (extdrive == emudrive) {
-                // Access to an emulated drive.
-                struct drive_s *cdemu_gf = GET_GLOBAL(cdemu_drive_gf);
-                if (regs->ah > 0x16) {
-                    // Only old-style commands supported.
-                    disk_13XX(regs, cdemu_gf);
-                    return;
-                }
+    if (CONFIG_CDROM_EMU && GET_LOW(CDEmu.media)) {
+        const u8 emudrive = GET_LOW(CDEmu.emulated_drive);
+
+        if (extdrive == emudrive) {
+            // Access to an emulated drive.
+            struct drive_s *cdemu_gf = GET_GLOBAL(cdemu_drive_gf);
+
+            if (regs->ah <= 0x16 || regs->ah == 0x4b) {
                 disk_13(regs, cdemu_gf);
-                return;
+            } else {
+                // Only old-style commands supported.
+                disk_13XX(regs, cdemu_gf);
             }
-            if (extdrive < EXTSTART_CD && ((emudrive ^ extdrive) & 0x80) == 0)
-                // Adjust id to make room for emulated drive.
-                extdrive--;
+
+            return;
+        }
+
+        if (extdrive < EXTSTART_CD && ((emudrive ^ extdrive) & 0x80) == 0) {
+            // Adjust id to make room for emulated drive.
+            extdrive--;
         }
     }
     handle_legacy_disk(regs, extdrive);
-- 
2.34.1

_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-le...@seabios.org

Reply via email to