On Thu, 27 Feb 2014 oliver@xxxxxxxxxx wrote: > From: Oliver Neukum <oneukum@xxxxxxx> > > I have a device that times out if enumerated after being > switched on while connected. Increasing timeouts or retries > doesn't help. The device needs an additional reset. > > Signed-off-by: Oliver Neukum <oliver@xxxxxxxxxx> > --- > drivers/usb/core/hub.c | 15 +++++++++++++++ > 1 file changed, 15 insertions(+) > > diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c > index 3489bf1..cf992de 100644 > --- a/drivers/usb/core/hub.c > +++ b/drivers/usb/core/hub.c > @@ -4005,6 +4005,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, > enum usb_device_speed oldspeed = udev->speed; > const char *speed; > int devnum = udev->devnum; > + bool second_reset = false; > > /* root hub ports have a slightly longer reset period > * (from USB 2.0 spec, section 7.1.7.5) > @@ -4136,6 +4137,20 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, > USB_DT_DEVICE << 8, 0, > buf, GET_DESCRIPTOR_BUFSIZE, > initial_descriptor_timeout); > + > + /* > + * Some devices time out if they are powered on > + * when already connected. They need a second > + * reset. > + */ > + if (r == -ETIMEDOUT && !second_reset) { > + retval = hub_port_reset(hub, port1, udev, delay, false); > + second_reset = true; > + if (retval < 0) > + dev_err(&udev->dev, > + "recovery from timeout failed, error %d\n", > + retval); > + } > switch (buf->bMaxPacketSize0) { > case 8: case 16: case 32: case 64: case 255: > if (buf->bDescriptorType == You shouldn't need all this stuff. Just break out of the j loop early if r is -ETIMEDOUT. That is, a few lines below all this, do - if (r == 0) + if (r == 0 || r == -EDTIMEDOUT) break; The code that follows already does a reset. Alan Stern -- 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