When a FireWire CD-ROM or RBC harddisk was detached, the ieee1394
subsystem and probably the scsi subsystem was locked up. The fix
unblocks the sbp2 host before attempting to remove scsi devices.
Commands from scsi highlevel are no longer blocked, but rather
completed with DID_NO_CONNECT when the FireWire node was detached.

Signed-off-by: Stefan Richter <[EMAIL PROTECTED]>

Index: sbp2.c
===================================================================
--- sbp2.c      (revision 1316)
+++ sbp2.c      (working copy)
@@ -637,8 +637,11 @@
        scsi_id = ud->device.driver_data;
 
        /* Trigger shutdown functions in scsi's highlevel. */
-       if (scsi_id && scsi_id->sdev)
+       if (scsi_id) {
+               BUG_ON(!scsi_id->scsi_host || !scsi_id->sdev);
+               scsi_unblock_requests(scsi_id->scsi_host);
                scsi_remove_device(scsi_id->sdev);
+       }
 
        sbp2_logout_device(scsi_id);
        sbp2_remove_device(scsi_id);
@@ -2310,6 +2313,7 @@
        struct scsi_id_instance_data *scsi_id =
                (struct scsi_id_instance_data 
*)SCpnt->device->host->hostdata[0];
        struct sbp2scsi_host_info *hi;
+       int result = DID_NO_CONNECT << 16;
 
        SBP2_DEBUG("sbp2scsi_queuecommand");
 
@@ -2317,30 +2321,28 @@
         * If scsi_id is null, it means there is no device in this slot,
         * so we should return selection timeout.
         */
-       if (!scsi_id) {
-               SCpnt->result = DID_NO_CONNECT << 16;
-               done (SCpnt);
-               return 0;
-       }
+       if (!scsi_id)
+               goto done;
 
+       /*
+        * Node was detached.
+        */
+       if (scsi_id->ne->in_limbo)
+               goto done;
+
        hi = scsi_id->hi;
 
        if (!hi) {
                SBP2_ERR("sbp2scsi_host_info is NULL - this is bad!");
-               SCpnt->result = DID_NO_CONNECT << 16;
-               done (SCpnt);
-               return(0);
+               goto done;
        }
 
        /*
         * Until we handle multiple luns, just return selection time-out
         * to any IO directed at non-zero LUNs
         */
-       if (SCpnt->device->lun) {
-               SCpnt->result = DID_NO_CONNECT << 16;
-               done (SCpnt);
-               return(0);
-       }
+       if (SCpnt->device->lun)
+               goto done;
 
        /*
         * Check for request sense command, and handle it here
@@ -2351,7 +2353,7 @@
                memcpy(SCpnt->request_buffer, SCpnt->sense_buffer, 
SCpnt->request_bufflen);
                memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
                sbp2scsi_complete_command(scsi_id, SBP2_SCSI_STATUS_GOOD, 
SCpnt, done);
-               return(0);
+               return 0;
        }
 
        /*
@@ -2359,9 +2361,8 @@
         */
        if (!hpsb_node_entry_valid(scsi_id->ne)) {
                SBP2_ERR("Bus reset in progress - rejecting command");
-               SCpnt->result = DID_BUS_BUSY << 16;
-               done (SCpnt);
-               return(0);
+               result = DID_BUS_BUSY << 16;
+               goto done;
        }
 
        /*
@@ -2372,8 +2373,12 @@
                sbp2scsi_complete_command(scsi_id, 
SBP2_SCSI_STATUS_SELECTION_TIMEOUT,
                                          SCpnt, done);
        }
+       return 0;
 
-       return(0);
+done:
+       SCpnt->result = result;
+       done(SCpnt);
+       return 0;
 }
 
 /*

-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to