Merge commit 'origin/master' into next
[sfrench/cifs-2.6.git] / drivers / usb / core / hub.c
index cd50d86029e7a719ed5bff47db80e6fca3cb7e6b..be86ae3f40881516d529a894319ed52c71086b82 100644 (file)
@@ -392,7 +392,7 @@ static void hub_irq(struct urb *urb)
 {
        struct usb_hub *hub = urb->context;
        int status = urb->status;
-       int i;
+       unsigned i;
        unsigned long bits;
 
        switch (status) {
@@ -1305,6 +1305,7 @@ void usb_set_device_state(struct usb_device *udev,
                recursively_mark_NOTATTACHED(udev);
        spin_unlock_irqrestore(&device_state_lock, flags);
 }
+EXPORT_SYMBOL_GPL(usb_set_device_state);
 
 /*
  * WUSB devices are simple: they have no hubs behind, so the mapping
@@ -2471,20 +2472,20 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
         */
        switch (udev->speed) {
        case USB_SPEED_VARIABLE:        /* fixed at 512 */
-               udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(512);
+               udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
                break;
        case USB_SPEED_HIGH:            /* fixed at 64 */
-               udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
+               udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
                break;
        case USB_SPEED_FULL:            /* 8, 16, 32, or 64 */
                /* to determine the ep0 maxpacket size, try to read
                 * the device descriptor to get bMaxPacketSize0 and
                 * then correct our initial guess.
                 */
-               udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
+               udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
                break;
        case USB_SPEED_LOW:             /* fixed at 8 */
-               udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(8);
+               udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8);
                break;
        default:
                goto fail;
@@ -3392,10 +3393,10 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
                udev->descriptor = descriptor;  /* for disconnect() calls */
                goto re_enumerate;
        }
-  
+
+       /* Restore the device's previous configuration */
        if (!udev->actconfig)
                goto done;
-
        ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                        USB_REQ_SET_CONFIGURATION, 0,
                        udev->actconfig->desc.bConfigurationValue, 0,
@@ -3408,16 +3409,25 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
        }
        usb_set_device_state(udev, USB_STATE_CONFIGURED);
 
+       /* Put interfaces back into the same altsettings as before.
+        * Don't bother to send the Set-Interface request for interfaces
+        * that were already in altsetting 0; besides being unnecessary,
+        * many devices can't handle it.  Instead just reset the host-side
+        * endpoint state.
+        */
        for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
                struct usb_interface *intf = udev->actconfig->interface[i];
                struct usb_interface_descriptor *desc;
 
-               /* set_interface resets host side toggle even
-                * for altsetting zero.  the interface may have no driver.
-                */
                desc = &intf->cur_altsetting->desc;
-               ret = usb_set_interface(udev, desc->bInterfaceNumber,
-                       desc->bAlternateSetting);
+               if (desc->bAlternateSetting == 0) {
+                       usb_disable_interface(udev, intf, true);
+                       usb_enable_interface(udev, intf, true);
+                       ret = 0;
+               } else {
+                       ret = usb_set_interface(udev, desc->bInterfaceNumber,
+                                       desc->bAlternateSetting);
+               }
                if (ret < 0) {
                        dev_err(&udev->dev, "failed to restore interface %d "
                                "altsetting %d (error=%d)\n",