Skip to content

Commit

Permalink
xhci: Do not halt the host until both HCD have disconnected their dev…
Browse files Browse the repository at this point in the history
…ices.

We can't halt the host controller immediately when first HCD is removed as
it will cause problems if we have devices attached to the second (primary)
HCD, like a keyboard.

We've been carrying this in our Linux-as-a-bootloader environment for a
little while now. The machines all have the same TI TUSB73x0 part,
and when we kexec the devices don't come back until a system power cycle.

[minor adjustments, code comments and remove HALT check  -Mathias]
Signed-off-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Joel Stanley authored and Greg Kroah-Hartman committed Apr 8, 2017
1 parent b7f769a commit fe190ed
Showing 1 changed file with 10 additions and 10 deletions.
20 changes: 10 additions & 10 deletions drivers/usb/host/xhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -692,21 +692,21 @@ void xhci_stop(struct usb_hcd *hcd)

mutex_lock(&xhci->mutex);

if (!(xhci->xhc_state & XHCI_STATE_HALTED)) {
spin_lock_irq(&xhci->lock);

xhci->xhc_state |= XHCI_STATE_HALTED;
xhci->cmd_ring_state = CMD_RING_STATE_STOPPED;
xhci_halt(xhci);
xhci_reset(xhci);
spin_unlock_irq(&xhci->lock);
}

/* Only halt host and free memory after both hcds are removed */
if (!usb_hcd_is_primary_hcd(hcd)) {
/* usb core will free this hcd shortly, unset pointer */
xhci->shared_hcd = NULL;
mutex_unlock(&xhci->mutex);
return;
}

spin_lock_irq(&xhci->lock);
xhci->xhc_state |= XHCI_STATE_HALTED;
xhci->cmd_ring_state = CMD_RING_STATE_STOPPED;
xhci_halt(xhci);
xhci_reset(xhci);
spin_unlock_irq(&xhci->lock);

xhci_cleanup_msix(xhci);

/* Deleting Compliance Mode Recovery Timer */
Expand Down

0 comments on commit fe190ed

Please sign in to comment.