[SeaBIOS] [PATCH 01/17] block: Split process_op() command dispatch up into multiple functions

Kevin O'Connor kevin at koconnor.net
Tue Jul 7 21:26:05 CEST 2015


Introduce process_op_32(), process_op_16(), and process_op_both() and
split the disk driver command dispatch by its runtime mode
requirements.  This makes it more clear which modes each driver runs
in.  It also reduces the call32() boiler-plate code.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/block.c         | 125 +++++++++++++++++++++++++++++-----------------------
 src/hw/ahci.c       |   2 +-
 src/hw/blockcmd.c   |   2 +-
 src/hw/sdcard.c     |   2 +-
 src/hw/virtio-blk.c |   2 +-
 5 files changed, 73 insertions(+), 60 deletions(-)

diff --git a/src/block.c b/src/block.c
index a9b9851..e534319 100644
--- a/src/block.c
+++ b/src/block.c
@@ -464,10 +464,10 @@ fill_edd(u16 seg, struct int13dpt_s *param_far, struct drive_s *drive_gf)
 
 
 /****************************************************************
- * 16bit calling interface
+ * Disk driver dispatch
  ****************************************************************/
 
-int VISIBLE32FLAT
+static int
 process_atapi_op(struct disk_op_s *op)
 {
     switch (op->command) {
@@ -479,72 +479,85 @@ process_atapi_op(struct disk_op_s *op)
     }
 }
 
-// Execute a disk_op request.
-int
-process_op(struct disk_op_s *op)
+// Command dispatch for disk drivers that run in both 16bit and 32bit mode
+static int
+process_op_both(struct disk_op_s *op)
 {
-    ASSERT16();
-    int ret, origcount = op->count;
-    if (origcount * GET_GLOBALFLAT(op->drive_gf->blksize) > 64*1024) {
-        op->count = 0;
-        return DISK_RET_EBOUNDARY;
-    }
-    u8 type = GET_GLOBALFLAT(op->drive_gf->type);
-    switch (type) {
-    case DTYPE_FLOPPY:
-        ret = process_floppy_op(op);
-        break;
-    case DTYPE_ATA:
-        ret = process_ata_op(op);
-        break;
-    case DTYPE_RAMDISK:
-        ret = process_ramdisk_op(op);
-        break;
-    case DTYPE_CDEMU:
-        ret = process_cdemu_op(op);
-        break;
-    case DTYPE_VIRTIO_BLK: ;
-        extern void _cfunc32flat_process_virtio_blk_op(void);
-        ret = call32(_cfunc32flat_process_virtio_blk_op
-                     , (u32)MAKE_FLATPTR(GET_SEG(SS), op), DISK_RET_EPARAM);
-        break;
-    case DTYPE_AHCI: ;
-        extern void _cfunc32flat_process_ahci_op(void);
-        ret = call32(_cfunc32flat_process_ahci_op
-                     , (u32)MAKE_FLATPTR(GET_SEG(SS), op), DISK_RET_EPARAM);
-        break;
+    switch (GET_GLOBALFLAT(op->drive_gf->type)) {
     case DTYPE_ATA_ATAPI:
-        ret = process_atapi_op(op);
-        break;
-    case DTYPE_AHCI_ATAPI: ;
-        extern void _cfunc32flat_process_atapi_op(void);
-        ret = call32(_cfunc32flat_process_atapi_op
-                     , (u32)MAKE_FLATPTR(GET_SEG(SS), op), DISK_RET_EPARAM);
-        break;
-    case DTYPE_SDCARD: ;
-        extern void _cfunc32flat_process_sdcard_op(void);
-        ret = call32(_cfunc32flat_process_sdcard_op
-                     , (u32)MAKE_FLATPTR(GET_SEG(SS), op), DISK_RET_EPARAM);
-        break;
+        return process_atapi_op(op);
     case DTYPE_USB:
     case DTYPE_UAS:
     case DTYPE_LSI_SCSI:
     case DTYPE_ESP_SCSI:
     case DTYPE_MEGASAS:
-        ret = scsi_process_op(op);
-        break;
+        return scsi_process_op(op);
+    default:
+        if (!MODESEGMENT)
+            return DISK_RET_EPARAM;
+        // In 16bit mode and driver not found - try in 32bit mode
+        extern void _cfunc32flat_process_op_32(void);
+        return call32(_cfunc32flat_process_op_32
+                      , (u32)MAKE_FLATPTR(GET_SEG(SS), op), DISK_RET_EPARAM);
+    }
+}
+
+// Command dispatch for disk drivers that only run in 32bit mode
+int VISIBLE32FLAT
+process_op_32(struct disk_op_s *op)
+{
+    ASSERT32FLAT();
+    switch (op->drive_gf->type) {
+    case DTYPE_VIRTIO_BLK:
+        return process_virtio_blk_op(op);
+    case DTYPE_AHCI:
+        return process_ahci_op(op);
+    case DTYPE_AHCI_ATAPI:
+        return process_atapi_op(op);
+    case DTYPE_SDCARD:
+        return process_sdcard_op(op);
     case DTYPE_USB_32:
     case DTYPE_UAS_32:
     case DTYPE_VIRTIO_SCSI:
-    case DTYPE_PVSCSI: ;
-        extern void _cfunc32flat_scsi_process_op(void);
-        ret = call32(_cfunc32flat_scsi_process_op
-                     , (u32)MAKE_FLATPTR(GET_SEG(SS), op), DISK_RET_EPARAM);
-        break;
+    case DTYPE_PVSCSI:
+        return scsi_process_op(op);
     default:
-        ret = DISK_RET_EPARAM;
-        break;
+        return process_op_both(op);
     }
+}
+
+// Command dispatch for disk drivers that only run in 16bit mode
+static int
+process_op_16(struct disk_op_s *op)
+{
+    ASSERT16();
+    switch (GET_GLOBALFLAT(op->drive_gf->type)) {
+    case DTYPE_FLOPPY:
+        return process_floppy_op(op);
+    case DTYPE_ATA:
+        return process_ata_op(op);
+    case DTYPE_RAMDISK:
+        return process_ramdisk_op(op);
+    case DTYPE_CDEMU:
+        return process_cdemu_op(op);
+    default:
+        return process_op_both(op);
+    }
+}
+
+// Execute a disk_op_s request.
+int
+process_op(struct disk_op_s *op)
+{
+    int ret, origcount = op->count;
+    if (origcount * GET_GLOBALFLAT(op->drive_gf->blksize) > 64*1024) {
+        op->count = 0;
+        return DISK_RET_EBOUNDARY;
+    }
+    if (MODESEGMENT)
+        ret = process_op_16(op);
+    else
+        ret = process_op_32(op);
     if (ret && op->count == origcount)
         // If the count hasn't changed on error, assume no data transferred.
         op->count = 0;
diff --git a/src/hw/ahci.c b/src/hw/ahci.c
index 0d71cc4..82fce42 100644
--- a/src/hw/ahci.c
+++ b/src/hw/ahci.c
@@ -296,7 +296,7 @@ ahci_disk_readwrite(struct disk_op_s *op, int iswrite)
 }
 
 // command demuxer
-int VISIBLE32FLAT
+int
 process_ahci_op(struct disk_op_s *op)
 {
     if (!CONFIG_AHCI)
diff --git a/src/hw/blockcmd.c b/src/hw/blockcmd.c
index 4440201..3128f0a 100644
--- a/src/hw/blockcmd.c
+++ b/src/hw/blockcmd.c
@@ -166,7 +166,7 @@ cdb_write(struct disk_op_s *op)
  * Main SCSI commands
  ****************************************************************/
 
-int VISIBLE32FLAT
+int
 scsi_process_op(struct disk_op_s *op)
 {
     switch (op->command) {
diff --git a/src/hw/sdcard.c b/src/hw/sdcard.c
index 6ff93c8..626f042 100644
--- a/src/hw/sdcard.c
+++ b/src/hw/sdcard.c
@@ -208,7 +208,7 @@ sdcard_readwrite(struct disk_op_s *op, int iswrite)
     return DISK_RET_SUCCESS;
 }
 
-int VISIBLE32FLAT
+int
 process_sdcard_op(struct disk_op_s *op)
 {
     if (!CONFIG_SDCARD)
diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c
index 29bc4a5..0a02a03 100644
--- a/src/hw/virtio-blk.c
+++ b/src/hw/virtio-blk.c
@@ -77,7 +77,7 @@ virtio_blk_op(struct disk_op_s *op, int write)
     return status == VIRTIO_BLK_S_OK ? DISK_RET_SUCCESS : DISK_RET_EBADTRACK;
 }
 
-int VISIBLE32FLAT
+int
 process_virtio_blk_op(struct disk_op_s *op)
 {
     if (! CONFIG_VIRTIO_BLK)
-- 
1.9.3




More information about the SeaBIOS mailing list