Re: [PATCH] usb:super speed warm reset rejudge

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

 



On Fri, 4 Mar 2016, l00229106 wrote:

> Some super speed device, insert the u3 port, sometimes link is in the
> Compliance Mode State(0x340), and then satisfy hub_port_warm_reset_required
> conditions, the software will perform a warm reset, u3 PORTSC becomes
> 0x2a1203. In hub_port_reset function, it will clear
> USB_PORT_FEAT_C_CONNECTION by usb_clear_port_feature. Finally, the u3
> PORTSC become 0x1203 and super speed device can not be recognized.
> 
> The patch can solve it. When the software warm reset, it judge Whether
> the u3 endpoint in the enabled and connected state. if they are, we set
> connect_change = 1. We verify the patch and can correctly identify super
> speed devices.
> 
> Signed-off-by: l00229106 <lpc.li@xxxxxxxxxxxxx>
> ---
>  drivers/usb/core/hub.c | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index 350dcd9..039c4e9 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -5037,8 +5037,18 @@ static void port_event(struct usb_hub *hub, int port1)
>  			usb_reset_device(udev);
>  			usb_unlock_device(udev);
>  			usb_lock_port(port_dev);
> -			connect_change = 0;
>  		}
> +
> +		ret = hub_port_status(hub, i,
> +				&portstatus, &portchange);
> +		if (ret < 0)
> +			return;
> +
> +		if ((portstatus & USB_PORT_STAT_CONNECTION) && !udev &&
> +				portstatus & USB_PORT_STAT_ENABLE)
> +			connect_change = 1;

You should only test for USB_PORT_STAT_CONNECTION.  It doesn't matter
whether USB_PORT_STAT_ENABLE is set; either way, there has been a 
connect-status change.

> +		else
> +			connect_change = 0;
>  	}
>  
>  	if (connect_change)

Aside from the compiler errors found by the kbuild robot, this patch 
was added in the wrong place.  It should come here instead:

	if (hub_port_warm_reset_required(hub, port1, portstatus)) {
		dev_dbg(&port_dev->dev, "do warm reset\n");
		if (!udev || !(portstatus & USB_PORT_STAT_CONNECTION)
				|| udev->state == USB_STATE_NOTATTACHED) {
			if (hub_port_reset(hub, port1, NULL,
					HUB_BH_RESET_TIME, true) < 0)
				hub_port_disable(hub, port1, 1);
+			else {
+				...
+			}
		} else {

because the new code gets executed only when udev is NULL.

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



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux