]> xenbits.xensource.com Git - seabios.git/commitdiff
Separate cdemu disk accesses from regular disk accesses.
authorKevin O'Connor <kevin@koconnor.net>
Sun, 9 Aug 2009 17:08:21 +0000 (13:08 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Sun, 9 Aug 2009 17:08:21 +0000 (13:08 -0400)
Breakup basic_access() into basic_access, cdemu_access, and legacy_lba.
Also, check for verify and seek calls in __send_disk_op instead of all
    callers.
Also, send_disk_op returns sector count in dop.count instead of via ebda.

src/cdrom.c
src/disk.c
src/disk.h

index 8ccbeeab327e9626e418219080bfbb2e1d248301..b96afa070eda8803f796894e3be107503ce705cf 100644 (file)
@@ -180,6 +180,18 @@ cdrom_13(struct bregs *regs, u8 device)
  * CD emulation
  ****************************************************************/
 
+static void
+cdemu_1302(struct bregs *regs, u8 device)
+{
+    cdemu_access(regs, device, ATA_CMD_READ_SECTORS);
+}
+
+static void
+cdemu_1304(struct bregs *regs, u8 device)
+{
+    cdemu_access(regs, device, 0);
+}
+
 // read disk drive parameters
 static void
 cdemu_1308(struct bregs *regs, u8 device)
@@ -217,11 +229,9 @@ cdemu_13(struct bregs *regs)
     device += GET_EBDA2(ebda_seg, cdemu.device_spec);
 
     switch (regs->ah) {
-    // These functions are the same as for hard disks
-    case 0x02:
-    case 0x04:
-        disk_13(regs, device);
-        break;
+    case 0x02: cdemu_1302(regs, device); break;
+    case 0x04: cdemu_1304(regs, device); break;
+    case 0x08: cdemu_1308(regs, device); break;
 
     // These functions are the same as standard CDROM.
     case 0x00:
@@ -239,8 +249,6 @@ cdemu_13(struct bregs *regs)
         cdrom_13(regs, device);
         break;
 
-    case 0x08: cdemu_1308(regs, device); break;
-
     default:   disk_13XX(regs, device); break;
     }
 }
index 898fe499217c711dfdd06b9b0eb1a5a595ebbe6d..e56bcd0bc355a8e806cbdf2385411cc566da6a28 100644 (file)
@@ -40,6 +40,7 @@ __disk_stub(struct bregs *regs, int lineno, const char *fname)
 #define DISK_STUB(regs)                         \
     __disk_stub((regs), __LINE__, __func__)
 
+// Execute a "disk_op_s" request - this runs on a stack in the ebda.
 static int
 __send_disk_op(struct disk_op_s *op_far, u16 op_seg)
 {
@@ -55,6 +56,9 @@ __send_disk_op(struct disk_op_s *op_far, u16 op_seg)
     irq_enable();
 
     int status;
+    if (!dop.command)
+        // If verify or seek
+        status = 0;
     if (dop.command == CMD_CDEMU_READ)
         status = cdrom_read_512(&dop);
     else if (dop.command == CMD_CDROM_READ)
@@ -64,9 +68,16 @@ __send_disk_op(struct disk_op_s *op_far, u16 op_seg)
 
     irq_disable();
 
+    // Update count with total sectors transferred.
+    SET_FARVAR(op_seg, op_far->count, GET_EBDA(sector_count));
+
+    if (status)
+        dprintf(1, "disk_op cmd %d error %d!\n", dop.command, status);
+
     return status;
 }
 
+// Execute a "disk_op_s" request by jumping to a stack in the ebda.
 static int
 send_disk_op(struct disk_op_s *op)
 {
@@ -76,39 +87,20 @@ send_disk_op(struct disk_op_s *op)
     return stack_hop((u32)op, GET_SEG(SS), 0, __send_disk_op);
 }
 
-static void
-basic_access(struct bregs *regs, u8 device, u16 command)
+// Obtain the requested disk lba from an old-style chs request.
+static int
+legacy_lba(struct bregs *regs, struct disk_op_s *op, u16 nlc, u16 nlh, u16 nlspt)
 {
-    struct disk_op_s dop;
-    dop.lba = 0;
-    dop.driveid = device;
-    u8 type = GET_GLOBAL(ATA.devices[device].type);
-    u16 nlc, nlh, nlspt;
-    if (type == ATA_TYPE_ATA) {
-        nlc   = GET_GLOBAL(ATA.devices[device].lchs.cylinders);
-        nlh   = GET_GLOBAL(ATA.devices[device].lchs.heads);
-        nlspt = GET_GLOBAL(ATA.devices[device].lchs.spt);
-        dop.command = command;
-    } else {
-        // Must be cd emulation.
-        u16 ebda_seg = get_ebda_seg();
-        nlc   = GET_EBDA2(ebda_seg, cdemu.cylinders);
-        nlh   = GET_EBDA2(ebda_seg, cdemu.heads);
-        nlspt = GET_EBDA2(ebda_seg, cdemu.spt);
-        dop.lba = GET_EBDA2(ebda_seg, cdemu.ilba) * 4;
-        dop.command = CMD_CDEMU_READ;
-    }
-
-    dop.count       = regs->al;
-    u16 cylinder    = regs->ch | ((((u16) regs->cl) << 2) & 0x300);
-    u16 sector      = regs->cl & 0x3f;
-    u16 head        = regs->dh;
+    op->count = regs->al;
+    u16 cylinder = regs->ch | ((((u16)regs->cl) << 2) & 0x300);
+    u16 sector = regs->cl & 0x3f;
+    u16 head = regs->dh;
 
-    if (dop.count > 128 || dop.count == 0 || sector == 0) {
+    if (op->count > 128 || op->count == 0 || sector == 0) {
         dprintf(1, "int13_harddisk: function %02x, parameter out of range!\n"
                 , regs->ah);
         disk_ret(regs, DISK_RET_EPARAM);
-        return;
+        return -1;
     }
 
     // sanity check on cyl heads, sec
@@ -117,37 +109,73 @@ basic_access(struct bregs *regs, u8 device, u16 command)
                 " range %04x/%04x/%04x!\n"
                 , regs->ah, cylinder, head, sector);
         disk_ret(regs, DISK_RET_EPARAM);
-        return;
-    }
-
-    if (!command) {
-        // If verify or seek
-        disk_ret(regs, DISK_RET_SUCCESS);
-        return;
+        return -1;
     }
 
     // translate lchs to lba
-    dop.lba += (((((u32)cylinder * (u32)nlh) + (u32)head) * (u32)nlspt)
-                + (u32)sector - 1);
+    op->lba = (((((u32)cylinder * (u32)nlh) + (u32)head) * (u32)nlspt)
+               + (u32)sector - 1);
 
     u16 segment = regs->es;
     u16 offset  = regs->bx;
-    dop.buf_fl = MAKE_FLATPTR(segment, offset);
+    op->buf_fl = MAKE_FLATPTR(segment, offset);
+
+    return 0;
+}
+
+// Perform read/write/verify using old-style chs accesses
+static void
+basic_access(struct bregs *regs, u8 device, u16 command)
+{
+    struct disk_op_s dop;
+    dop.driveid = device;
+    dop.command = command;
+    u16 nlc = GET_GLOBAL(ATA.devices[device].lchs.cylinders);
+    u16 nlh = GET_GLOBAL(ATA.devices[device].lchs.heads);
+    u16 nlspt = GET_GLOBAL(ATA.devices[device].lchs.spt);
+    int ret = legacy_lba(regs, &dop, nlc, nlh, nlspt);
+    if (ret)
+        return;
 
     int status = send_disk_op(&dop);
 
-    // Set nb of sector transferred
-    regs->al = GET_EBDA(sector_count);
+    regs->al = dop.count;
 
-    if (status != 0) {
-        dprintf(1, "int13_harddisk: function %02x, error %d!\n"
-                , regs->ah, status);
+    if (status) {
         disk_ret(regs, DISK_RET_EBADTRACK);
         return;
     }
     disk_ret(regs, DISK_RET_SUCCESS);
 }
 
+// Perform cdemu read/verify
+void
+cdemu_access(struct bregs *regs, u8 device, u16 command)
+{
+    struct disk_op_s dop;
+    dop.driveid = device;
+    dop.command = (command == ATA_CMD_READ_SECTORS ? CMD_CDEMU_READ : 0);
+    u16 ebda_seg = get_ebda_seg();
+    u16 nlc = GET_EBDA2(ebda_seg, cdemu.cylinders);
+    u16 nlh = GET_EBDA2(ebda_seg, cdemu.heads);
+    u16 nlspt = GET_EBDA2(ebda_seg, cdemu.spt);
+    int ret = legacy_lba(regs, &dop, nlc, nlh, nlspt);
+    if (ret)
+        return;
+    dop.lba += GET_EBDA2(ebda_seg, cdemu.ilba) * 4;
+
+    int status = send_disk_op(&dop);
+
+    regs->al = dop.count;
+
+    if (status) {
+        disk_ret(regs, DISK_RET_EBADTRACK);
+        return;
+    }
+    disk_ret(regs, DISK_RET_SUCCESS);
+}
+
+// Perform read/write/verify using new-style "int13ext" accesses.
 static void
 extended_access(struct bregs *regs, u8 device, u16 command)
 {
@@ -168,12 +196,6 @@ extended_access(struct bregs *regs, u8 device, u16 command)
         dop.command = CMD_CDROM_READ;
     }
 
-    if (!command) {
-        // If verify or seek
-        disk_ret(regs, DISK_RET_SUCCESS);
-        return;
-    }
-
     u16 segment = GET_INT13EXT(regs, segment);
     u16 offset = GET_INT13EXT(regs, offset);
     dop.buf_fl = MAKE_FLATPTR(segment, offset);
@@ -181,11 +203,9 @@ extended_access(struct bregs *regs, u8 device, u16 command)
 
     int status = send_disk_op(&dop);
 
-    SET_INT13EXT(regs, count, GET_EBDA(sector_count));
+    SET_INT13EXT(regs, count, dop.count);
 
-    if (status != 0) {
-        dprintf(1, "int13_harddisk: function %02x, error %d!\n"
-                , regs->ah, status);
+    if (status) {
         disk_ret(regs, DISK_RET_EBADTRACK);
         return;
     }
index 8e9f1cbff296df9b6993be560bb337204e1f7cae..b4d844405072d943de321288870800ba02360f98 100644 (file)
@@ -224,6 +224,7 @@ void floppy_tick();
 // disk.c
 void disk_13(struct bregs *regs, u8 device);
 void disk_13XX(struct bregs *regs, u8 device);
+void cdemu_access(struct bregs *regs, u8 device, u16 command);
 
 // cdrom.c
 void cdrom_13(struct bregs *regs, u8 device);