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.sharp@xxxxxxxxxxxxxxx> > Reported-by: John Covici <covici@xxxxxxxxxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx > --- 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html