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 743cf80debb1..d0a65401670b 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); |
@@ -1848,8 +1855,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
1848 | 1855 | ||
1849 | /* Free any rings that were dropped, but not changed. */ | 1856 | /* Free any rings that were dropped, but not changed. */ |
1850 | for (i = 1; i < 31; ++i) { | 1857 | for (i = 1; i < 31; ++i) { |
1851 | if ((ctrl_ctx->drop_flags & (1 << (i + 1))) && | 1858 | if ((le32_to_cpu(ctrl_ctx->drop_flags) & (1 << (i + 1))) && |
1852 | !(ctrl_ctx->add_flags & (1 << (i + 1)))) | 1859 | !(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1)))) |
1853 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); | 1860 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); |
1854 | } | 1861 | } |
1855 | xhci_zero_in_ctx(xhci, virt_dev); | 1862 | xhci_zero_in_ctx(xhci, virt_dev); |
@@ -2466,6 +2473,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
2466 | struct xhci_command *reset_device_cmd; | 2473 | struct xhci_command *reset_device_cmd; |
2467 | int timeleft; | 2474 | int timeleft; |
2468 | int last_freed_endpoint; | 2475 | int last_freed_endpoint; |
2476 | struct xhci_slot_ctx *slot_ctx; | ||
2469 | 2477 | ||
2470 | ret = xhci_check_args(hcd, udev, NULL, 0, false, __func__); | 2478 | ret = xhci_check_args(hcd, udev, NULL, 0, false, __func__); |
2471 | if (ret <= 0) | 2479 | if (ret <= 0) |
@@ -2498,6 +2506,12 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
2498 | return -EINVAL; | 2506 | return -EINVAL; |
2499 | } | 2507 | } |
2500 | 2508 | ||
2509 | /* If device is not setup, there is no point in resetting it */ | ||
2510 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); | ||
2511 | if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) == | ||
2512 | SLOT_STATE_DISABLED) | ||
2513 | return 0; | ||
2514 | |||
2501 | xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); | 2515 | xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); |
2502 | /* Allocate the command structure that holds the struct completion. | 2516 | /* Allocate the command structure that holds the struct completion. |
2503 | * Assume we're in process context, since the normal device reset | 2517 | * Assume we're in process context, since the normal device reset |