On Wed, Oct 03, 2012 at 11:29:00AM -0700, Sarah Sharp wrote:
> Hi Don,
> 
> Please test this patch on top of the other patch.

So yeah, that seemed to work. :-)

Thanks!

Cheers,
Don

> 
> 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.sh...@linux.intel.com>
> Reported-by: Don Zickus <dzic...@redhat.com>
> ---
>  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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to