[SeaBIOS] [PATCH] Unify ATAPI command processing.

Kevin O'Connor kevin at koconnor.net
Sat Jul 21 19:40:39 CEST 2012


Unify the ATA and AHCI ATAPI command processing into one function in
block.c (process_atapi_op).

This patch disables the existing handlers for ATA ATAPI isready and
reset.  However, it's unlikely that support is needed and it does not
appear that the implemented support is fully correct.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/ahci.c     |   61 +++++++++++++++++---------------------------------------
 src/ata.c      |   58 +++++++++++++----------------------------------------
 src/ata.h      |    1 -
 src/block.c    |   19 ++++++++++++++----
 src/blockcmd.c |    7 ++-----
 src/cdrom.c    |    2 +-
 src/disk.c     |    6 +++---
 src/disk.h     |   13 ++++++------
 8 files changed, 60 insertions(+), 107 deletions(-)

diff --git a/src/ahci.c b/src/ahci.c
index 1d7dbf8..4a8eafb 100644
--- a/src/ahci.c
+++ b/src/ahci.c
@@ -301,49 +301,23 @@ ahci_disk_readwrite(struct disk_op_s *op, int iswrite)
 // command demuxer
 int process_ahci_op(struct disk_op_s *op)
 {
-    struct ahci_port_s *port;
-    u32 atapi;
-
     if (!CONFIG_AHCI)
         return 0;
-
-    port = container_of(op->drive_g, struct ahci_port_s, drive);
-    atapi = GET_GLOBAL(port->atapi);
-
-    if (atapi) {
-        switch (op->command) {
-        case CMD_READ:
-            return cdb_read(op);
-        case CMD_WRITE:
-        case CMD_FORMAT:
-            return DISK_RET_EWRITEPROTECT;
-        case CMD_RESET:
-            /* FIXME: what should we do here? */
-        case CMD_VERIFY:
-        case CMD_SEEK:
-            return DISK_RET_SUCCESS;
-        default:
-            dprintf(1, "AHCI: unknown cdrom command %d\n", op->command);
-            op->count = 0;
-            return DISK_RET_EPARAM;
-        }
-    } else {
-        switch (op->command) {
-        case CMD_READ:
-            return ahci_disk_readwrite(op, 0);
-        case CMD_WRITE:
-            return ahci_disk_readwrite(op, 1);
-        case CMD_RESET:
-            /* FIXME: what should we do here? */
-        case CMD_FORMAT:
-        case CMD_VERIFY:
-        case CMD_SEEK:
-            return DISK_RET_SUCCESS;
-        default:
-            dprintf(1, "AHCI: unknown disk command %d\n", op->command);
-            op->count = 0;
-            return DISK_RET_EPARAM;
-        }
+    switch (op->command) {
+    case CMD_READ:
+        return ahci_disk_readwrite(op, 0);
+    case CMD_WRITE:
+        return ahci_disk_readwrite(op, 1);
+    case CMD_FORMAT:
+    case CMD_RESET:
+    case CMD_ISREADY:
+    case CMD_VERIFY:
+    case CMD_SEEK:
+        return DISK_RET_SUCCESS;
+    default:
+        dprintf(1, "AHCI: unknown disk command %d\n", op->command);
+        op->count = 0;
+        return DISK_RET_EPARAM;
     }
 }
 
@@ -516,12 +490,12 @@ static int ahci_port_init(struct ahci_port_s *port)
             return -1;
     }
 
-    port->drive.type = DTYPE_AHCI;
     port->drive.cntl_id = pnr;
     port->drive.removable = (buffer[0] & 0x80) ? 1 : 0;
 
     if (!port->atapi) {
         // found disk (ata)
+        port->drive.type = DTYPE_AHCI;
         port->drive.blksize = DISK_SECTOR_SIZE;
         port->drive.pchs.cylinders = buffer[1];
         port->drive.pchs.heads = buffer[3];
@@ -548,11 +522,12 @@ static int ahci_port_init(struct ahci_port_s *port)
         port->prio = bootprio_find_ata_device(ctrl->pci_tmp, pnr, 0);
     } else {
         // found cdrom (atapi)
+        port->drive.type = DTYPE_AHCI_ATAPI;
         port->drive.blksize = CDROM_SECTOR_SIZE;
         port->drive.sectors = (u64)-1;
         u8 iscd = ((buffer[0] >> 8) & 0x1f) == 0x05;
         if (!iscd) {
-            dprintf(1, "AHCI/%d: atapi device is'nt a cdrom\n", port->pnr);
+            dprintf(1, "AHCI/%d: atapi device isn't a cdrom\n", port->pnr);
             return -1;
         }
         port->desc = znprintf(MAXDESCSIZE
diff --git a/src/ata.c b/src/ata.c
index 3246acb..7ff5f86 100644
--- a/src/ata.c
+++ b/src/ata.c
@@ -141,31 +141,6 @@ isready(struct atadrive_s *adrive_g)
     return DISK_RET_ENOTREADY;
 }
 
-// Default 16bit command demuxer for ATA and ATAPI devices.
-static int
-process_ata_misc_op(struct disk_op_s *op)
-{
-    if (!CONFIG_ATA)
-        return 0;
-
-    struct atadrive_s *adrive_g = container_of(
-        op->drive_g, struct atadrive_s, drive);
-    switch (op->command) {
-    case CMD_RESET:
-        ata_reset(adrive_g);
-        return DISK_RET_SUCCESS;
-    case CMD_ISREADY:
-        return isready(adrive_g);
-    case CMD_FORMAT:
-    case CMD_VERIFY:
-    case CMD_SEEK:
-        return DISK_RET_SUCCESS;
-    default:
-        op->count = 0;
-        return DISK_RET_EPARAM;
-    }
-}
-
 
 /****************************************************************
  * ATA send command
@@ -580,13 +555,25 @@ process_ata_op(struct disk_op_s *op)
     if (!CONFIG_ATA)
         return 0;
 
+    struct atadrive_s *adrive_g = container_of(
+        op->drive_g, struct atadrive_s, drive);
     switch (op->command) {
     case CMD_READ:
         return ata_readwrite(op, 0);
     case CMD_WRITE:
         return ata_readwrite(op, 1);
+    case CMD_RESET:
+        ata_reset(adrive_g);
+        return DISK_RET_SUCCESS;
+    case CMD_ISREADY:
+        return isready(adrive_g);
+    case CMD_FORMAT:
+    case CMD_VERIFY:
+    case CMD_SEEK:
+        return DISK_RET_SUCCESS;
     default:
-        return process_ata_misc_op(op);
+        op->count = 0;
+        return DISK_RET_EPARAM;
     }
 }
 
@@ -662,23 +649,6 @@ fail:
     return DISK_RET_SUCCESS;
 }
 
-// 16bit command demuxer for ATAPI cdroms.
-int
-process_atapi_op(struct disk_op_s *op)
-{
-    if (!CONFIG_ATA)
-        return 0;
-    switch (op->command) {
-    case CMD_READ:
-        return cdb_read(op);
-    case CMD_FORMAT:
-    case CMD_WRITE:
-        return DISK_RET_EWRITEPROTECT;
-    default:
-        return process_ata_misc_op(op);
-    }
-}
-
 
 /****************************************************************
  * ATA detect and init
@@ -762,7 +732,7 @@ init_drive_atapi(struct atadrive_s *dummy, u16 *buffer)
     struct atadrive_s *adrive_g = init_atadrive(dummy, buffer);
     if (!adrive_g)
         return NULL;
-    adrive_g->drive.type = DTYPE_ATAPI;
+    adrive_g->drive.type = DTYPE_ATA_ATAPI;
     adrive_g->drive.blksize = CDROM_SECTOR_SIZE;
     adrive_g->drive.sectors = (u64)-1;
     u8 iscd = ((buffer[0] >> 8) & 0x1f) == 0x05;
diff --git a/src/ata.h b/src/ata.h
index cfc6108..1f41233 100644
--- a/src/ata.h
+++ b/src/ata.h
@@ -28,7 +28,6 @@ int cdrom_read(struct disk_op_s *op);
 int atapi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize);
 void ata_setup(void);
 int process_ata_op(struct disk_op_s *op);
-int process_atapi_op(struct disk_op_s *op);
 
 // Global defines -- ATA register and register bits.
 // command block & control block regs
diff --git a/src/block.c b/src/block.c
index 2de9c5d..1c200cc 100644
--- a/src/block.c
+++ b/src/block.c
@@ -280,8 +280,6 @@ map_floppy_drive(struct drive_s *drive_g)
 static int
 process_scsi_op(struct disk_op_s *op)
 {
-    if (!CONFIG_VIRTIO_SCSI && !CONFIG_USB_MSC && !CONFIG_USB_UAS && !CONFIG_LSI_SCSI)
-        return 0;
     switch (op->command) {
     case CMD_READ:
         return cdb_read(op);
@@ -299,6 +297,18 @@ process_scsi_op(struct disk_op_s *op)
     }
 }
 
+static int
+process_atapi_op(struct disk_op_s *op)
+{
+    switch (op->command) {
+    case CMD_WRITE:
+    case CMD_FORMAT:
+        return DISK_RET_EWRITEPROTECT;
+    default:
+        return process_scsi_op(op);
+    }
+}
+
 // Execute a disk_op request.
 int
 process_op(struct disk_op_s *op)
@@ -310,8 +320,6 @@ process_op(struct disk_op_s *op)
         return process_floppy_op(op);
     case DTYPE_ATA:
         return process_ata_op(op);
-    case DTYPE_ATAPI:
-        return process_atapi_op(op);
     case DTYPE_RAMDISK:
         return process_ramdisk_op(op);
     case DTYPE_CDEMU:
@@ -320,6 +328,9 @@ process_op(struct disk_op_s *op)
         return process_virtio_blk_op(op);
     case DTYPE_AHCI:
         return process_ahci_op(op);
+    case DTYPE_ATA_ATAPI:
+    case DTYPE_AHCI_ATAPI:
+        return process_atapi_op(op);
     case DTYPE_USB:
     case DTYPE_UAS:
     case DTYPE_VIRTIO_SCSI:
diff --git a/src/blockcmd.c b/src/blockcmd.c
index 0d0acfd..95406c6 100644
--- a/src/blockcmd.c
+++ b/src/blockcmd.c
@@ -23,13 +23,13 @@ cdb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize)
 {
     u8 type = GET_GLOBAL(op->drive_g->type);
     switch (type) {
-    case DTYPE_ATAPI:
+    case DTYPE_ATA_ATAPI:
         return atapi_cmd_data(op, cdbcmd, blocksize);
     case DTYPE_USB:
         return usb_cmd_data(op, cdbcmd, blocksize);
     case DTYPE_UAS:
         return uas_cmd_data(op, cdbcmd, blocksize);
-    case DTYPE_AHCI:
+    case DTYPE_AHCI_ATAPI:
         return ahci_cmd_data(op, cdbcmd, blocksize);
     case DTYPE_VIRTIO_SCSI:
         return virtio_scsi_cmd_data(op, cdbcmd, blocksize);
@@ -96,9 +96,6 @@ scsi_is_ready(struct disk_op_s *op)
 int
 scsi_init_drive(struct drive_s *drive, const char *s, int prio)
 {
-    if (!CONFIG_USB_UAS && !CONFIG_USB_MSC && !CONFIG_VIRTIO_SCSI && !CONFIG_LSI_SCSI)
-        return 0;
-
     struct disk_op_s dop;
     memset(&dop, 0, sizeof(dop));
     dop.drive_g = drive;
diff --git a/src/cdrom.c b/src/cdrom.c
index 6e0055d..42d8e08 100644
--- a/src/cdrom.c
+++ b/src/cdrom.c
@@ -201,7 +201,7 @@ cdrom_boot(struct drive_s *drive_g)
         dprintf(1, "scsi_is_ready returned %d\n", ret);
 
     // Read the Boot Record Volume Descriptor
-    u8 buffer[2048];
+    u8 buffer[CDROM_SECTOR_SIZE];
     dop.lba = 0x11;
     dop.count = 1;
     dop.buf_fl = buffer;
diff --git a/src/disk.c b/src/disk.c
index 8eff464..8e1d3ec 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -530,7 +530,7 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g)
             , size, type, npc, nph, npspt, (u32)lba, blksize);
 
     SET_FARVAR(seg, param_far->size, 26);
-    if (type == DTYPE_ATAPI) {
+    if (type == DTYPE_ATA_ATAPI) {
         // 0x74 = removable, media change, lockable, max values
         SET_FARVAR(seg, param_far->infos, 0x74);
         SET_FARVAR(seg, param_far->cylinders, 0xffffffff);
@@ -552,7 +552,7 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g)
     SET_FARVAR(seg, param_far->blksize, blksize);
 
     if (size < 30 ||
-        (type != DTYPE_ATA && type != DTYPE_ATAPI &&
+        (type != DTYPE_ATA && type != DTYPE_ATA_ATAPI &&
          type != DTYPE_VIRTIO_BLK && type != DTYPE_VIRTIO_SCSI)) {
         disk_ret(regs, DISK_RET_SUCCESS);
         return;
@@ -565,7 +565,7 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g)
     u64 device_path = 0;
     u8 channel = 0;
     SET_FARVAR(seg, param_far->size, 30);
-    if (type == DTYPE_ATA || type == DTYPE_ATAPI) {
+    if (type == DTYPE_ATA || type == DTYPE_ATA_ATAPI) {
         SET_FARVAR(seg, param_far->dpte, SEGOFF(SEG_LOW, (u32)&DefaultDPTE));
 
         // Fill in dpte
diff --git a/src/disk.h b/src/disk.h
index 6810cd7..2b2511f 100644
--- a/src/disk.h
+++ b/src/disk.h
@@ -224,15 +224,16 @@ struct drive_s {
 #define DTYPE_NONE         0x00
 #define DTYPE_FLOPPY       0x01
 #define DTYPE_ATA          0x02
-#define DTYPE_ATAPI        0x03
+#define DTYPE_ATA_ATAPI    0x03
 #define DTYPE_RAMDISK      0x04
 #define DTYPE_CDEMU        0x05
 #define DTYPE_AHCI         0x06
-#define DTYPE_VIRTIO_SCSI  0x07
-#define DTYPE_VIRTIO_BLK   0x08
-#define DTYPE_USB          0x09
-#define DTYPE_UAS          0x0a
-#define DTYPE_LSI_SCSI     0x0b
+#define DTYPE_AHCI_ATAPI   0x07
+#define DTYPE_VIRTIO_SCSI  0x08
+#define DTYPE_VIRTIO_BLK   0x09
+#define DTYPE_USB          0x0a
+#define DTYPE_UAS          0x0b
+#define DTYPE_LSI_SCSI     0x0c
 
 #define MAXDESCSIZE 80
 
-- 
1.7.10.4




More information about the SeaBIOS mailing list