Re: [PATCH v2] usb: hub: Cycle HUB power when initialization fails

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

 



On Thu, 9 Nov 2017, Mike Looijmans wrote:

> Sometimes the USB device gets confused about the state of the initialization and
> the connection fails. In particular, the device thinks that it's already set up
> and running while the host thinks the device still needs to be configured. To
> work around this issue, power-cycle the hub's output to issue a sort of "reset"
> to the device. This makes the device restart its state machine and then the
> initialization succeeds.
> 
> This fixes problems where the kernel reports a list of errors like this:
> 
> usb 1-1.3: device not accepting address 19, error -71
> 
> The end result is a non-functioning device. After this patch, the sequence
> becomes like this:
> 
> usb 1-1.3: new high-speed USB device number 18 using ci_hdrc
> usb 1-1.3: device not accepting address 18, error -71
> usb 1-1.3: new high-speed USB device number 19 using ci_hdrc
> usb 1-1.3: device not accepting address 19, error -71
> usb 1-1-port3: attempt power cycle
> usb 1-1.3: new high-speed USB device number 21 using ci_hdrc
> usb-storage 1-1.3:1.2: USB Mass Storage device detected
> 
> Signed-off-by: Mike Looijmans <mike.looijmans@xxxxxxxx>
> ---
> v2: On feedback from Alan Stern:
>       No blank line changes
>       Don't further increase the retry count
>     Delay 2x the power-up delay (100ms minimum) instead of magic "800"
> 
>  drivers/usb/core/hub.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index e9ce6bb..8f7d942 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -4935,6 +4935,15 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
>  		usb_put_dev(udev);
>  		if ((status == -ENOTCONN) || (status == -ENOTSUPP))
>  			break;
> +
> +		/* When halfway through our retry count, power-cycle the port */
> +		if (i == (SET_CONFIG_TRIES / 2) - 1) {
> +			dev_info(&port_dev->dev, "attempt power cycle\n");
> +			usb_hub_set_port_power(hdev, hub, port1, false);
> +			msleep(2 * hub_power_on_good_delay(hub));
> +			usb_hub_set_port_power(hdev, hub, port1, true);
> +			msleep(hub_power_on_good_delay(hub));
> +		}
>  	}
>  	if (hub->hdev->parent ||
>  			!hcd->driver->port_handed_over ||

Acked-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>

--
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