This patch started life as as366, got some modifications, and lives now as
as366b.  It implements a delay in SCSI-layer device scanning for
usb-storage devices at insertion time.

Many devices work better with this delay.  We believe we can remove several
US_FL_FIX_INQUIRY unusual_devs.h entries with this patch.  (That's a hint,
Phil!)

The delay is adjustable via a sysfs parameter which is global to the
usb-storage module.  The default is 5 seconds.

Greg, please apply.

Matt

Signed-off-by: Matthew Dharm <[EMAIL PROTECTED]>
Signed-off-by: Alan Stern <[EMAIL PROTECTED]>

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/09/26 11:39:40-07:00 [EMAIL PROTECTED] 
#   as366
# 
# drivers/usb/storage/usb.h
#   2004/09/26 11:39:13-07:00 [EMAIL PROTECTED] +2 -0
#   as366
# 
# drivers/usb/storage/usb.c
#   2004/09/26 11:39:13-07:00 [EMAIL PROTECTED] +59 -11
#   as366
# 
diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c Sun Sep 26 12:36:08 2004
+++ b/drivers/usb/storage/usb.c Sun Sep 26 12:36:08 2004
@@ -97,6 +97,11 @@
 MODULE_DESCRIPTION("USB Mass Storage driver for Linux");
 MODULE_LICENSE("GPL");
 
+static unsigned int delay_use = 5;
+module_param(delay_use, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device");
+
+
 static int storage_probe(struct usb_interface *iface,
                         const struct usb_device_id *id);
 
@@ -882,6 +887,42 @@
        kfree(us);
 }
 
+/* Thread to carry out delayed SCSI-device scanning */
+static int usb_stor_scan_thread(void * __us)
+{
+       struct us_data *us = (struct us_data *)__us;
+
+       /*
+        * This thread doesn't need any user-level access,
+        * so get rid of all our resources.
+        */
+       lock_kernel();
+       daemonize("usb-stor");
+       current->flags |= PF_NOFREEZE;
+       unlock_kernel();
+
+       printk(KERN_DEBUG
+               "usb-storage: device found at %d\n", us->pusb_dev->devnum);
+
+       /* Wait for the timeout to expire or for a disconnect */
+       if (delay_use > 0) {
+               printk(KERN_DEBUG "usb-storage: waiting for device "
+                               "to settle before scanning\n");
+               wait_event_interruptible_timeout(us->scsi_scan_wait,
+                               test_bit(US_FLIDX_DISCONNECTING, &us->flags),
+                               delay_use * HZ);
+       }
+
+       /* If the device is still connected, perform the scanning */
+       if (!test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
+               scsi_scan_host(us->host);
+               printk(KERN_DEBUG "usb-storage: device scan complete\n");
+       }
+
+       complete_and_exit(&us->scsi_scan_done, 0);
+}
+
+
 /* Probe to see if we can drive a newly-connected USB device */
 static int storage_probe(struct usb_interface *intf,
                         const struct usb_device_id *id)
@@ -903,6 +944,8 @@
        init_MUTEX_LOCKED(&(us->sema));
        init_completion(&(us->notify));
        init_waitqueue_head(&us->dev_reset_wait);
+       init_waitqueue_head(&us->scsi_scan_wait);
+       init_completion(&us->scsi_scan_done);
 
        /* Associate the us_data structure with the USB device */
        result = associate_dev(us, intf);
@@ -951,12 +994,10 @@
        if (result)
                goto BadDevice;
 
-       /* Acquire all the other resources */
+       /* Acquire all the other resources and add the host */
        result = usb_stor_acquire_resources(us);
        if (result)
                goto BadDevice;
-
-       /* Finally, add the host (this does SCSI device scanning) */
        result = scsi_add_host(us->host, &intf->dev);
        if (result) {
                printk(KERN_WARNING USB_STORAGE
@@ -964,10 +1005,15 @@
                goto BadDevice;
        }
 
-       scsi_scan_host(us->host);
+       /* Start up the thread for delayed SCSI-device scanning */
+       result = kernel_thread(usb_stor_scan_thread, us, CLONE_VM);
+       if (result < 0) {
+               printk(KERN_WARNING USB_STORAGE 
+                      "Unable to start the device-scanning thread\n");
+               scsi_remove_host(us->host);
+               goto BadDevice;
+       }
 
-       printk(KERN_DEBUG 
-              "USB Mass Storage device found at %d\n", us->pusb_dev->devnum);
        return 0;
 
        /* We come here if there are any problems */
@@ -991,6 +1037,11 @@
        usb_stor_stop_transport(us);
        wake_up(&us->dev_reset_wait);
 
+       /* Interrupt the SCSI-device-scanning thread's time delay, and
+        * wait for the thread to finish */
+       wake_up(&us->scsi_scan_wait);
+       wait_for_completion(&us->scsi_scan_done);
+
        /* Wait for the current command to finish, then remove the host */
        down(&us->dev_semaphore);
        up(&us->dev_semaphore);
@@ -1012,12 +1063,9 @@
 
        /* register the driver, return usb_register return code if error */
        retval = usb_register(&usb_storage_driver);
-       if (retval)
-               goto out;
+       if (retval == 0)
+               printk(KERN_INFO "USB Mass Storage support registered.\n");
 
-       /* we're all set */
-       printk(KERN_INFO "USB Mass Storage support registered.\n");
-out:
        return retval;
 }
 
diff -Nru a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
--- a/drivers/usb/storage/usb.h Sun Sep 26 12:36:08 2004
+++ b/drivers/usb/storage/usb.h Sun Sep 26 12:36:08 2004
@@ -161,6 +161,8 @@
        struct semaphore        sema;            /* to sleep thread on   */
        struct completion       notify;          /* thread begin/end     */
        wait_queue_head_t       dev_reset_wait;  /* wait during reset    */
+       wait_queue_head_t       scsi_scan_wait;  /* wait before scanning */
+       struct completion       scsi_scan_done;  /* scan thread end      */
 
        /* subdriver information */
        void                    *extra;          /* Any extra data          */

-- 
Matthew Dharm                              Home: [EMAIL PROTECTED] 
Maintainer, Linux USB Mass Storage Driver

Oh BAY-bee.
                                        -- Dust Puppy to Greg
User Friendly, 12/13/1997

Attachment: pgpylYlMBWFPK.pgp
Description: PGP signature

Reply via email to