Hi Don, Please test this patch on top of the other patch. Sarah Sharp >8-------------------------------------------------------------------8< Some USB 3.0 devices signal that they don't implement Link PM by having all zeroes in the U1/U2 exit latencies in their SuperSpeed BOS descriptor. Don found that a Western Digital device he has experiences transfer errors when LPM is enabled. The lsusb shows the U1/U2 exit latencies are set to zero: Binary Object Store Descriptor: bLength 5 bDescriptorType 15 wTotalLength 22 bNumDeviceCaps 2 SuperSpeed USB Device Capability: bLength 10 bDescriptorType 16 bDevCapabilityType 3 bmAttributes 0x00 Latency Tolerance Messages (LTM) Supported wSpeedsSupported 0x000e Device can operate at Full Speed (12Mbps) Device can operate at High Speed (480Mbps) Device can operate at SuperSpeed (5Gbps) bFunctionalitySupport 1 Lowest fully-functional device speed is Full Speed (12Mbps) bU1DevExitLat 0 micro seconds bU2DevExitLat 0 micro seconds The fix is to not enable LPM for a particular link state if we find its corresponding exit latency is zero. Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx> Reported-by: Don Zickus <dzickus@xxxxxxxxxx> --- drivers/usb/core/hub.c | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 55bef91..2568441 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3484,8 +3484,16 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, enum usb3_link_state state) { int timeout; - __u8 u1_mel; - __le16 u2_mel; + __u8 u1_mel = udev->bos->ss_cap->bU1devExitLat; + __le16 u2_mel = udev->bos->ss_cap->bU2DevExitLat; + + /* If the device says it doesn't have *any* exit latency to come out of + * U1 or U2, it's probably lying. Assume it doesn't implement that link + * state. + */ + if ((state == USB3_LPM_U1 && u1_mel == 0) || + (state == USB3_LPM_U2 && u2_mel == 0)) + return; /* We allow the host controller to set the U1/U2 timeout internally * first, so that it can change its schedule to account for the @@ -3512,8 +3520,6 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, * link commands. This can cause transfer errors, so only enable * device-initiated LPM. */ - u1_mel = udev->bos->ss_cap->bU1devExitLat; - u2_mel = udev->bos->ss_cap->bU2DevExitLat; if ((state == USB3_LPM_U1 && u1_mel == USB_U1_MAX_VALID_MEL) || (state == USB3_LPM_U2 && le16_to_cpu(u2_mel) == USB_U2_MAX_VALID_MEL)) { -- 1.7.9 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html