[SeaBIOS] [RFC PATCH 08/16] usb-msc: always go through TEST UNIT READY

Paolo Bonzini pbonzini at redhat.com
Tue Nov 15 17:01:16 CET 2011


Add the wait loop that CDs are already using to usb-msc.  USB drives
might also report NOT READY at startup.

Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
 src/blockcmd.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
 src/blockcmd.h |    2 ++
 src/cdrom.c    |   48 ++----------------------------------------------
 src/usb-msc.c  |    7 ++++++-
 4 files changed, 54 insertions(+), 47 deletions(-)

diff --git a/src/blockcmd.c b/src/blockcmd.c
index f5e2ce3..e86fe29 100644
--- a/src/blockcmd.c
+++ b/src/blockcmd.c
@@ -32,6 +32,50 @@ cdb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize)
 }
 
 int
+scsi_is_ready(struct disk_op_s *op)
+{
+    dprintf(6, "scsi_is_ready (drive=%p)\n", op->drive_g);
+
+    /* Retry TEST UNIT READY for 5 seconds unless MEDIUM NOT PRESENT is
+     * reported by the device.  If the device reports "IN PROGRESS",
+     * 30 seconds is added. */
+    int in_progress = 0;
+    u64 end = calc_future_tsc(5000);
+    for (;;) {
+        if (check_tsc(end)) {
+            dprintf(1, "test unit ready failed\n");
+            return -1;
+        }
+
+        int ret = cdb_test_unit_ready(op);
+        if (!ret)
+            // Success
+            break;
+
+        struct cdbres_request_sense sense;
+        ret = cdb_get_sense(op, &sense);
+        if (ret)
+            // Error - retry.
+            continue;
+
+        // Sense succeeded.
+        if (sense.asc == 0x3a) { /* MEDIUM NOT PRESENT */
+            dprintf(1, "Device reports MEDIUM NOT PRESENT\n");
+            return -1;
+        }
+
+        if (sense.asc == 0x04 && sense.ascq == 0x01 && !in_progress) {
+            /* IN PROGRESS OF BECOMING READY */
+            printf("Waiting for device to detect medium... ");
+            /* Allow 30 seconds more */
+            end = calc_future_tsc(30000);
+            in_progress = 1;
+        }
+    }
+    return 0;
+}
+
+int
 cdb_get_inquiry(struct disk_op_s *op, struct cdbres_inquiry *data)
 {
     struct cdb_request_sense cmd;
diff --git a/src/blockcmd.h b/src/blockcmd.h
index 6923e4c..106a529 100644
--- a/src/blockcmd.h
+++ b/src/blockcmd.h
@@ -80,4 +80,6 @@ int cdb_inquiry(struct disk_op_s *op, struct cdbres_inquiry *data);
 int cdb_read(struct disk_op_s *op);
 int cdb_write(struct disk_op_s *op);
 
+int scsi_is_ready(struct disk_op_s *op);
+
 #endif // blockcmd.h
diff --git a/src/cdrom.c b/src/cdrom.c
index b817999..170ffc4 100644
--- a/src/cdrom.c
+++ b/src/cdrom.c
@@ -184,50 +184,6 @@ cdemu_134b(struct bregs *regs)
  * CD booting
  ****************************************************************/
 
-static int
-atapi_is_ready(struct disk_op_s *op)
-{
-    dprintf(6, "atapi_is_ready (drive=%p)\n", op->drive_g);
-
-    /* Retry TEST UNIT READY for 5 seconds unless MEDIUM NOT PRESENT is
-     * reported by the device.  If the device reports "IN PROGRESS",
-     * 30 seconds is added. */
-    int in_progress = 0;
-    u64 end = calc_future_tsc(5000);
-    for (;;) {
-        if (check_tsc(end)) {
-            dprintf(1, "test unit ready failed\n");
-            return -1;
-        }
-
-        int ret = cdb_test_unit_ready(op);
-        if (!ret)
-            // Success
-            break;
-
-        struct cdbres_request_sense sense;
-        ret = cdb_get_sense(op, &sense);
-        if (ret)
-            // Error - retry.
-            continue;
-
-        // Sense succeeded.
-        if (sense.asc == 0x3a) { /* MEDIUM NOT PRESENT */
-            dprintf(1, "Device reports MEDIUM NOT PRESENT\n");
-            return -1;
-        }
-
-        if (sense.asc == 0x04 && sense.ascq == 0x01 && !in_progress) {
-            /* IN PROGRESS OF BECOMING READY */
-            printf("Waiting for device to detect medium... ");
-            /* Allow 30 seconds more */
-            end = calc_future_tsc(30000);
-            in_progress = 1;
-        }
-    }
-    return 0;
-}
-
 int
 cdrom_boot(struct drive_s *drive_g)
 {
@@ -238,9 +194,9 @@ cdrom_boot(struct drive_s *drive_g)
     if (!dop.drive_g || cdid < 0)
         return 1;
 
-    int ret = atapi_is_ready(&dop);
+    int ret = scsi_is_ready(&dop);
     if (ret)
-        dprintf(1, "atapi_is_ready returned %d\n", ret);
+        dprintf(1, "scsi_is_ready returned %d\n", ret);
 
     // Read the Boot Record Volume Descriptor
     u8 buffer[2048];
diff --git a/src/usb-msc.c b/src/usb-msc.c
index 6cadb71..6f77275 100644
--- a/src/usb-msc.c
+++ b/src/usb-msc.c
@@ -238,11 +238,16 @@ usb_msc_init(struct usb_pipe *pipe
             , vendor, product, rev, pdt, removable);
     udrive_g->drive.removable = removable;
 
+    ret = scsi_is_ready(&dop);
+    if (ret) {
+        dprintf(1, "scsi_is_ready returned %d\n", ret);
+        return ret;
+    }
+
     struct cdbres_read_capacity capdata;
     ret = cdb_read_capacity(&dop, &capdata);
     if (ret)
         return ret;
-    // XXX - retry for some timeout?
 
     // READ CAPACITY returns the address of the last block
     udrive_g->drive.blksize = ntohl(capdata.blksize);
-- 
1.7.7.1





More information about the SeaBIOS mailing list