diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2011-05-23 19:41:17 -0400 |
---|---|---|
committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2011-05-25 18:23:35 -0400 |
commit | fe6c6c13d8dcb32398eef143e2e8efc3fb4019bf (patch) | |
tree | 1e340233ee7136051a1dd4ec3d3b30327e9196d1 /drivers/usb | |
parent | 0714a57c6865f31ed3366e5abdfae7da580d41d2 (diff) |
xhci: Don't submit commands when the host is dead.
When the xHCI host controller dies, the USB core may attempt to reset the
devices to their default configuration before disconnecting them. This
causes calls into the xHCI bandwidth allocation functions. Don't allow
those functions to submit commands or work on xHCI structures if the host
controller is marked as dying.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/xhci.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8f2a56ece44f..58183d2a8089 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -1314,8 +1314,10 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1314 | if (ret <= 0) | 1314 | if (ret <= 0) |
1315 | return ret; | 1315 | return ret; |
1316 | xhci = hcd_to_xhci(hcd); | 1316 | xhci = hcd_to_xhci(hcd); |
1317 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); | 1317 | if (xhci->xhc_state & XHCI_STATE_DYING) |
1318 | return -ENODEV; | ||
1318 | 1319 | ||
1320 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); | ||
1319 | drop_flag = xhci_get_endpoint_flag(&ep->desc); | 1321 | drop_flag = xhci_get_endpoint_flag(&ep->desc); |
1320 | if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) { | 1322 | if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) { |
1321 | xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n", | 1323 | xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n", |
@@ -1401,6 +1403,8 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1401 | return ret; | 1403 | return ret; |
1402 | } | 1404 | } |
1403 | xhci = hcd_to_xhci(hcd); | 1405 | xhci = hcd_to_xhci(hcd); |
1406 | if (xhci->xhc_state & XHCI_STATE_DYING) | ||
1407 | return -ENODEV; | ||
1404 | 1408 | ||
1405 | added_ctxs = xhci_get_endpoint_flag(&ep->desc); | 1409 | added_ctxs = xhci_get_endpoint_flag(&ep->desc); |
1406 | last_ctx = xhci_last_valid_endpoint(added_ctxs); | 1410 | last_ctx = xhci_last_valid_endpoint(added_ctxs); |
@@ -1676,6 +1680,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
1676 | if (ret <= 0) | 1680 | if (ret <= 0) |
1677 | return ret; | 1681 | return ret; |
1678 | xhci = hcd_to_xhci(hcd); | 1682 | xhci = hcd_to_xhci(hcd); |
1683 | if (xhci->xhc_state & XHCI_STATE_DYING) | ||
1684 | return -ENODEV; | ||
1679 | 1685 | ||
1680 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); | 1686 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); |
1681 | virt_dev = xhci->devs[udev->slot_id]; | 1687 | virt_dev = xhci->devs[udev->slot_id]; |