Re: [PATCH v2] usb: hub: Allow reset retry for USB2 devices on connect bounce

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

 



On Tue, 17 Oct 2017, Mathias Nyman wrote:

> If the connect status change is set during reset signaling, but
> the status remains connected just retry port reset.
> 
> This solves an issue with connecting a 90W HP Thunderbolt 3 dock
> with a Lenovo Carbon x1 (5th generation) which causes a 30min loop
> of a high speed device being re-discovererd before usb ports starts
> working.
> 
> [...]
> [ 389.023845] usb 3-1: new high-speed USB device number 55 using xhci_hcd
> [ 389.491841] usb 3-1: new high-speed USB device number 56 using xhci_hcd
> [ 389.959928] usb 3-1: new high-speed USB device number 57 using xhci_hcd
> [...]
> 
> This is caused by a high speed device that doesn't successfully go to the
> enabled state after the second port reset. Instead the connection bounces
> (connected, with connect status change), bailing out completely from
> enumeration just to restart from scratch.
> 
> Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1716332
> 
> Cc: Stable <stable@xxxxxxxxxxxxxxx>
> Signed-off-by: Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx>
> ---
> v2 changes:
>   clear connect change bit in hub_port_wait_reset() where it was detected
> 
>  drivers/usb/core/hub.c | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index 41eaf0b..763b455 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -2710,13 +2710,16 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
>  	if (!(portstatus & USB_PORT_STAT_CONNECTION))
>  		return -ENOTCONN;
>  
> -	/* bomb out completely if the connection bounced.  A USB 3.0
> -	 * connection may bounce if multiple warm resets were issued,
> +	/* Retry if connect change is set but status is still connected.
> +	 * A USB 3.0 connection may bounce if multiple warm resets were issued,
>  	 * but the device may have successfully re-connected. Ignore it.
>  	 */
>  	if (!hub_is_superspeed(hub->hdev) &&
> -			(portchange & USB_PORT_STAT_C_CONNECTION))
> -		return -ENOTCONN;
> +	    (portchange & USB_PORT_STAT_C_CONNECTION)) {
> +		usb_clear_port_feature(hub->hdev, port1,
> +				       USB_PORT_FEAT_C_CONNECTION);
> +		return -EAGAIN;
> +	}
>  
>  	if (!(portstatus & USB_PORT_STAT_ENABLE))
>  		return -EBUSY;
> 

Acked-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]