diff options
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r-- | drivers/usb/core/hub.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index cd50d86029e7..be86ae3f4088 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -392,7 +392,7 @@ static void hub_irq(struct urb *urb) | |||
392 | { | 392 | { |
393 | struct usb_hub *hub = urb->context; | 393 | struct usb_hub *hub = urb->context; |
394 | int status = urb->status; | 394 | int status = urb->status; |
395 | int i; | 395 | unsigned i; |
396 | unsigned long bits; | 396 | unsigned long bits; |
397 | 397 | ||
398 | switch (status) { | 398 | switch (status) { |
@@ -1305,6 +1305,7 @@ void usb_set_device_state(struct usb_device *udev, | |||
1305 | recursively_mark_NOTATTACHED(udev); | 1305 | recursively_mark_NOTATTACHED(udev); |
1306 | spin_unlock_irqrestore(&device_state_lock, flags); | 1306 | spin_unlock_irqrestore(&device_state_lock, flags); |
1307 | } | 1307 | } |
1308 | EXPORT_SYMBOL_GPL(usb_set_device_state); | ||
1308 | 1309 | ||
1309 | /* | 1310 | /* |
1310 | * WUSB devices are simple: they have no hubs behind, so the mapping | 1311 | * 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, | |||
2471 | */ | 2472 | */ |
2472 | switch (udev->speed) { | 2473 | switch (udev->speed) { |
2473 | case USB_SPEED_VARIABLE: /* fixed at 512 */ | 2474 | case USB_SPEED_VARIABLE: /* fixed at 512 */ |
2474 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(512); | 2475 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); |
2475 | break; | 2476 | break; |
2476 | case USB_SPEED_HIGH: /* fixed at 64 */ | 2477 | case USB_SPEED_HIGH: /* fixed at 64 */ |
2477 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64); | 2478 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); |
2478 | break; | 2479 | break; |
2479 | case USB_SPEED_FULL: /* 8, 16, 32, or 64 */ | 2480 | case USB_SPEED_FULL: /* 8, 16, 32, or 64 */ |
2480 | /* to determine the ep0 maxpacket size, try to read | 2481 | /* to determine the ep0 maxpacket size, try to read |
2481 | * the device descriptor to get bMaxPacketSize0 and | 2482 | * the device descriptor to get bMaxPacketSize0 and |
2482 | * then correct our initial guess. | 2483 | * then correct our initial guess. |
2483 | */ | 2484 | */ |
2484 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64); | 2485 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); |
2485 | break; | 2486 | break; |
2486 | case USB_SPEED_LOW: /* fixed at 8 */ | 2487 | case USB_SPEED_LOW: /* fixed at 8 */ |
2487 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(8); | 2488 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8); |
2488 | break; | 2489 | break; |
2489 | default: | 2490 | default: |
2490 | goto fail; | 2491 | goto fail; |
@@ -3392,10 +3393,10 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
3392 | udev->descriptor = descriptor; /* for disconnect() calls */ | 3393 | udev->descriptor = descriptor; /* for disconnect() calls */ |
3393 | goto re_enumerate; | 3394 | goto re_enumerate; |
3394 | } | 3395 | } |
3395 | 3396 | ||
3397 | /* Restore the device's previous configuration */ | ||
3396 | if (!udev->actconfig) | 3398 | if (!udev->actconfig) |
3397 | goto done; | 3399 | goto done; |
3398 | |||
3399 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 3400 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
3400 | USB_REQ_SET_CONFIGURATION, 0, | 3401 | USB_REQ_SET_CONFIGURATION, 0, |
3401 | udev->actconfig->desc.bConfigurationValue, 0, | 3402 | udev->actconfig->desc.bConfigurationValue, 0, |
@@ -3408,16 +3409,25 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
3408 | } | 3409 | } |
3409 | usb_set_device_state(udev, USB_STATE_CONFIGURED); | 3410 | usb_set_device_state(udev, USB_STATE_CONFIGURED); |
3410 | 3411 | ||
3412 | /* Put interfaces back into the same altsettings as before. | ||
3413 | * Don't bother to send the Set-Interface request for interfaces | ||
3414 | * that were already in altsetting 0; besides being unnecessary, | ||
3415 | * many devices can't handle it. Instead just reset the host-side | ||
3416 | * endpoint state. | ||
3417 | */ | ||
3411 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { | 3418 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { |
3412 | struct usb_interface *intf = udev->actconfig->interface[i]; | 3419 | struct usb_interface *intf = udev->actconfig->interface[i]; |
3413 | struct usb_interface_descriptor *desc; | 3420 | struct usb_interface_descriptor *desc; |
3414 | 3421 | ||
3415 | /* set_interface resets host side toggle even | ||
3416 | * for altsetting zero. the interface may have no driver. | ||
3417 | */ | ||
3418 | desc = &intf->cur_altsetting->desc; | 3422 | desc = &intf->cur_altsetting->desc; |
3419 | ret = usb_set_interface(udev, desc->bInterfaceNumber, | 3423 | if (desc->bAlternateSetting == 0) { |
3420 | desc->bAlternateSetting); | 3424 | usb_disable_interface(udev, intf, true); |
3425 | usb_enable_interface(udev, intf, true); | ||
3426 | ret = 0; | ||
3427 | } else { | ||
3428 | ret = usb_set_interface(udev, desc->bInterfaceNumber, | ||
3429 | desc->bAlternateSetting); | ||
3430 | } | ||
3421 | if (ret < 0) { | 3431 | if (ret < 0) { |
3422 | dev_err(&udev->dev, "failed to restore interface %d " | 3432 | dev_err(&udev->dev, "failed to restore interface %d " |
3423 | "altsetting %d (error=%d)\n", | 3433 | "altsetting %d (error=%d)\n", |