Re: [PATCH v4] USB: fix bug of device descriptor got from superspeed device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I've applied this to the for-usb-linus-queue branch, thanks.

Sarah Sharp

On Mon, Mar 26, 2012 at 09:16:02PM +0800, Elric Fu wrote:
> When the Seagate Goflex USB3.0 device is attached to VIA xHCI
> host, sometimes the device will downgrade mode to high speed.
> By the USB analyzer, I found the device finished the link
> training process and worked at superspeed mode. But the device
> descriptor got from the device shows the device works at 2.1.
> It is very strange and seems like the device controller of
> Seagate Goflex has a little confusion.
> 
> The first 8 bytes of device descriptor should be:
> 12 01 00 03 00 00 00 09
> 
> But the first 8 bytes of wrong device descriptor are:
> 12 01 10 02 00 00 00 40
> 
> The wrong device descriptor caused the initialization of mass
> storage failed. After a while, the device would be recognized
> as a high speed device and works fine.
> 
> This patch will warm reset the device to fix the issue after
> finding the bcdUSB field of device descriptor isn't 0x0300
> but the speed mode of device is superspeed.
> 
> Signed-off-by: Elric Fu <elricfu1@xxxxxxxxx>
> Acked-by: Andiry Xu <Andiry.Xu@xxxxxxx>
> Acked-by: Sergei Shtylyov <sshtylyov@xxxxxxxxxx>
> ---
>  drivers/usb/core/hub.c |   16 ++++++++++++++++
>  1 files changed, 16 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index 265c2f6..7e619f4 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -3071,6 +3071,22 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
>  	if (retval)
>  		goto fail;
>  
> +	/*
> +	 * Some superspeed devices have finished the link training process
> +	 * and attached to a superspeed hub port, but the device descriptor
> +	 * got from those devices show they aren't superspeed devices. Warm
> +	 * reset the port attached by the devices can fix them.
> +	 */
> +	if ((udev->speed == USB_SPEED_SUPER) &&
> +			(le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) {
> +		dev_err(&udev->dev, "got a wrong device descriptor, "
> +				"warm reset device\n");
> +		hub_port_reset(hub, port1, udev,
> +				HUB_BH_RESET_TIME, true);
> +		retval = -EINVAL;
> +		goto fail;
> +	}
> +
>  	if (udev->descriptor.bMaxPacketSize0 == 0xff ||
>  			udev->speed == USB_SPEED_SUPER)
>  		i = 512;
> -- 
> 1.7.9.1
> 
--
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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux