aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/hub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r--drivers/usb/core/hub.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 28664eb7f55..ec6c97dadbe 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1667,7 +1667,6 @@ void usb_disconnect(struct usb_device **pdev)
1667{ 1667{
1668 struct usb_device *udev = *pdev; 1668 struct usb_device *udev = *pdev;
1669 int i; 1669 int i;
1670 struct usb_hcd *hcd = bus_to_hcd(udev->bus);
1671 1670
1672 /* mark the device as inactive, so any further urb submissions for 1671 /* mark the device as inactive, so any further urb submissions for
1673 * this device (and any of its children) will fail immediately. 1672 * this device (and any of its children) will fail immediately.
@@ -1690,9 +1689,7 @@ void usb_disconnect(struct usb_device **pdev)
1690 * so that the hardware is now fully quiesced. 1689 * so that the hardware is now fully quiesced.
1691 */ 1690 */
1692 dev_dbg (&udev->dev, "unregistering device\n"); 1691 dev_dbg (&udev->dev, "unregistering device\n");
1693 mutex_lock(hcd->bandwidth_mutex);
1694 usb_disable_device(udev, 0); 1692 usb_disable_device(udev, 0);
1695 mutex_unlock(hcd->bandwidth_mutex);
1696 usb_hcd_synchronize_unlinks(udev); 1693 usb_hcd_synchronize_unlinks(udev);
1697 1694
1698 usb_remove_ep_devs(&udev->ep0); 1695 usb_remove_ep_devs(&udev->ep0);
@@ -3163,6 +3160,22 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
3163 if (retval) 3160 if (retval)
3164 goto fail; 3161 goto fail;
3165 3162
3163 /*
3164 * Some superspeed devices have finished the link training process
3165 * and attached to a superspeed hub port, but the device descriptor
3166 * got from those devices show they aren't superspeed devices. Warm
3167 * reset the port attached by the devices can fix them.
3168 */
3169 if ((udev->speed == USB_SPEED_SUPER) &&
3170 (le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) {
3171 dev_err(&udev->dev, "got a wrong device descriptor, "
3172 "warm reset device\n");
3173 hub_port_reset(hub, port1, udev,
3174 HUB_BH_RESET_TIME, true);
3175 retval = -EINVAL;
3176 goto fail;
3177 }
3178
3166 if (udev->descriptor.bMaxPacketSize0 == 0xff || 3179 if (udev->descriptor.bMaxPacketSize0 == 0xff ||
3167 udev->speed == USB_SPEED_SUPER) 3180 udev->speed == USB_SPEED_SUPER)
3168 i = 512; 3181 i = 512;