Commit 13161f66 authored by Matthew Dharm's avatar Matthew Dharm Committed by Greg Kroah-Hartman

[PATCH] USB Storage: Fix queuecommand() for disconnected devices

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().
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarMatthew Dharm <mdharm-usb@one-eyed-alien.net>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>


===== drivers/usb/storage/scsiglue.c 1.84 vs edited =====
parent 4d483d05
...@@ -175,7 +175,7 @@ static int queuecommand(struct scsi_cmnd *srb, ...@@ -175,7 +175,7 @@ static int queuecommand(struct scsi_cmnd *srb,
US_DEBUGP("%s called\n", __FUNCTION__); US_DEBUGP("%s called\n", __FUNCTION__);
srb->host_scribble = (unsigned char *)us; srb->host_scribble = (unsigned char *)us;
/* enqueue the command */ /* check for state-transition errors */
if (us->sm_state != US_STATE_IDLE || us->srb != NULL) { if (us->sm_state != US_STATE_IDLE || us->srb != NULL) {
printk(KERN_ERR USB_STORAGE "Error in %s: " printk(KERN_ERR USB_STORAGE "Error in %s: "
"state = %d, us->srb = %p\n", "state = %d, us->srb = %p\n",
...@@ -183,10 +183,17 @@ static int queuecommand(struct scsi_cmnd *srb, ...@@ -183,10 +183,17 @@ static int queuecommand(struct scsi_cmnd *srb,
return SCSI_MLQUEUE_HOST_BUSY; 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; srb->scsi_done = done;
us->srb = srb; us->srb = srb;
/* wake up the process task */
up(&(us->sema)); up(&(us->sema));
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment