usb: Don't enable LPM if the exit latency is zero.
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. This patch should be backported to kernels as old as 3.5, that contain the commit 1ea7e0e8e3d0f50901d335ea4178ab2aa8c88201 "USB: Add support to enable/disable USB3 link states." Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Reported-by: Don Zickus <dzickus@redhat.com> Tested-by: Don Zickus <dzickus@redhat.com> Cc: stable@vger.kernel.org
This commit is contained in:
parent
d01f87c0ff
commit
ae8963adb4
@ -3415,6 +3415,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 = 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user