ChangeSet 1.2181.4.60, 2005/03/24 15:13:20-08:00, [EMAIL PROTECTED]
[PATCH] USB Storage: exit control thread immediately upon disconnect
This patch started life as as475 from Alan Stern. It has been rediffed
against the tip, tho that was several days ago.
This patch causes the main control thread to exit as soon as possible,
i.e., as soon as the DISCONNECTING flag is set. It no longer waits for
an
explicit exit command, one with srb == NULL.
There won't be any bad implications for our interaction with the SCSI
midlayer, because once the DISCONNECTING flag is set we fail every
submitted command immediately in the queuecommand routine. And if a
command manages to squeeze through the crack (submitted and accepted
before we disconnect but not yet processed), the SCSI midlayer will
cancel
it automatically when we remove the host.
Signed-off-by: Alan Stern <[EMAIL PROTECTED]>
Signed-off-by: Matthew Dharm <[EMAIL PROTECTED]>
Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
usb.c | 45 +++++++++------------------------------------
1 files changed, 9 insertions(+), 36 deletions(-)
diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c 2005-03-30 15:16:53 -08:00
+++ b/drivers/usb/storage/usb.c 2005-03-30 15:16:53 -08:00
@@ -304,9 +304,9 @@
/* lock the device pointers */
down(&(us->dev_semaphore));
- /* if us->srb is NULL, we are being asked to exit */
- if (us->srb == NULL) {
- US_DEBUGP("-- exit command received\n");
+ /* if the device has disconnected, we are free to exit */
+ if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
+ US_DEBUGP("-- exiting\n");
up(&(us->dev_semaphore));
break;
}
@@ -320,12 +320,6 @@
goto SkipForAbort;
}
- /* don't do anything if we are disconnecting */
- if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
- US_DEBUGP("No command during disconnect\n");
- goto SkipForDisconnect;
- }
-
scsi_unlock(host);
/* reject the command if the direction indicator
@@ -393,7 +387,6 @@
complete(&(us->notify));
/* finished working on this command */
-SkipForDisconnect:
us->srb = NULL;
scsi_unlock(host);
@@ -776,33 +769,12 @@
{
US_DEBUGP("-- %s\n", __FUNCTION__);
- /* Kill the control thread. The SCSI host must already have been
- * removed so it won't try to queue any more commands.
+ /* Tell the control thread to exit. The SCSI host must
+ * already have been removed so it won't try to queue
+ * any more commands.
*/
- if (us->pid) {
-
- /* Wait for the thread to be idle */
- down(&us->dev_semaphore);
- US_DEBUGP("-- sending exit command to thread\n");
-
- /* If the SCSI midlayer queued a final command just before
- * scsi_remove_host() was called, us->srb might not be
- * NULL. We can overwrite it safely, because the midlayer
- * will not wait for the command to finish. Also the
- * control thread will already have been awakened.
- * That's okay, an extra up() on us->sema won't hurt.
- *
- * Enqueue the command, wake up the thread, and wait for
- * notification that it has exited.
- */
- scsi_lock(us_to_host(us));
- us->srb = NULL;
- scsi_unlock(us_to_host(us));
- up(&us->dev_semaphore);
-
- up(&us->sema);
- wait_for_completion(&us->notify);
- }
+ US_DEBUGP("-- sending exit command to thread\n");
+ up(&us->sema);
/* Call the destructor routine, if it exists */
if (us->extra_destructor) {
@@ -975,6 +947,7 @@
/* We come here if there are any problems */
BadDevice:
US_DEBUGP("storage_probe() failed\n");
+ set_bit(US_FLIDX_DISCONNECTING, &us->flags);
usb_stor_release_resources(us);
dissociate_dev(us);
scsi_host_put(host);
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html