diff options
| author | Jack Pham <jackp@codeaurora.org> | 2015-12-09 15:52:43 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 21:22:04 -0700 |
| commit | 3a490dd6ebf9e5ac5d8b457be2ce58794249416c (patch) | |
| tree | ed89991a2ec4e2d5a4a059958745a6606be52e44 /drivers/usb | |
| parent | 3d2c84e2f1c0694ac6e50f7a901caf365edf1681 (diff) | |
usb: xhci: clean up command queue when halting
Calling usb_remove_hcd() on both of the xHCI HCDs may race with
hub_event() which executes on its own workqueue. When xhci_halt()
is called and stops the command ring, the hub thread may have
already issued a command such as xhci_configure_endpoint() and
is currently waiting for the command to complete while holding
the device lock. Meanwhile since the controller is already halted,
no events are expected to complete and the command timer will
continually timeout every 5 seconds and re-arm itself. Since the
completion for the command is never issued, the threads are
essentially deadlocked.
Avoid this situation when halting the controller by forcing the
command queue to be cleaned up.
Change-Id: I88150e3435b5f06e37e9881dddaeff4807c24cc9
Signed-off-by: Jack Pham <jackp@codeaurora.org>
Diffstat (limited to 'drivers/usb')
| -rw-r--r-- | drivers/usb/host/xhci.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index b9577ebbb2b1..e57340a86eb3 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -117,6 +117,13 @@ int xhci_halt(struct xhci_hcd *xhci) if (!ret) { xhci->xhc_state |= XHCI_STATE_HALTED; xhci->cmd_ring_state = CMD_RING_STATE_STOPPED; + + if (timer_pending(&xhci->cmd_timer)) { + xhci_dbg_trace(xhci, trace_xhci_dbg_init, + "Cleanup command queue"); + del_timer(&xhci->cmd_timer); + xhci_cleanup_command_queue(xhci); + } } else xhci_warn(xhci, "Host not halted after %u microseconds.\n", XHCI_MAX_HALT_USEC); |
