long timeleft;
        int status;
 
-       /* don't submit URBs during abort/disconnect processing */
-       if (us->dflags & ABORTING_OR_DISCONNECTING)
+       /* don't submit URBs during abort processing */
+       if (test_bit(US_FLIDX_ABORTING, &us->dflags))
                return -EIO;
 
        /* set up data structures for the wakeup system */
         * to cancel it */
        set_bit(US_FLIDX_URB_ACTIVE, &us->dflags);
 
-       /* did an abort/disconnect occur during the submission? */
-       if (us->dflags & ABORTING_OR_DISCONNECTING) {
+       /* did an abort occur during the submission? */
+       if (test_bit(US_FLIDX_ABORTING, &us->dflags)) {
 
                /* cancel the URB, if it hasn't been cancelled already */
                if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags)) {
 {
        int result;
 
-       /* don't submit s-g requests during abort/disconnect processing */
-       if (us->dflags & ABORTING_OR_DISCONNECTING)
+       /* don't submit s-g requests during abort processing */
+       if (test_bit(US_FLIDX_ABORTING, &us->dflags))
                return USB_STOR_XFER_ERROR;
 
        /* initialize the scatter-gather request block */
         * okay to cancel it */
        set_bit(US_FLIDX_SG_ACTIVE, &us->dflags);
 
-       /* did an abort/disconnect occur during the submission? */
-       if (us->dflags & ABORTING_OR_DISCONNECTING) {
+       /* did an abort occur during the submission? */
+       if (test_bit(US_FLIDX_ABORTING, &us->dflags)) {
 
                /* cancel the request, if it hasn't been cancelled already */
                if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags)) {
 
                /* lock the device pointers */
                mutex_lock(&(us->dev_mutex));
 
-               /* if the device has disconnected, we are free to exit */
-               if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
-                       US_DEBUGP("-- exiting\n");
+               /* lock access to the state */
+               scsi_lock(host);
+
+               /* When we are called with no command pending, we're done */
+               if (us->srb == NULL) {
+                       scsi_unlock(host);
                        mutex_unlock(&us->dev_mutex);
+                       US_DEBUGP("-- exiting\n");
                        break;
                }
 
-               /* lock access to the state */
-               scsi_lock(host);
-
                /* has the command timed out *already* ? */
                if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
                        us->srb->result = DID_ABORT << 16;
                /* lock access to the state */
                scsi_lock(host);
 
-               /* did the command already complete because of a disconnect? */
-               if (!us->srb)
-                       ;               /* nothing to do */
-
                /* indicate that the command is done */
-               else if (us->srb->result != DID_ABORT << 16) {
+               if (us->srb->result != DID_ABORT << 16) {
                        US_DEBUGP("scsi cmd done, result=0x%x\n", 
                                   us->srb->result);
                        us->srb->scsi_done(us->srb);
        US_DEBUGP("-- %s\n", __func__);
 
        /* Tell the control thread to exit.  The SCSI host must
-        * already have been removed so it won't try to queue
-        * any more commands.
+        * already have been removed and the DISCONNECTING flag set
+        * so that we won't accept any more commands.
         */
        US_DEBUGP("-- sending exit command to thread\n");
-       set_bit(US_FLIDX_DISCONNECTING, &us->dflags);
        complete(&us->cmnd_ready);
        if (us->ctl_thread)
                kthread_stop(us->ctl_thread);
        usb_set_intfdata(us->pusb_intf, NULL);
 }
 
-/* First stage of disconnect processing: stop all commands and remove
- * the host */
+/* First stage of disconnect processing: stop SCSI scanning,
+ * remove the host, and stop accepting new commands
+ */
 static void quiesce_and_remove_host(struct us_data *us)
 {
        struct Scsi_Host *host = us_to_host(us);
 
-       /* Prevent new USB transfers, stop the current command, and
-        * interrupt a SCSI-scan or device-reset delay */
-       scsi_lock(host);
-       set_bit(US_FLIDX_DISCONNECTING, &us->dflags);
-       scsi_unlock(host);
-       usb_stor_stop_transport(us);
-       wake_up(&us->delay_wait);
+       /* If the device is really gone, cut short reset delays */
+       if (us->pusb_dev->state == USB_STATE_NOTATTACHED)
+               set_bit(US_FLIDX_DISCONNECTING, &us->dflags);
 
-       /* queuecommand won't accept any new commands and the control
-        * thread won't execute a previously-queued command.  If there
-        * is such a command pending, complete it with an error. */
-       mutex_lock(&us->dev_mutex);
-       if (us->srb) {
-               us->srb->result = DID_NO_CONNECT << 16;
-               scsi_lock(host);
-               us->srb->scsi_done(us->srb);
-               us->srb = NULL;
-               complete(&us->notify);          /* in case of an abort */
-               scsi_unlock(host);
-       }
-       mutex_unlock(&us->dev_mutex);
+       /* Prevent SCSI-scanning (if it hasn't started yet)
+        * and wait for the SCSI-scanning thread to stop.
+        */
+       set_bit(US_FLIDX_DONT_SCAN, &us->dflags);
+       wake_up(&us->delay_wait);
+       wait_for_completion(&us->scanning_done);
 
-       /* Now we own no commands so it's safe to remove the SCSI host */
+       /* Removing the host will perform an orderly shutdown: caches
+        * synchronized, disks spun down, etc.
+        */
        scsi_remove_host(host);
 
-       /* Wait for the SCSI-scanning thread to stop */
-       wait_for_completion(&us->scanning_done);
+       /* Prevent any new commands from being accepted and cut short
+        * reset delays.
+        */
+       scsi_lock(host);
+       set_bit(US_FLIDX_DISCONNECTING, &us->dflags);
+       scsi_unlock(host);
+       wake_up(&us->delay_wait);
 }
 
 /* Second stage of disconnect processing: deallocate all resources */
                printk(KERN_DEBUG "usb-storage: waiting for device "
                                "to settle before scanning\n");
                wait_event_freezable_timeout(us->delay_wait,
-                               test_bit(US_FLIDX_DISCONNECTING, &us->dflags),
+                               test_bit(US_FLIDX_DONT_SCAN, &us->dflags),
                                delay_use * HZ);
        }
 
        /* If the device is still connected, perform the scanning */
-       if (!test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
+       if (!test_bit(US_FLIDX_DONT_SCAN, &us->dflags)) {
 
                /* For bulk-only devices, determine the max LUN value */
                if (us->protocol == US_PR_BULK &&
        if (IS_ERR(th)) {
                printk(KERN_WARNING USB_STORAGE 
                       "Unable to start the device-scanning thread\n");
+               complete(&us->scanning_done);
                quiesce_and_remove_host(us);
                result = PTR_ERR(th);
                goto BadDevice;
        .pre_reset =    storage_pre_reset,
        .post_reset =   storage_post_reset,
        .id_table =     storage_usb_ids,
+       .soft_unbind =  1,
 };
 
 static int __init usb_stor_init(void)