On Tue, 4 Dec 2012, Sarah Sharp wrote:

> If hot and warm reset fails, or a port remains in the Compliance Mode,
> the USB core needs to be able to disable a USB 3.0 port.  Unlike USB 2.0
> ports, once the port is placed into the Disabled link state, it will not
> report any new device connects.  To get device connect notifications, we
> need to put the link into the Disabled state, and then the RxDetect
> state.
> 
> The xHCI driver needs to atomically clear all change bits on USB 3.0
> port disable, so that we get Port Status Change Events for future port
> changes.
> 
> (We could technically do this in the USB core instead of in the xHCI
> roothub code, since the port state machine can't advance out of the
> disabled state until we set the link state to RxDetect.  However,
> external USB 3.0 hubs don't need this code.  They are level-triggered,
> not edge-triggered like xHCI, so they will continue to send interrupt
> events when any change bit is set.  Therefore it doesn't make sense to
> put this code in the USB core.)

Please merge the two previous paragraphs into one, so that it's clear 
you're referring to the "atomically clear all change bits" requirement.

> This patch is part of a series to fix several reports of infinite loops
> on device enumeration failure.  This includes John, when he boots with
> a USB 3.0 device (Roseweil eusb3 enclosure) attached to his NEC 0.96
> host controller.  The fix requires warm reset support, so it does not
> make sense to backport this patch to stable kernels without warm reset
> support.
> 
> This patch should be backported to kernels as old as 3.2, contain the
> commit ID 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: refine warm
> reset logic"
> 
> Signed-off-by: Sarah Sharp <sarah.a.sh...@linux.intel.com>
> Reported-by: John Covici <cov...@ccs.covici.com>
> Cc: sta...@vger.kernel.org

> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -877,6 +877,60 @@ static int hub_hub_status(struct usb_hub *hub,
>       return ret;
>  }
>  
> +static int hub_set_port_link_state(struct usb_hub *hub, int port1,
> +                     unsigned int link_status)
> +{
> +     return set_port_feature(hub->hdev,
> +                     port1 | (link_status << 3),

Shouldn't this be << 8?

> --- a/drivers/usb/host/xhci-hub.c
> +++ b/drivers/usb/host/xhci-hub.c
> @@ -761,12 +761,39 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
> u16 wValue,

>                       /* Software should not attempt to set
>                        * port link state above '5' (Rx.Detect) and the port
>                        * must be enabled.
>                        */
>                       if ((temp & PORT_PE) == 0 ||
> -                             (link_state > USB_SS_PORT_LS_RX_DETECT)) {
> +                             (link_state > USB_SS_PORT_LS_U3)) {
>                               xhci_warn(xhci, "Cannot set link state.\n");
>                               goto error;
>                       }

Looks like the comment needs to be updated too.

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

Reply via email to