diff options
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r-- | drivers/usb/host/xhci.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index d9660eb97eb9..06e7023258d0 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -430,12 +430,19 @@ int xhci_run(struct usb_hcd *hcd) | |||
430 | free_irq(hcd->irq, hcd); | 430 | free_irq(hcd->irq, hcd); |
431 | hcd->irq = -1; | 431 | hcd->irq = -1; |
432 | 432 | ||
433 | /* Some Fresco Logic host controllers advertise MSI, but fail to | ||
434 | * generate interrupts. Don't even try to enable MSI. | ||
435 | */ | ||
436 | if (xhci->quirks & XHCI_BROKEN_MSI) | ||
437 | goto legacy_irq; | ||
438 | |||
433 | ret = xhci_setup_msix(xhci); | 439 | ret = xhci_setup_msix(xhci); |
434 | if (ret) | 440 | if (ret) |
435 | /* fall back to msi*/ | 441 | /* fall back to msi*/ |
436 | ret = xhci_setup_msi(xhci); | 442 | ret = xhci_setup_msi(xhci); |
437 | 443 | ||
438 | if (ret) { | 444 | if (ret) { |
445 | legacy_irq: | ||
439 | /* fall back to legacy interrupt*/ | 446 | /* fall back to legacy interrupt*/ |
440 | ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, | 447 | ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, |
441 | hcd->irq_descr, hcd); | 448 | hcd->irq_descr, hcd); |
@@ -1849,8 +1856,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
1849 | 1856 | ||
1850 | /* Free any rings that were dropped, but not changed. */ | 1857 | /* Free any rings that were dropped, but not changed. */ |
1851 | for (i = 1; i < 31; ++i) { | 1858 | for (i = 1; i < 31; ++i) { |
1852 | if ((ctrl_ctx->drop_flags & (1 << (i + 1))) && | 1859 | if ((le32_to_cpu(ctrl_ctx->drop_flags) & (1 << (i + 1))) && |
1853 | !(ctrl_ctx->add_flags & (1 << (i + 1)))) | 1860 | !(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1)))) |
1854 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); | 1861 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); |
1855 | } | 1862 | } |
1856 | xhci_zero_in_ctx(xhci, virt_dev); | 1863 | xhci_zero_in_ctx(xhci, virt_dev); |
@@ -2467,6 +2474,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
2467 | struct xhci_command *reset_device_cmd; | 2474 | struct xhci_command *reset_device_cmd; |
2468 | int timeleft; | 2475 | int timeleft; |
2469 | int last_freed_endpoint; | 2476 | int last_freed_endpoint; |
2477 | struct xhci_slot_ctx *slot_ctx; | ||
2470 | 2478 | ||
2471 | ret = xhci_check_args(hcd, udev, NULL, 0, false, __func__); | 2479 | ret = xhci_check_args(hcd, udev, NULL, 0, false, __func__); |
2472 | if (ret <= 0) | 2480 | if (ret <= 0) |
@@ -2499,6 +2507,12 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
2499 | return -EINVAL; | 2507 | return -EINVAL; |
2500 | } | 2508 | } |
2501 | 2509 | ||
2510 | /* If device is not setup, there is no point in resetting it */ | ||
2511 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); | ||
2512 | if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) == | ||
2513 | SLOT_STATE_DISABLED) | ||
2514 | return 0; | ||
2515 | |||
2502 | xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); | 2516 | xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); |
2503 | /* Allocate the command structure that holds the struct completion. | 2517 | /* Allocate the command structure that holds the struct completion. |
2504 | * Assume we're in process context, since the normal device reset | 2518 | * Assume we're in process context, since the normal device reset |