We can't halt the secondary HCD, because it's also the primary HCD, which will cause problems if we have devices attached to the 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. I'd like some advice on an acceptable way to upstream the fix, so that the xhci device survives kexec. Signed-off-by: Joel Stanley <joel@xxxxxxxxx> --- drivers/usb/host/xhci.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index adc169d2fd76..ec92a843325b 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -682,6 +682,21 @@ void xhci_stop(struct usb_hcd *hcd) mutex_lock(&xhci->mutex); + /* + * We can't halt the secondary HCD, because it's also the primary + * HCD, which will cause problems if we have devices attached to the + * primary HCD, like a keyboard. + */ + if (!usb_hcd_is_primary_hcd(hcd)) { + /* The shared_hcd is going to be deallocated shortly (the USB + * core only calls this function when allocation fails in + * usb_add_hcd(), or usb_remove_hcd() is called). So we need + * to unset xHCI's pointer. */ + xhci->shared_hcd = NULL; + mutex_unlock(&xhci->mutex); + return; + } + if (!(xhci->xhc_state & XHCI_STATE_HALTED)) { spin_lock_irq(&xhci->lock); @@ -693,11 +708,6 @@ void xhci_stop(struct usb_hcd *hcd) spin_unlock_irq(&xhci->lock); } - if (!usb_hcd_is_primary_hcd(hcd)) { - mutex_unlock(&xhci->mutex); - return; - } - xhci_cleanup_msix(xhci); /* Deleting Compliance Mode Recovery Timer */ -- 2.9.3 -- 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