Following the recommendation of James Bottomley (of SCSI fame), this patch changes the queuecommand() routine so that when a command is received for a disconnected device, instead of accepting the command and then ignoring it, we fail the command immediately with DID_NO_CONNECT.
This fixes a timeout-abort-oops sequence that would occur when the
higher-level drivers (mostly the CD driver) try to queue a SYNCHRONIZE
CACHE command during scsi_remove_host().
Greg, please apply. If possible, this would be really good to squeeze
in before 2.6.9 goes final, as lots of people will hit this.
Matt
Signed-off-by: Alan Stern <[EMAIL PROTECTED]>
Signed-off-by: Matthew Dharm <[EMAIL PROTECTED]>
===== drivers/usb/storage/scsiglue.c 1.84 vs edited =====
--- 1.84/drivers/usb/storage/scsiglue.c 2004-09-13 08:11:34 -04:00
+++ edited/drivers/usb/storage/scsiglue.c 2004-09-30 16:07:33 -04:00
@@ -175,7 +175,7 @@
US_DEBUGP("%s called\n", __FUNCTION__);
srb->host_scribble = (unsigned char *)us;
- /* enqueue the command */
+ /* check for state-transition errors */
if (us->sm_state != US_STATE_IDLE || us->srb != NULL) {
printk(KERN_ERR USB_STORAGE "Error in %s: "
"state = %d, us->srb = %p\n",
@@ -183,10 +183,17 @@
return SCSI_MLQUEUE_HOST_BUSY;
}
+ /* fail the command if we are disconnecting */
+ if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
+ US_DEBUGP("Fail command during disconnect\n");
+ srb->result = DID_NO_CONNECT << 16;
+ done(srb);
+ return 0;
+ }
+
+ /* enqueue the command and wake up the control thread */
srb->scsi_done = done;
us->srb = srb;
-
- /* wake up the process task */
up(&(us->sema));
return 0;
--
Matthew Dharm Home: [EMAIL PROTECTED]
Maintainer, Linux USB Mass Storage Driver
NYET! The evil stops here!
-- Pitr
User Friendly, 6/22/1998
pgpNpDGvbYZE5.pgp
Description: PGP signature
