Use new 'struct disk_op_s' to issue ata requests.
authorKevin O'Connor <kevin@koconnor.net>
Wed, 31 Dec 2008 05:31:03 +0000 (00:31 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Wed, 31 Dec 2008 05:31:03 +0000 (00:31 -0500)
Using the struct at all callers reduces the parameter assignments.
Replace ata_op_s with new disk_op_s and update all users.
Unify basic/extended_access methods to use new send_disk_op() func.
Remove cdrom_read_emu -- integrate logic into callers.
Remove ata.h -- move all defs to disk.h

src/ata.c
src/ata.h [deleted file]
src/boot.c
src/cdrom.c
src/disk.c
src/disk.h
src/post.c

index 3694c3b9aa4d80606286cca4cb83b5c40469e8a6..81d00cd0b94d12ae3a55397e08b2950a89f82818 100644 (file)
--- a/src/ata.c
+++ b/src/ata.c
@@ -5,7 +5,6 @@
 //
 // This file may be distributed under the terms of the GNU GPLv3 license.
 
-#include "ata.h" // ATA_*
 #include "types.h" // u8
 #include "ioport.h" // inb
 #include "util.h" // dprintf
@@ -16,6 +15,7 @@
 #include "pci_ids.h" // PCI_CLASS_STORAGE_OTHER
 #include "pci_regs.h" // PCI_INTERRUPT_LINE
 #include "disk.h" // struct ata_s
+#include "atabits.h" // ATA_CB_STAT
 
 #define TIMEOUT 0
 #define BSY 1
@@ -136,13 +136,6 @@ ata_reset(int driveid)
  * ATA send command
  ****************************************************************/
 
-struct ata_op_s {
-    u64 lba;
-    void *far_buffer;
-    u16 driveid;
-    u16 count;
-};
-
 struct ata_pio_command {
     u8 feature;
     u8 sector_count;
@@ -318,21 +311,21 @@ ata_transfer(int driveid, int iswrite, int count, int blocksize
 }
 
 static noinline int
-ata_transfer_disk(const struct ata_op_s *op, int iswrite)
+ata_transfer_disk(const struct disk_op_s *op)
 {
-    return ata_transfer(op->driveid, iswrite, op->count, IDE_SECTOR_SIZE
-                        , 0, 0, op->far_buffer);
+    return ata_transfer(op->driveid, op->command == ATA_CMD_WRITE_SECTORS
+                        , op->count, IDE_SECTOR_SIZE, 0, 0, op->far_buffer);
 }
 
 static noinline int
-ata_transfer_cdrom(const struct ata_op_s *op)
+ata_transfer_cdrom(const struct disk_op_s *op)
 {
     return ata_transfer(op->driveid, 0, op->count, CDROM_SECTOR_SIZE
                         , 0, 0, op->far_buffer);
 }
 
 static noinline int
-ata_transfer_emu(const struct ata_op_s *op, int before, int after)
+ata_transfer_cdemu(const struct disk_op_s *op, int before, int after)
 {
     int vcount = op->count * 4 - before - after;
     int ret = ata_transfer(op->driveid, 0, op->count, CDROM_SECTOR_SIZE
@@ -351,7 +344,7 @@ ata_transfer_emu(const struct ata_op_s *op, int before, int after)
  ****************************************************************/
 
 static noinline int
-send_cmd_disk(const struct ata_op_s *op, u16 command)
+send_cmd_disk(const struct disk_op_s *op)
 {
     u8 slave = op->driveid % 2;
     u64 lba = op->lba;
@@ -359,7 +352,7 @@ send_cmd_disk(const struct ata_op_s *op, u16 command)
     struct ata_pio_command cmd;
     memset(&cmd, 0, sizeof(cmd));
 
-    cmd.command = command;
+    cmd.command = op->command;
     if (op->count >= (1<<8) || lba + op->count >= (1<<28)) {
         cmd.sector_count2 = op->count >> 8;
         cmd.lba_low2 = lba >> 24;
@@ -383,20 +376,12 @@ send_cmd_disk(const struct ata_op_s *op, u16 command)
 
 // Read/write count blocks from a harddrive.
 __always_inline int
-ata_cmd_data(int driveid, u16 command, u64 lba, u16 count, void *far_buffer)
+ata_cmd_data(struct disk_op_s *op)
 {
-    struct ata_op_s op;
-    op.driveid = driveid;
-    op.lba = lba;
-    op.count = count;
-    op.far_buffer = far_buffer;
-
-    int ret = send_cmd_disk(&op, command);
+    int ret = send_cmd_disk(op);
     if (ret)
         return ret;
-
-    int iswrite = command == ATA_CMD_WRITE_SECTORS;
-    return ata_transfer_disk(&op, iswrite);
+    return ata_transfer_disk(op);
 }
 
 
@@ -438,7 +423,7 @@ send_atapi_cmd(int driveid, u8 *cmdbuf, u8 cmdlen, u16 blocksize)
 
 // Low-level cdrom read atapi command transmit function.
 static int
-send_cmd_cdrom(const struct ata_op_s *op)
+send_cmd_cdrom(const struct disk_op_s *op)
 {
     u8 atacmd[12];
     memset(atacmd, 0, sizeof(atacmd));
@@ -457,49 +442,39 @@ send_cmd_cdrom(const struct ata_op_s *op)
 
 // Read sectors from the cdrom.
 __always_inline int
-cdrom_read(int driveid, u32 lba, u32 count, void *far_buffer)
+cdrom_read(struct disk_op_s *op)
 {
-    struct ata_op_s op;
-    op.driveid = driveid;
-    op.lba = lba;
-    op.count = count;
-    op.far_buffer = far_buffer;
-
-    int ret = send_cmd_cdrom(&op);
+    int ret = send_cmd_cdrom(op);
     if (ret)
         return ret;
 
-    return ata_transfer_cdrom(&op);
+    return ata_transfer_cdrom(op);
 }
 
 // Pretend the cdrom has 512 byte sectors (instead of 2048) and read
 // sectors.
 __always_inline int
-cdrom_read_512(int driveid, u32 vlba, u32 vcount, void *far_buffer)
+cdrom_read_512(struct disk_op_s *op)
 {
+    u32 vlba = op->lba;
+    u32 vcount = op->count;
+    u32 lba = op->lba = vlba / 4;
     u32 velba = vlba + vcount - 1;
-    u32 lba = vlba / 4;
     u32 elba = velba / 4;
-    int count = elba - lba + 1;
+    op->count = elba - lba + 1;
     int before = vlba % 4;
     int after = 3 - (velba % 4);
 
-    struct ata_op_s op;
-    op.driveid = driveid;
-    op.lba = lba;
-    op.count = count;
-    op.far_buffer = far_buffer;
-
     dprintf(16, "cdrom_read_512: id=%d vlba=%d vcount=%d buf=%p lba=%d elba=%d"
             " count=%d before=%d after=%d\n"
-            , driveid, vlba, vcount, far_buffer, lba, elba
-            , count, before, after);
+            , op->driveid, vlba, vcount, op->far_buffer, lba, elba
+            , op->count, before, after);
 
-    int ret = send_cmd_cdrom(&op);
+    int ret = send_cmd_cdrom(op);
     if (ret)
         return ret;
 
-    return ata_transfer_emu(&op, before, after);
+    return ata_transfer_cdemu(op, before, after);
 }
 
 // Send a simple atapi command to a drive.
@@ -568,9 +543,13 @@ init_drive_atapi(int driveid)
     // Now we send a IDENTIFY command to ATAPI device
     u8 buffer[0x0200];
     memset(buffer, 0, sizeof(buffer));
-    u16 ret = ata_cmd_data(driveid, ATA_CMD_IDENTIFY_DEVICE_PACKET
-                           , 1, 1
-                           , MAKE_FARPTR(GET_SEG(SS), (u32)buffer));
+    struct disk_op_s dop;
+    dop.driveid = driveid;
+    dop.command = ATA_CMD_IDENTIFY_DEVICE_PACKET;
+    dop.count = 1;
+    dop.lba = 1;
+    dop.far_buffer = MAKE_FARPTR(GET_SEG(SS), (u32)buffer);
+    u16 ret = ata_cmd_data(&dop);
     if (ret != 0)
         BX_PANIC("ata-detect: Failed to detect ATAPI device\n");
 
@@ -746,9 +725,13 @@ init_drive_ata(int driveid)
     // Now we send a IDENTIFY command to ATA device
     u8 buffer[0x0200];
     memset(buffer, 0, sizeof(buffer));
-    u16 ret = ata_cmd_data(driveid, ATA_CMD_IDENTIFY_DEVICE
-                           , 1, 1
-                           , MAKE_FARPTR(GET_SEG(SS), (u32)buffer));
+    struct disk_op_s dop;
+    dop.driveid = driveid;
+    dop.command = ATA_CMD_IDENTIFY_DEVICE;
+    dop.count = 1;
+    dop.lba = 1;
+    dop.far_buffer = MAKE_FARPTR(GET_SEG(SS), (u32)buffer);
+    u16 ret = ata_cmd_data(&dop);
     if (ret)
         BX_PANIC("ata-detect: Failed to detect ATA device\n");
 
diff --git a/src/ata.h b/src/ata.h
deleted file mode 100644 (file)
index 59b01d3..0000000
--- a/src/ata.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Low level ATA disk definitions
-//
-// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
-// Copyright (C) 2002  MandrakeSoft S.A.
-//
-// This file may be distributed under the terms of the GNU GPLv3 license.
-
-#ifndef __ATA_H
-#define __ATA_H
-
-#include "types.h" // u16
-#include "atabits.h" // ATA_CB_DH_DEV1
-
-// Function definitions
-void ata_reset(int driveid);
-int ata_cmd_data(int driveid, u16 command, u64 lba, u16 count, void *far_buffer);
-int ata_cmd_packet(int driveid, u8 *cmdbuf, u8 cmdlen
-                   , u32 length, void *far_buffer);
-int cdrom_read(int driveid, u32 lba, u32 count, void *far_buffer);
-int cdrom_read_512(int driveid, u32 lba, u32 count, void *far_buffer);
-void hard_drive_setup();
-
-#endif /* __ATA_H */
index df3647dad438e09b7adb50928d04c2eaec352899..bc13f7988156aa63940bcd41580fcc1ebe499c14 100644 (file)
@@ -8,7 +8,6 @@
 #include "util.h" // irq_enable
 #include "biosvar.h" // GET_EBDA
 #include "config.h" // CONFIG_*
-#include "ata.h" // ata_detect
 #include "disk.h" // cdrom_boot
 #include "bregs.h" // struct bregs
 #include "boot.h" // struct ipl_s
index 00ecc7170aca988b00a58dc4c356b7ab1f97e447..dbf4379537b8dffbe0ebb522e8a6b95afceed064 100644 (file)
@@ -7,9 +7,9 @@
 
 #include "disk.h" // cdrom_13
 #include "util.h" // memset
-#include "ata.h" // ATA_CMD_READ_SECTORS
 #include "bregs.h" // struct bregs
 #include "biosvar.h" // GET_EBDA
+#include "atabits.h" // ATA_TYPE_ATAPI
 
 
 /****************************************************************
@@ -180,15 +180,6 @@ cdrom_13(struct bregs *regs, u8 device)
  * CD emulation
  ****************************************************************/
 
-// Read a series of 512 byte sectors from the cdrom starting at the
-// image offset.
-__always_inline int
-cdrom_read_emu(u16 biosid, u32 vlba, u32 count, void *far_buffer)
-{
-    u32 ilba = GET_EBDA(cdemu.ilba);
-    return cdrom_read_512(biosid, ilba * 4 + vlba, count, far_buffer);
-}
-
 // read disk drive parameters
 static void
 cdemu_1308(struct bregs *regs, u8 device)
@@ -443,8 +434,12 @@ cdrom_boot()
 
     // Read the Boot Record Volume Descriptor
     u8 buffer[2048];
-    ret = cdrom_read(device, 0x11, 1
-                     , MAKE_FARPTR(GET_SEG(SS), (u32)buffer));
+    struct disk_op_s dop;
+    dop.driveid = device;
+    dop.lba = 0x11;
+    dop.count = 1;
+    dop.far_buffer = MAKE_FARPTR(GET_SEG(SS), (u32)buffer);
+    ret = cdrom_read(&dop);
     if (ret)
         return 3;
 
@@ -458,8 +453,8 @@ cdrom_boot()
     u32 lba = *(u32*)&buffer[0x47];
 
     // And we read the Boot Catalog
-    ret = cdrom_read(device, lba, 1
-                     , MAKE_FARPTR(GET_SEG(SS), (u32)buffer));
+    dop.lba = lba;
+    ret = cdrom_read(&dop);
     if (ret)
         return 7;
 
@@ -497,7 +492,10 @@ cdrom_boot()
     SET_EBDA2(ebda_seg, cdemu.ilba, lba);
 
     // And we read the image in memory
-    ret = cdrom_read_emu(device, 0, nbsectors, MAKE_FARPTR(boot_segment, 0));
+    dop.lba = lba * 4;
+    dop.count = nbsectors;
+    dop.far_buffer = MAKE_FARPTR(boot_segment, 0);
+    ret = cdrom_read_512(&dop);
     if (ret)
         return 12;
 
index 010b14c5b3cbf46760567d17107515e8a1e325cd..e72be9dd2db06c1e3c85358efef2ce1d7caafee3 100644 (file)
@@ -9,10 +9,10 @@
 #include "biosvar.h" // SET_BDA
 #include "config.h" // CONFIG_*
 #include "util.h" // debug_enter
-#include "ata.h" // ATA_*
 #include "pic.h" // eoi_pic2
 #include "bregs.h" // struct bregs
 #include "pci.h" // pci_bdf_to_bus
+#include "atabits.h" // ATA_CB_STAT
 
 
 /****************************************************************
@@ -39,29 +39,57 @@ __disk_stub(const char *fname, int lineno, struct bregs *regs)
 #define DISK_STUB(regs) \
     __disk_stub(__func__, __LINE__, (regs))
 
+static __always_inline int
+send_disk_op(struct disk_op_s *op)
+{
+    dprintf(DEBUG_HDL_13, "disk_op d=%d lba=%d buf=%p count=%d cmd=%d\n"
+            , op->driveid, (u32)op->lba, op->far_buffer
+            , op->count, op->command);
+
+    irq_enable();
+
+    int status;
+    if (op->command == CMD_CDEMU_READ)
+        status = cdrom_read_512(op);
+    else if (op->command == CMD_CDROM_READ)
+        status = cdrom_read(op);
+    else
+        status = ata_cmd_data(op);
+
+    irq_disable();
+
+    return status;
+}
+
 static void
 basic_access(struct bregs *regs, u8 device, u16 command)
 {
+    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;
     }
 
-    u16 count       = regs->al;
+    dop.count       = regs->al;
     u16 cylinder    = regs->ch | ((((u16) regs->cl) << 2) & 0x300);
     u16 sector      = regs->cl & 0x3f;
     u16 head        = regs->dh;
 
-    if (count > 128 || count == 0 || sector == 0) {
+    if (dop.count > 128 || dop.count == 0 || sector == 0) {
         dprintf(1, "int13_harddisk: function %02x, parameter out of range!\n"
                 , regs->ah);
         disk_ret(regs, DISK_RET_EPARAM);
@@ -84,22 +112,14 @@ basic_access(struct bregs *regs, u8 device, u16 command)
     }
 
     // translate lchs to lba
-    u32 lba = (((((u32)cylinder * (u32)nlh) + (u32)head) * (u32)nlspt)
-               + (u32)sector - 1);
+    dop.lba += (((((u32)cylinder * (u32)nlh) + (u32)head) * (u32)nlspt)
+                + (u32)sector - 1);
 
     u16 segment = regs->es;
     u16 offset  = regs->bx;
-    void *far_buffer = MAKE_FARPTR(segment, offset);
-
-    irq_enable();
+    dop.far_buffer = MAKE_FARPTR(segment, offset);
 
-    int status;
-    if (type == ATA_TYPE_ATA)
-        status = ata_cmd_data(device, command, lba, count, far_buffer);
-    else
-        status = cdrom_read_emu(device, lba, count, far_buffer);
-
-    irq_disable();
+    int status = send_disk_op(&dop);
 
     // Set nb of sector transferred
     regs->al = GET_EBDA(sector_count);
@@ -115,15 +135,21 @@ basic_access(struct bregs *regs, u8 device, u16 command)
 static void
 extended_access(struct bregs *regs, u8 device, u16 command)
 {
+    struct disk_op_s dop;
     // Get lba and check.
-    u64 lba = GET_INT13EXT(regs, lba);
+    dop.lba = GET_INT13EXT(regs, lba);
+    dop.command = command;
+    dop.driveid = device;
     u8 type = GET_GLOBAL(ATA.devices[device].type);
-    if (type == ATA_TYPE_ATA
-        && lba >= GET_GLOBAL(ATA.devices[device].sectors)) {
-        dprintf(1, "int13_harddisk: function %02x. LBA out of range\n"
-                , regs->ah);
-        disk_ret(regs, DISK_RET_EPARAM);
-        return;
+    if (type == ATA_TYPE_ATA) {
+        if (dop.lba >= GET_GLOBAL(ATA.devices[device].sectors)) {
+            dprintf(1, "int13_harddisk: function %02x. LBA out of range\n"
+                    , regs->ah);
+            disk_ret(regs, DISK_RET_EPARAM);
+            return;
+        }
+    } else {
+        dop.command = CMD_CDROM_READ;
     }
 
     if (!command) {
@@ -134,21 +160,10 @@ extended_access(struct bregs *regs, u8 device, u16 command)
 
     u16 segment = GET_INT13EXT(regs, segment);
     u16 offset = GET_INT13EXT(regs, offset);
-    void *far_buffer = MAKE_FARPTR(segment, offset);
-    u16 count = GET_INT13EXT(regs, count);
+    dop.far_buffer = MAKE_FARPTR(segment, offset);
+    dop.count = GET_INT13EXT(regs, count);
 
-    dprintf(DEBUG_HDL_13, "extacc lba=%d buf=%p count=%d\n"
-            , (u32)lba, far_buffer, count);
-
-    irq_enable();
-
-    int status;
-    if (type == ATA_TYPE_ATA)
-        status = ata_cmd_data(device, command, lba, count, far_buffer);
-    else
-        status = cdrom_read(device, lba, count, far_buffer);
-
-    irq_disable();
+    int status = send_disk_op(&dop);
 
     SET_INT13EXT(regs, count, GET_EBDA(sector_count));
 
index d091c7f04c9f6961630dc43332864cdd1d631254..6c69dcaef2b4516283219b088acf79ef69887b74 100644 (file)
@@ -103,6 +103,22 @@ void __disk_ret(const char *fname, int lineno, struct bregs *regs, u8 code);
     __disk_ret(__func__, __LINE__, (regs), (code))
 
 
+/****************************************************************
+ * Disk command request
+ ****************************************************************/
+
+struct disk_op_s {
+    u64 lba;
+    void *far_buffer;
+    u16 count;
+    u8 driveid;
+    u8 command;
+};
+
+#define CMD_CDROM_READ 1
+#define CMD_CDEMU_READ 2
+
+
 /****************************************************************
  * Global storage
  ****************************************************************/
@@ -153,6 +169,13 @@ struct ata_s {
 
 // ata.c
 extern struct ata_s ATA;
+int ata_cmd_data(struct disk_op_s *op);
+int cdrom_read(struct disk_op_s *op);
+int cdrom_read_512(struct disk_op_s *op);
+int ata_cmd_packet(int driveid, u8 *cmdbuf, u8 cmdlen
+                   , u32 length, void *far_buffer);
+void ata_reset(int driveid);
+void hard_drive_setup();
 
 // floppy.c
 extern struct floppy_ext_dbt_s diskette_param_table2;
@@ -165,11 +188,9 @@ void disk_13(struct bregs *regs, u8 device);
 void disk_13XX(struct bregs *regs, u8 device);
 
 // cdrom.c
-int cdrom_read_emu(u16 device, u32 lba, u32 count, void *far_buffer);
 void cdrom_13(struct bregs *regs, u8 device);
 void cdemu_13(struct bregs *regs);
 void cdemu_134b(struct bregs *regs);
 int cdrom_boot();
 
-
 #endif // disk.h
index c2a9b62200a4ace39020c45b22ccd7309ecbbc0b..b53bc75d86bc6b2470e63eae34e374e26e602ad4 100644 (file)
@@ -10,7 +10,6 @@
 #include "cmos.h" // CMOS_*
 #include "util.h" // memset
 #include "biosvar.h" // struct bios_data_area_s
-#include "ata.h" // hard_drive_setup
 #include "disk.h" // floppy_drive_setup
 #include "memmap.h" // add_e820
 #include "pic.h" // pic_setup