> -----Original Message----- > From: linux-usb-owner@xxxxxxxxxxxxxxx [mailto:linux-usb- > owner@xxxxxxxxxxxxxxx] On Behalf Of Elric Fu > Sent: Monday, March 19, 2012 2:56 PM > To: Sarah Sharp > Cc: Elric Fu; linux-usb@xxxxxxxxxxxxxxx > Subject: [PATCH] USB: fix bug of device descriptor got from superspeed > device > > When the Seagate Goflex USB3.0 device is attached to VIA xHCI > host, sometimes the device will down 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. > What's the port link state when this occurs? Is it in U0 state? > 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> > --- > 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..5e4f3e0 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) && > + (udev->descriptor.bcdUSB != 0x0300)) { Perhaps using "< 0x0300" is better. Maybe there will be 3.01, 3.10 devices in the future. Thanks, Andiry > + dev_err(&udev->dev, "get 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 -- 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