diff options
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r-- | drivers/usb/core/hub.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 0f38f577c047..309425bb8e7f 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2092,6 +2092,12 @@ void usb_disconnect(struct usb_device **pdev) */ pm_runtime_barrier(&udev->dev); + if (udev->speed < USB_SPEED_HIGH ) { + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + if (hcd->driver->change_bus_speed) + hcd->driver->change_bus_speed(hcd, 0); + } + usb_lock_device(udev); hub_disconnect_children(udev); @@ -4871,9 +4877,19 @@ loop: if (hub->hdev->parent || !hcd->driver->port_handed_over || !(hcd->driver->port_handed_over)(hcd, port1)) { - if (status != -ENOTCONN && status != -ENODEV) + if (status != -ENOTCONN && status != -ENODEV) { dev_err(&port_dev->dev, - "unable to enumerate USB device\n"); + "unable to enumerate USB device" + " at %s while bus at %s \n", + usb_speed_string(udev->speed), + hdev->descriptor.bDeviceProtocol == USB_HUB_PR_FS ? + "FULL_SPEED" : "HIGH_SPEED"); + + if (udev->speed < USB_SPEED_HIGH && + hdev->descriptor.bDeviceProtocol > USB_HUB_PR_FS && + hcd->driver->change_bus_speed) + hcd->driver->change_bus_speed(hcd, 1); + } } done: |