diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2016-07-26 23:34:33 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-07-26 23:34:33 -0700 |
| commit | 6870e5d936aa2badb677ee2f52a941d240b9d22e (patch) | |
| tree | 3078c7df601940392402e58a70f65a20dd4faf71 | |
| parent | 92a41a2846e75083e9078cebd69ef3a7b75a5ad3 (diff) | |
| parent | 30f5d80b01688672b5910d3c80b1da1f79106e37 (diff) | |
Merge "xhci: fix 10 second timeout on removal of PCI hotpluggable xhci controllers"
| -rw-r--r-- | drivers/usb/host/xhci-pci.c | 1 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-ring.c | 3 | ||||
| -rw-r--r-- | drivers/usb/host/xhci.c | 8 | ||||
| -rw-r--r-- | drivers/usb/host/xhci.h | 1 |
4 files changed, 9 insertions, 4 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index c2d65206ec6c..6c47c26b5df7 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -299,6 +299,7 @@ static void xhci_pci_remove(struct pci_dev *dev) struct xhci_hcd *xhci; xhci = hcd_to_xhci(pci_get_drvdata(dev)); + xhci->xhc_state |= XHCI_STATE_REMOVING; if (xhci->shared_hcd) { usb_remove_hcd(xhci->shared_hcd); usb_put_hcd(xhci->shared_hcd); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index db0f0831b94f..2b63969c2bbf 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -4008,7 +4008,8 @@ static int queue_command(struct xhci_hcd *xhci, struct xhci_command *cmd, int reserved_trbs = xhci->cmd_ring_reserved_trbs; int ret; - if (xhci->xhc_state) { + if ((xhci->xhc_state & XHCI_STATE_DYING) || + (xhci->xhc_state & XHCI_STATE_HALTED)) { xhci_dbg(xhci, "xHCI dying or halted, can't queue_command\n"); return -ESHUTDOWN; } diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 42f74d55e3bd..dd7669331d00 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -155,7 +155,8 @@ static int xhci_start(struct xhci_hcd *xhci) "waited %u microseconds.\n", XHCI_MAX_HALT_USEC); if (!ret) - xhci->xhc_state &= ~(XHCI_STATE_HALTED | XHCI_STATE_DYING); + /* clear state flags. Including dying, halted or removing */ + xhci->xhc_state = 0; return ret; } @@ -2762,7 +2763,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) if (ret <= 0) return ret; xhci = hcd_to_xhci(hcd); - if (xhci->xhc_state & XHCI_STATE_DYING) + if ((xhci->xhc_state & XHCI_STATE_DYING) || + (xhci->xhc_state & XHCI_STATE_REMOVING)) return -ENODEV; xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); @@ -3809,7 +3811,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, mutex_lock(&xhci->mutex); - if (xhci->xhc_state) /* dying or halted */ + if (xhci->xhc_state) /* dying, removing or halted */ goto out; if (!udev->slot_id) { diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index a6e94e029a10..dc03aac4f88a 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1604,6 +1604,7 @@ struct xhci_hcd { */ #define XHCI_STATE_DYING (1 << 0) #define XHCI_STATE_HALTED (1 << 1) +#define XHCI_STATE_REMOVING (1 << 2) /* Statistics */ int error_bitmask; unsigned int quirks; |
