There is a FIXME note in usb_kick_khubd() that it may have problems if the hub isn't bound to the hub driver yet. Since the xHCI hardware can send a port status change event as soon as the interrupts are turned on, there is a race condition between registering khubd and the xHCI host controller driver. Solve this by ignoring port status change events until after khubd polls the port status bits for the first time. khubd should notice any changes from previous events at that time. Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx> --- drivers/usb/host/xhci-hub.c | 1 + drivers/usb/host/xhci-ring.c | 13 +++++++++---- drivers/usb/host/xhci.h | 2 ++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index eac5b53..904c20f 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -154,6 +154,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, case GetPortStatus: if (!wIndex || wIndex > ports) goto error; + xhci->state |= XHCI_HUB_REGISTERED; wIndex--; status = 0; addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS*(wIndex & 0xff); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 588686f..b268be6 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -699,10 +699,15 @@ static void handle_port_status(struct xhci_hcd *xhci, inc_deq(xhci, xhci->event_ring, true); xhci_set_hc_event_deq(xhci); - spin_unlock(&xhci->lock); - /* Pass this up to the core */ - usb_hcd_poll_rh_status(xhci_to_hcd(xhci)); - spin_lock(&xhci->lock); + if (xhci->state & XHCI_HUB_REGISTERED) { + spin_unlock(&xhci->lock); + /* Pass this up to the core */ + usb_hcd_poll_rh_status(xhci_to_hcd(xhci)); + spin_lock(&xhci->lock); + } else { + xhci_dbg(xhci, "xHCI roothub not registered," + "ignoring port status event.\n"); + } } /* diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 60770c8..7c661de 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1024,6 +1024,8 @@ struct xhci_hcd { int noops_submitted; int noops_handled; int error_bitmask; + unsigned int state; +#define XHCI_HUB_REGISTERED (1 << 0) }; /* For testing purposes */ -- 1.5.6.5 -- 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