On Thu, 27 Feb 2014 oli...@neukum.org wrote:
> From: Oliver Neukum
>
> 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
> ---
> 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;
> + boolsecond_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 majord...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html