diff options
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r-- | drivers/usb/host/xhci.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 924a6ccdb622..8fe4e124ddd4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -390,6 +390,10 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd) | |||
390 | } | 390 | } |
391 | 391 | ||
392 | legacy_irq: | 392 | legacy_irq: |
393 | if (!strlen(hcd->irq_descr)) | ||
394 | snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", | ||
395 | hcd->driver->description, hcd->self.busnum); | ||
396 | |||
393 | /* fall back to legacy interrupt*/ | 397 | /* fall back to legacy interrupt*/ |
394 | ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, | 398 | ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, |
395 | hcd->irq_descr, hcd); | 399 | hcd->irq_descr, hcd); |
@@ -2678,6 +2682,20 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
2678 | return ret; | 2682 | return ret; |
2679 | } | 2683 | } |
2680 | 2684 | ||
2685 | static void xhci_check_bw_drop_ep_streams(struct xhci_hcd *xhci, | ||
2686 | struct xhci_virt_device *vdev, int i) | ||
2687 | { | ||
2688 | struct xhci_virt_ep *ep = &vdev->eps[i]; | ||
2689 | |||
2690 | if (ep->ep_state & EP_HAS_STREAMS) { | ||
2691 | xhci_warn(xhci, "WARN: endpoint 0x%02x has streams on set_interface, freeing streams.\n", | ||
2692 | xhci_get_endpoint_address(i)); | ||
2693 | xhci_free_stream_info(xhci, ep->stream_info); | ||
2694 | ep->stream_info = NULL; | ||
2695 | ep->ep_state &= ~EP_HAS_STREAMS; | ||
2696 | } | ||
2697 | } | ||
2698 | |||
2681 | /* Called after one or more calls to xhci_add_endpoint() or | 2699 | /* Called after one or more calls to xhci_add_endpoint() or |
2682 | * xhci_drop_endpoint(). If this call fails, the USB core is expected | 2700 | * xhci_drop_endpoint(). If this call fails, the USB core is expected |
2683 | * to call xhci_reset_bandwidth(). | 2701 | * to call xhci_reset_bandwidth(). |
@@ -2742,8 +2760,10 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
2742 | /* Free any rings that were dropped, but not changed. */ | 2760 | /* Free any rings that were dropped, but not changed. */ |
2743 | for (i = 1; i < 31; ++i) { | 2761 | for (i = 1; i < 31; ++i) { |
2744 | if ((le32_to_cpu(ctrl_ctx->drop_flags) & (1 << (i + 1))) && | 2762 | if ((le32_to_cpu(ctrl_ctx->drop_flags) & (1 << (i + 1))) && |
2745 | !(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1)))) | 2763 | !(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1)))) { |
2746 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); | 2764 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); |
2765 | xhci_check_bw_drop_ep_streams(xhci, virt_dev, i); | ||
2766 | } | ||
2747 | } | 2767 | } |
2748 | xhci_zero_in_ctx(xhci, virt_dev); | 2768 | xhci_zero_in_ctx(xhci, virt_dev); |
2749 | /* | 2769 | /* |
@@ -2759,6 +2779,7 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
2759 | if (virt_dev->eps[i].ring) { | 2779 | if (virt_dev->eps[i].ring) { |
2760 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); | 2780 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); |
2761 | } | 2781 | } |
2782 | xhci_check_bw_drop_ep_streams(xhci, virt_dev, i); | ||
2762 | virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; | 2783 | virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; |
2763 | virt_dev->eps[i].new_ring = NULL; | 2784 | virt_dev->eps[i].new_ring = NULL; |
2764 | } | 2785 | } |
@@ -2954,7 +2975,7 @@ static int xhci_check_streams_endpoint(struct xhci_hcd *xhci, | |||
2954 | ret = xhci_check_args(xhci_to_hcd(xhci), udev, ep, 1, true, __func__); | 2975 | ret = xhci_check_args(xhci_to_hcd(xhci), udev, ep, 1, true, __func__); |
2955 | if (ret <= 0) | 2976 | if (ret <= 0) |
2956 | return -EINVAL; | 2977 | return -EINVAL; |
2957 | if (ep->ss_ep_comp.bmAttributes == 0) { | 2978 | if (usb_ss_max_streams(&ep->ss_ep_comp) == 0) { |
2958 | xhci_warn(xhci, "WARN: SuperSpeed Endpoint Companion" | 2979 | xhci_warn(xhci, "WARN: SuperSpeed Endpoint Companion" |
2959 | " descriptor for ep 0x%x does not support streams\n", | 2980 | " descriptor for ep 0x%x does not support streams\n", |
2960 | ep->desc.bEndpointAddress); | 2981 | ep->desc.bEndpointAddress); |
@@ -3121,6 +3142,12 @@ int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, | |||
3121 | xhci_dbg(xhci, "Driver wants %u stream IDs (including stream 0).\n", | 3142 | xhci_dbg(xhci, "Driver wants %u stream IDs (including stream 0).\n", |
3122 | num_streams); | 3143 | num_streams); |
3123 | 3144 | ||
3145 | /* MaxPSASize value 0 (2 streams) means streams are not supported */ | ||
3146 | if (HCC_MAX_PSA(xhci->hcc_params) < 4) { | ||
3147 | xhci_dbg(xhci, "xHCI controller does not support streams.\n"); | ||
3148 | return -ENOSYS; | ||
3149 | } | ||
3150 | |||
3124 | config_cmd = xhci_alloc_command(xhci, true, true, mem_flags); | 3151 | config_cmd = xhci_alloc_command(xhci, true, true, mem_flags); |
3125 | if (!config_cmd) { | 3152 | if (!config_cmd) { |
3126 | xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); | 3153 | xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); |
@@ -3519,6 +3546,8 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3519 | struct xhci_virt_ep *ep = &virt_dev->eps[i]; | 3546 | struct xhci_virt_ep *ep = &virt_dev->eps[i]; |
3520 | 3547 | ||
3521 | if (ep->ep_state & EP_HAS_STREAMS) { | 3548 | if (ep->ep_state & EP_HAS_STREAMS) { |
3549 | xhci_warn(xhci, "WARN: endpoint 0x%02x has streams on device reset, freeing streams.\n", | ||
3550 | xhci_get_endpoint_address(i)); | ||
3522 | xhci_free_stream_info(xhci, ep->stream_info); | 3551 | xhci_free_stream_info(xhci, ep->stream_info); |
3523 | ep->stream_info = NULL; | 3552 | ep->stream_info = NULL; |
3524 | ep->ep_state &= ~EP_HAS_STREAMS; | 3553 | ep->ep_state &= ~EP_HAS_STREAMS; |