]> git.neil.brown.name Git - history.git/commitdiff
Change to the USB core to retry failed devices on startup.
authorGreg Kroah-Hartman <greg@kroah.com>
Thu, 16 May 2002 08:40:19 +0000 (01:40 -0700)
committerGreg Kroah-Hartman <greg@kroah.com>
Thu, 16 May 2002 08:40:19 +0000 (01:40 -0700)
Based on a patch from Georg Acher <georg@acher.org>

drivers/usb/core/usb.c

index 801d6b4c77821c9b4b6aa6a5ee3e41d485126ad7..f5c7f45f1d7514bb3dc4aa101cbaa73c3cc05e55 100644 (file)
@@ -2583,9 +2583,13 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
  * Only hub drivers (including virtual root hub drivers for host
  * controllers) should ever call this.
  */
+#define NEW_DEVICE_RETRYS      2
+#define SET_ADDRESS_RETRYS     2
 int usb_new_device(struct usb_device *dev)
 {
        int err;
+       int i;
+       int j;
 
        /* USB v1.1 5.5.3 */
        /* We read the first 8 bytes from the device descriptor to get to */
@@ -2594,18 +2598,30 @@ int usb_new_device(struct usb_device *dev)
        dev->epmaxpacketin [0] = 8;
        dev->epmaxpacketout[0] = 8;
 
-       err = usb_set_address(dev);
-       if (err < 0) {
-               err("USB device not accepting new address=%d (error=%d)",
-                       dev->devnum, err);
-               clear_bit(dev->devnum, dev->bus->devmap.devicemap);
-               dev->devnum = -1;
-               return 1;
-       }
+       for (i = 0; i < NEW_DEVICE_RETRYS; ++i) {
 
-       wait_ms(10);    /* Let the SET_ADDRESS settle */
+               for (j = 0; j < SET_ADDRESS_RETRYS; ++j) {
+                       err = usb_set_address(dev);
+                       if (err >= 0)
+                               break;
+                       wait_ms(200);
+               }
+               if (err < 0) {
+                       err("USB device not accepting new address=%d (error=%d)",
+                               dev->devnum, err);
+                       clear_bit(dev->devnum, dev->bus->devmap.devicemap);
+                       dev->devnum = -1;
+                       return 1;
+               }
+
+               wait_ms(10);    /* Let the SET_ADDRESS settle */
+
+               err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8);
+               if (err >= 8)
+                       break;
+               wait_ms(100);
+       }
 
-       err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8);
        if (err < 8) {
                if (err < 0)
                        err("USB device not responding, giving up (error=%d)", err);