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 <[email protected]>
Reported-by: Don Zickus <[email protected]>
---
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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html