diff options
| author | Mauro Carvalho Chehab <[email protected]> | 2014-04-14 12:00:36 -0300 |
|---|---|---|
| committer | Mauro Carvalho Chehab <[email protected]> | 2014-04-14 12:00:36 -0300 |
| commit | 277a163c83d7ba93fba1e8980d29a9f8bfcfba6c (patch) | |
| tree | ccfd357d152292958957b6b8a993892e7a8cc95f /drivers/usb/host/xhci.c | |
| parent | a83b93a7480441a47856dc9104bea970e84cda87 (diff) | |
| parent | c9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (diff) | |
Merge tag 'v3.15-rc1' into patchwork
Linux 3.15-rc1
* tag 'v3.15-rc1': (12180 commits)
Linux 3.15-rc1
mm: Initialize error in shmem_file_aio_read()
cifs: Use min_t() when comparing "size_t" and "unsigned long"
sym53c8xx_2: Set DID_REQUEUE return code when aborting squeue
powerpc: Don't try to set LPCR unless we're in hypervisor mode
futex: update documentation for ordering guarantees
ceph: fix pr_fmt() redefinition
vti: don't allow to add the same tunnel twice
gre: don't allow to add the same tunnel twice
drivers: net: xen-netfront: fix array initialization bug
missing bits of "splice: fix racy pipe->buffers uses"
cifs: fix the race in cifs_writev()
ceph_sync_{,direct_}write: fix an oops on ceph_osdc_new_request() failure
pktgen: be friendly to LLTX devices
r8152: check RTL8152_UNPLUG
net: sun4i-emac: add promiscuous support
net/apne: replace IS_ERR and PTR_ERR with PTR_ERR_OR_ZERO
blackfin: cleanup board files
bf609: clock: drop unused clock bit set/clear functions
Blackfin: bf537: rename "CONFIG_ADT75"
...
Diffstat (limited to 'drivers/usb/host/xhci.c')
| -rw-r--r-- | drivers/usb/host/xhci.c | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 6fe577d46fa2..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) } legacy_irq: + if (!strlen(hcd->irq_descr)) + snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", + hcd->driver->description, hcd->self.busnum); + /* fall back to legacy interrupt*/ ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, hcd->irq_descr, hcd); @@ -2678,6 +2682,20 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, return ret; } +static void xhci_check_bw_drop_ep_streams(struct xhci_hcd *xhci, + struct xhci_virt_device *vdev, int i) +{ + struct xhci_virt_ep *ep = &vdev->eps[i]; + + if (ep->ep_state & EP_HAS_STREAMS) { + xhci_warn(xhci, "WARN: endpoint 0x%02x has streams on set_interface, freeing streams.\n", + xhci_get_endpoint_address(i)); + xhci_free_stream_info(xhci, ep->stream_info); + ep->stream_info = NULL; + ep->ep_state &= ~EP_HAS_STREAMS; + } +} + /* Called after one or more calls to xhci_add_endpoint() or * xhci_drop_endpoint(). If this call fails, the USB core is expected * to call xhci_reset_bandwidth(). @@ -2742,8 +2760,10 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) /* Free any rings that were dropped, but not changed. */ for (i = 1; i < 31; ++i) { if ((le32_to_cpu(ctrl_ctx->drop_flags) & (1 << (i + 1))) && - !(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1)))) + !(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1)))) { xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); + xhci_check_bw_drop_ep_streams(xhci, virt_dev, i); + } } xhci_zero_in_ctx(xhci, virt_dev); /* @@ -2759,6 +2779,7 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) if (virt_dev->eps[i].ring) { xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); } + xhci_check_bw_drop_ep_streams(xhci, virt_dev, i); virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; virt_dev->eps[i].new_ring = NULL; } @@ -2954,7 +2975,7 @@ static int xhci_check_streams_endpoint(struct xhci_hcd *xhci, ret = xhci_check_args(xhci_to_hcd(xhci), udev, ep, 1, true, __func__); if (ret <= 0) return -EINVAL; - if (ep->ss_ep_comp.bmAttributes == 0) { + if (usb_ss_max_streams(&ep->ss_ep_comp) == 0) { xhci_warn(xhci, "WARN: SuperSpeed Endpoint Companion" " descriptor for ep 0x%x does not support streams\n", ep->desc.bEndpointAddress); @@ -3121,6 +3142,12 @@ int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, xhci_dbg(xhci, "Driver wants %u stream IDs (including stream 0).\n", num_streams); + /* MaxPSASize value 0 (2 streams) means streams are not supported */ + if (HCC_MAX_PSA(xhci->hcc_params) < 4) { + xhci_dbg(xhci, "xHCI controller does not support streams.\n"); + return -ENOSYS; + } + config_cmd = xhci_alloc_command(xhci, true, true, mem_flags); if (!config_cmd) { 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) struct xhci_virt_ep *ep = &virt_dev->eps[i]; if (ep->ep_state & EP_HAS_STREAMS) { + xhci_warn(xhci, "WARN: endpoint 0x%02x has streams on device reset, freeing streams.\n", + xhci_get_endpoint_address(i)); xhci_free_stream_info(xhci, ep->stream_info); ep->stream_info = NULL; ep->ep_state &= ~EP_HAS_STREAMS; @@ -4733,6 +4762,9 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) /* Accept arbitrarily long scatter-gather lists */ hcd->self.sg_tablesize = ~0; + /* support to build packet from discontinuous buffers */ + hcd->self.no_sg_constraint = 1; + /* XHCI controllers don't stop the ep queue on short packets :| */ hcd->self.no_stop_on_short = 1; @@ -4757,14 +4789,6 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) /* xHCI private pointer was set in xhci_pci_probe for the second * registered roothub. */ - xhci = hcd_to_xhci(hcd); - /* - * Support arbitrarily aligned sg-list entries on hosts without - * TD fragment rules (which are currently unsupported). - */ - if (xhci->hci_version < 0x100) - hcd->self.no_sg_constraint = 1; - return 0; } @@ -4793,9 +4817,6 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) if (xhci->hci_version > 0x96) xhci->quirks |= XHCI_SPURIOUS_SUCCESS; - if (xhci->hci_version < 0x100) - hcd->self.no_sg_constraint = 1; - /* Make sure the HC is halted. */ retval = xhci_halt(xhci); if (retval) |