|
@@ -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 */
|