diff options
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/Kconfig | 1 | ||||
-rw-r--r-- | drivers/usb/core/devio.c | 8 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 32 |
3 files changed, 21 insertions, 20 deletions
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index bdb6bd0b63a6..ecaacc8ed311 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -45,7 +45,6 @@ config USB_DYNAMIC_MINORS config USB_OTG bool "OTG support" depends on PM - default n help The most notable feature of USB OTG is support for a "Dual-Role" device, which can act as either a device diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index fa783531ee88..aa17dab6c4ea 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -2130,6 +2130,9 @@ static int proc_ioctl(struct usb_dev_state *ps, struct usbdevfs_ioctl *ctl) if (ps->privileges_dropped) return -EACCES; + if (!connected(ps)) + return -ENODEV; + /* alloc buffer */ size = _IOC_SIZE(ctl->ioctl_code); if (size > 0) { @@ -2146,11 +2149,6 @@ static int proc_ioctl(struct usb_dev_state *ps, struct usbdevfs_ioctl *ctl) } } - if (!connected(ps)) { - kfree(buf); - return -ENODEV; - } - if (ps->dev->state != USB_STATE_CONFIGURED) retval = -EHOSTUNREACH; else if (!(intf = usb_ifnum_to_if(ps->dev, ctl->ifno))) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 2f94568ba385..572e8c26a129 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3999,6 +3999,9 @@ static int usb_set_lpm_timeout(struct usb_device *udev, * control transfers to set the hub timeout or enable device-initiated U1/U2 * will be successful. * + * If the control transfer to enable device-initiated U1/U2 entry fails, then + * hub-initiated U1/U2 will be disabled. + * * If we cannot set the parent hub U1/U2 timeout, we attempt to let the xHCI * driver know about it. If that call fails, it should be harmless, and just * take up more slightly more bus bandwidth for unnecessary U1/U2 exit latency. @@ -4053,23 +4056,24 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, * host know that this link state won't be enabled. */ hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); - } else { - /* Only a configured device will accept the Set Feature - * U1/U2_ENABLE - */ - if (udev->actconfig) - usb_set_device_initiated_lpm(udev, state, true); + return; + } - /* As soon as usb_set_lpm_timeout(timeout) returns 0, the - * hub-initiated LPM is enabled. Thus, LPM is enabled no - * matter the result of usb_set_device_initiated_lpm(). - * The only difference is whether device is able to initiate - * LPM. - */ + /* Only a configured device will accept the Set Feature + * U1/U2_ENABLE + */ + if (udev->actconfig && + usb_set_device_initiated_lpm(udev, state, true) == 0) { if (state == USB3_LPM_U1) udev->usb3_lpm_u1_enabled = 1; else if (state == USB3_LPM_U2) udev->usb3_lpm_u2_enabled = 1; + } else { + /* Don't request U1/U2 entry if the device + * cannot transition to U1/U2. + */ + usb_set_lpm_timeout(udev, state, 0); + hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); } } @@ -4139,7 +4143,7 @@ int usb_disable_lpm(struct usb_device *udev) if (!udev || !udev->parent || udev->speed < USB_SPEED_SUPER || !udev->lpm_capable || - udev->state < USB_STATE_DEFAULT) + udev->state < USB_STATE_CONFIGURED) return 0; hcd = bus_to_hcd(udev->bus); @@ -4198,7 +4202,7 @@ void usb_enable_lpm(struct usb_device *udev) if (!udev || !udev->parent || udev->speed < USB_SPEED_SUPER || !udev->lpm_capable || - udev->state < USB_STATE_DEFAULT) + udev->state < USB_STATE_CONFIGURED) return; udev->lpm_disable_count--; |