|
|
@@ -3961,6 +3961,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.
|
|
|
@@ -4015,23 +4018,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);
|
|
|
}
|
|
|
}
|
|
|
|