From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759604AbcISGgV (ORCPT ); Mon, 19 Sep 2016 02:36:21 -0400 Received: from mail-pf0-f196.google.com ([209.85.192.196]:32862 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753067AbcISGgM (ORCPT ); Mon, 19 Sep 2016 02:36:12 -0400 From: Joel Stanley To: linux-usb@vger.kernel.org Cc: linux-kernel@vger.kernel.org, gregkh@linuxfoundation.org Subject: [RFC PATCH] xhci: do not halt the secondary HCD Date: Mon, 19 Sep 2016 16:05:45 +0930 Message-Id: <20160919063545.2055-1-joel@jms.id.au> X-Mailer: git-send-email 2.9.3 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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