summaryrefslogtreecommitdiff
path: root/drivers/usb/host/xhci-ring.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2010-04-03 02:34:16 +0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-21 00:21:38 +0400
commit8df75f42f8e67e2851cdcf6da91640fb881defd1 (patch)
tree8af91f0a691d1b76f0298480e84fb77c394c24dc /drivers/usb/host/xhci-ring.c
parent94af1220985c71cd80d6c161b7a42c51ef08b923 (diff)
downloadlinux-8df75f42f8e67e2851cdcf6da91640fb881defd1.tar.xz
USB: xhci: Add memory allocation for USB3 bulk streams.
Add support for allocating streams for USB 3.0 bulk endpoints. See Documentation/usb/bulk-streams.txt for more information about how and why you would use streams. When an endpoint has streams enabled, instead of having one ring where all transfers are enqueued to the hardware, it has several rings. The ring dequeue pointer in the endpoint context is changed to point to a "Stream Context Array". This is basically an array of pointers to transfer rings, one for each stream ID that the driver wants to use. The Stream Context Array size must be a power of two, and host controllers can place a limit on the size of the array (4 to 2^16 entries). These two facts make calculating the size of the Stream Context Array and the number of entries actually used by the driver a bit tricky. Besides the Stream Context Array and rings for all the stream IDs, we need one more data structure. The xHCI hardware will not tell us which stream ID a transfer event was for, but it will give us the slot ID, endpoint index, and physical address for the TRB that caused the event. For every endpoint on a device, add a radix tree to map physical TRB addresses to virtual segments within a stream ring. Keep track of whether an endpoint is transitioning to using streams, and don't enqueue any URBs while that's taking place. Refuse to transition an endpoint to streams if there are already URBs enqueued for that endpoint. We need to make sure that freeing streams does not fail, since a driver's disconnect() function may attempt to do this, and it cannot fail. Pre-allocate the command structure used to issue the Configure Endpoint command, and reserve space on the command ring for each stream endpoint. This may be a bit overkill, but it is permissible for the driver to allocate all streams in one call and free them in multiple calls. (It is not advised, however, since it is a waste of resources and time.) Even with the memory and ring room pre-allocated, freeing streams can still fail because the xHC rejects the configure endpoint command. It is valid (by the xHCI 0.96 spec) to return a "Bandwidth Error" or a "Resource Error" for a configure endpoint command. We should never see a Bandwidth Error, since bulk endpoints do not effect the reserved bandwidth. The host controller can still return a Resource Error, but it's improbable since the xHC would be going from a more resource-intensive configuration (streams) to a less resource-intensive configuration (no streams). If the xHC returns a Resource Error, the endpoint will be stuck with streams and will be unusable for drivers. It's an unavoidable consequence of broken host controller hardware. Includes bug fixes from the original patch, contributed by John Youn <John.Youn@synopsys.com> and Andy Green <AGreen@PLXTech.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r--drivers/usb/host/xhci-ring.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index c1359ed310b5..a14f657e279b 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -323,6 +323,10 @@ static void ring_ep_doorbell(struct xhci_hcd *xhci,
ep_state = ep->ep_state;
/* Don't ring the doorbell for this endpoint if there are pending
* cancellations because the we don't want to interrupt processing.
+ * We don't want to restart any stream rings if there's a set dequeue
+ * pointer command pending because the device can choose to start any
+ * stream once the endpoint is on the HW schedule.
+ * FIXME - check all the stream rings for pending cancellations.
*/
if (!(ep_state & EP_HALT_PENDING) && !(ep_state & SET_DEQ_PENDING)
&& !(ep_state & EP_HALTED)) {
@@ -916,8 +920,9 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
* Configure endpoint commands can come from the USB core
* configuration or alt setting changes, or because the HW
* needed an extra configure endpoint command after a reset
- * endpoint command. In the latter case, the xHCI driver is
- * not waiting on the configure endpoint command.
+ * endpoint command or streams were being configured.
+ * If the command was for a halted endpoint, the xHCI driver
+ * is not waiting on the configure endpoint command.
*/
ctrl_ctx = xhci_get_input_control_ctx(xhci,
virt_dev->in_ctx);