This looks fine, I'll add it to my xHCI queue next week and make sure to Cc you when I send it to Greg, along with a couple other bug fixes that have been languishing from Paul Zimmerman. Thanks, Sarah Sharp On Fri, Feb 11, 2011 at 11:33:10AM -0800, Luben Tuikov wrote: > If the device isn't reset, the XHCI HCD sends > SET ADDRESS to address 0 while the device is > already in Addressed state, and the request is > dropped on the floor as it is addressed to the > default address. This sequence of events, which this > patch fixes looks like this: > > usb_reset_and_verify_device() > hub_port_init() > hub_set_address() > SET_ADDRESS to 0 with 1 > usb_get_device_descriptor(udev, 8) > usb_get_device_descriptor(udev, 18) > descriptors_changed() --> goto re_enumerate: > hub_port_logical_disconnect() > kick_khubd() > > And then: > > hub_events() > hub_port_connect_change() > usb_disconnect() > usb_disable_device() > new device struct > sets device state to Powered > choose_address() > hub_port_init() <-- no reset, but SET ADDRESS to 0 with 1, timeout! > > The solution is to always reset the device in > hub_port_init() to put it in a known state. > > Signed-off-by: Luben Tuikov <ltuikov@xxxxxxxxx> > --- > drivers/usb/core/hub.c | 18 +++++++----------- > 1 files changed, 7 insertions(+), 11 deletions(-) > > diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c > index 4310cc4..7e8c482 100644 > --- a/drivers/usb/core/hub.c > +++ b/drivers/usb/core/hub.c > @@ -2681,17 +2681,13 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, > > mutex_lock(&usb_address0_mutex); > > - if (!udev->config && oldspeed == USB_SPEED_SUPER) { > - /* Don't reset USB 3.0 devices during an initial setup */ > - usb_set_device_state(udev, USB_STATE_DEFAULT); > - } else { > - /* Reset the device; full speed may morph to high speed */ > - /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ > - retval = hub_port_reset(hub, port1, udev, delay); > - if (retval < 0) /* error or disconnect */ > - goto fail; > - /* success, speed is known */ > - } > + /* Reset the device; full speed may morph to high speed */ > + /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ > + retval = hub_port_reset(hub, port1, udev, delay); > + if (retval < 0) /* error or disconnect */ > + goto fail; > + /* success, speed is known */ > + > retval = -ENODEV; > > if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) { > -- > 1.7.0.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