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

Reply via email to