]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[scsi] Eliminate polling while waiting for window to open
authorMichael Brown <mcb30@ipxe.org>
Fri, 24 Jun 2011 16:14:46 +0000 (17:14 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 28 Jun 2011 13:45:12 +0000 (14:45 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/block/scsi.c

index 016a6c55a7bbe88e02e991881bcdc4828c55076c..fb90fbce46dd395c72668c88f88e0bdc37238f8e 100644 (file)
@@ -218,8 +218,10 @@ struct scsi_device {
 
 /** SCSI device flags */
 enum scsi_device_flags {
-       /** Unit is ready */
-       SCSIDEV_UNIT_READY = 0x0001,
+       /** TEST UNIT READY has been issued */
+       SCSIDEV_UNIT_TESTED = 0x0001,
+       /** TEST UNIT READY has completed successfully */
+       SCSIDEV_UNIT_READY = 0x0002,
 };
 
 /** A SCSI command */
@@ -897,16 +899,20 @@ static struct interface_descriptor scsidev_ready_desc =
 static void scsidev_step ( struct scsi_device *scsidev ) {
        int rc;
 
+       /* Do nothing if we have already issued TEST UNIT READY */
+       if ( scsidev->flags & SCSIDEV_UNIT_TESTED )
+               return;
+
        /* Wait until underlying SCSI device is ready */
        if ( xfer_window ( &scsidev->scsi ) == 0 )
                return;
 
-       /* Stop process */
-       process_del ( &scsidev->process );
-
        DBGC ( scsidev, "SCSI %p waiting for unit to become ready\n",
               scsidev );
 
+       /* Mark TEST UNIT READY as sent */
+       scsidev->flags |= SCSIDEV_UNIT_TESTED;
+
        /* Issue TEST UNIT READY command */
        if ( ( rc = scsidev_test_unit_ready ( scsidev, &scsidev->ready )) !=0){
                scsidev_close ( scsidev, rc );
@@ -916,6 +922,7 @@ static void scsidev_step ( struct scsi_device *scsidev ) {
 
 /** SCSI device SCSI interface operations */
 static struct interface_operation scsidev_scsi_op[] = {
+       INTF_OP ( xfer_window_changed, struct scsi_device *, scsidev_step ),
        INTF_OP ( intf_close, struct scsi_device *, scsidev_close ),
 };
 
@@ -926,7 +933,7 @@ static struct interface_descriptor scsidev_scsi_desc =
 
 /** SCSI device process descriptor */
 static struct process_descriptor scsidev_process_desc =
-       PROC_DESC ( struct scsi_device, process, scsidev_step );
+       PROC_DESC_ONCE ( struct scsi_device, process, scsidev_step );
 
 /**
  * Open SCSI device