aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci.h
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2010-04-02 18:34:16 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-20 16:21:38 -0400
commit8df75f42f8e67e2851cdcf6da91640fb881defd1 (patch)
tree8af91f0a691d1b76f0298480e84fb77c394c24dc /drivers/usb/host/xhci.h
parent94af1220985c71cd80d6c161b7a42c51ef08b923 (diff)
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.h')
-rw-r--r--drivers/usb/host/xhci.h84
1 files changed, 75 insertions, 9 deletions
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index a7c4e1122902..7a9447cb6ea9 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -117,7 +117,7 @@ struct xhci_cap_regs {
117/* true: no secondary Stream ID Support */ 117/* true: no secondary Stream ID Support */
118#define HCC_NSS(p) ((p) & (1 << 7)) 118#define HCC_NSS(p) ((p) & (1 << 7))
119/* Max size for Primary Stream Arrays - 2^(n+1), where n is bits 12:15 */ 119/* Max size for Primary Stream Arrays - 2^(n+1), where n is bits 12:15 */
120#define HCC_MAX_PSA (1 << ((((p) >> 12) & 0xf) + 1)) 120#define HCC_MAX_PSA(p) (1 << ((((p) >> 12) & 0xf) + 1))
121/* Extended Capabilities pointer from PCI base - section 5.3.6 */ 121/* Extended Capabilities pointer from PCI base - section 5.3.6 */
122#define HCC_EXT_CAPS(p) XHCI_HCC_EXT_CAPS(p) 122#define HCC_EXT_CAPS(p) XHCI_HCC_EXT_CAPS(p)
123 123
@@ -585,6 +585,10 @@ struct xhci_ep_ctx {
585/* Interval - period between requests to an endpoint - 125u increments. */ 585/* Interval - period between requests to an endpoint - 125u increments. */
586#define EP_INTERVAL(p) ((p & 0xff) << 16) 586#define EP_INTERVAL(p) ((p & 0xff) << 16)
587#define EP_INTERVAL_TO_UFRAMES(p) (1 << (((p) >> 16) & 0xff)) 587#define EP_INTERVAL_TO_UFRAMES(p) (1 << (((p) >> 16) & 0xff))
588#define EP_MAXPSTREAMS_MASK (0x1f << 10)
589#define EP_MAXPSTREAMS(p) (((p) << 10) & EP_MAXPSTREAMS_MASK)
590/* Endpoint is set up with a Linear Stream Array (vs. Secondary Stream Array) */
591#define EP_HAS_LSA (1 << 15)
588 592
589/* ep_info2 bitmasks */ 593/* ep_info2 bitmasks */
590/* 594/*
@@ -648,8 +652,50 @@ struct xhci_command {
648/* add context bitmasks */ 652/* add context bitmasks */
649#define ADD_EP(x) (0x1 << x) 653#define ADD_EP(x) (0x1 << x)
650 654
655struct xhci_stream_ctx {
656 /* 64-bit stream ring address, cycle state, and stream type */
657 u64 stream_ring;
658 /* offset 0x14 - 0x1f reserved for HC internal use */
659 u32 reserved[2];
660};
661
662/* Stream Context Types (section 6.4.1) - bits 3:1 of stream ctx deq ptr */
663#define SCT_FOR_CTX(p) (((p) << 1) & 0x7)
664/* Secondary stream array type, dequeue pointer is to a transfer ring */
665#define SCT_SEC_TR 0
666/* Primary stream array type, dequeue pointer is to a transfer ring */
667#define SCT_PRI_TR 1
668/* Dequeue pointer is for a secondary stream array (SSA) with 8 entries */
669#define SCT_SSA_8 2
670#define SCT_SSA_16 3
671#define SCT_SSA_32 4
672#define SCT_SSA_64 5
673#define SCT_SSA_128 6
674#define SCT_SSA_256 7
675
676/* Assume no secondary streams for now */
677struct xhci_stream_info {
678 struct xhci_ring **stream_rings;
679 /* Number of streams, including stream 0 (which drivers can't use) */
680 unsigned int num_streams;
681 /* The stream context array may be bigger than
682 * the number of streams the driver asked for
683 */
684 struct xhci_stream_ctx *stream_ctx_array;
685 unsigned int num_stream_ctxs;
686 dma_addr_t ctx_array_dma;
687 /* For mapping physical TRB addresses to segments in stream rings */
688 struct radix_tree_root trb_address_map;
689 struct xhci_command *free_streams_command;
690};
691
692#define SMALL_STREAM_ARRAY_SIZE 256
693#define MEDIUM_STREAM_ARRAY_SIZE 1024
694
651struct xhci_virt_ep { 695struct xhci_virt_ep {
652 struct xhci_ring *ring; 696 struct xhci_ring *ring;
697 /* Related to endpoints that are configured to use stream IDs only */
698 struct xhci_stream_info *stream_info;
653 /* Temporary storage in case the configure endpoint command fails and we 699 /* Temporary storage in case the configure endpoint command fails and we
654 * have to restore the device state to the previous state 700 * have to restore the device state to the previous state
655 */ 701 */
@@ -658,6 +704,11 @@ struct xhci_virt_ep {
658#define SET_DEQ_PENDING (1 << 0) 704#define SET_DEQ_PENDING (1 << 0)
659#define EP_HALTED (1 << 1) /* For stall handling */ 705#define EP_HALTED (1 << 1) /* For stall handling */
660#define EP_HALT_PENDING (1 << 2) /* For URB cancellation */ 706#define EP_HALT_PENDING (1 << 2) /* For URB cancellation */
707/* Transitioning the endpoint to using streams, don't enqueue URBs */
708#define EP_GETTING_STREAMS (1 << 3)
709#define EP_HAS_STREAMS (1 << 4)
710/* Transitioning the endpoint to not using streams, don't enqueue URBs */
711#define EP_GETTING_NO_STREAMS (1 << 5)
661 /* ---- Related to URB cancellation ---- */ 712 /* ---- Related to URB cancellation ---- */
662 struct list_head cancelled_td_list; 713 struct list_head cancelled_td_list;
663 /* The TRB that was last reported in a stopped endpoint ring */ 714 /* The TRB that was last reported in a stopped endpoint ring */
@@ -710,14 +761,6 @@ struct xhci_device_context_array {
710 */ 761 */
711 762
712 763
713struct xhci_stream_ctx {
714 /* 64-bit stream ring address, cycle state, and stream type */
715 u64 stream_ring;
716 /* offset 0x14 - 0x1f reserved for HC internal use */
717 u32 reserved[2];
718};
719
720
721struct xhci_transfer_event { 764struct xhci_transfer_event {
722 /* 64-bit buffer address, or immediate data */ 765 /* 64-bit buffer address, or immediate data */
723 u64 buffer; 766 u64 buffer;
@@ -952,6 +995,10 @@ union xhci_trb {
952/* Allow two commands + a link TRB, along with any reserved command TRBs */ 995/* Allow two commands + a link TRB, along with any reserved command TRBs */
953#define MAX_RSVD_CMD_TRBS (TRBS_PER_SEGMENT - 3) 996#define MAX_RSVD_CMD_TRBS (TRBS_PER_SEGMENT - 3)
954#define SEGMENT_SIZE (TRBS_PER_SEGMENT*16) 997#define SEGMENT_SIZE (TRBS_PER_SEGMENT*16)
998/* SEGMENT_SHIFT should be log2(SEGMENT_SIZE).
999 * Change this if you change TRBS_PER_SEGMENT!
1000 */
1001#define SEGMENT_SHIFT 10
955/* TRB buffer pointers can't cross 64KB boundaries */ 1002/* TRB buffer pointers can't cross 64KB boundaries */
956#define TRB_MAX_BUFF_SHIFT 16 1003#define TRB_MAX_BUFF_SHIFT 16
957#define TRB_MAX_BUFF_SIZE (1 << TRB_MAX_BUFF_SHIFT) 1004#define TRB_MAX_BUFF_SIZE (1 << TRB_MAX_BUFF_SHIFT)
@@ -1088,6 +1135,8 @@ struct xhci_hcd {
1088 /* DMA pools */ 1135 /* DMA pools */
1089 struct dma_pool *device_pool; 1136 struct dma_pool *device_pool;
1090 struct dma_pool *segment_pool; 1137 struct dma_pool *segment_pool;
1138 struct dma_pool *small_streams_pool;
1139 struct dma_pool *medium_streams_pool;
1091 1140
1092#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING 1141#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
1093 /* Poll the rings - for debugging */ 1142 /* Poll the rings - for debugging */
@@ -1242,6 +1291,17 @@ void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring);
1242void xhci_free_or_cache_endpoint_ring(struct xhci_hcd *xhci, 1291void xhci_free_or_cache_endpoint_ring(struct xhci_hcd *xhci,
1243 struct xhci_virt_device *virt_dev, 1292 struct xhci_virt_device *virt_dev,
1244 unsigned int ep_index); 1293 unsigned int ep_index);
1294struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci,
1295 unsigned int num_stream_ctxs,
1296 unsigned int num_streams, gfp_t flags);
1297void xhci_free_stream_info(struct xhci_hcd *xhci,
1298 struct xhci_stream_info *stream_info);
1299void xhci_setup_streams_ep_input_ctx(struct xhci_hcd *xhci,
1300 struct xhci_ep_ctx *ep_ctx,
1301 struct xhci_stream_info *stream_info);
1302void xhci_setup_no_streams_ep_input_ctx(struct xhci_hcd *xhci,
1303 struct xhci_ep_ctx *ep_ctx,
1304 struct xhci_virt_ep *ep);
1245struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, 1305struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci,
1246 bool allocate_in_ctx, bool allocate_completion, 1306 bool allocate_in_ctx, bool allocate_completion,
1247 gfp_t mem_flags); 1307 gfp_t mem_flags);
@@ -1266,6 +1326,12 @@ int xhci_get_frame(struct usb_hcd *hcd);
1266irqreturn_t xhci_irq(struct usb_hcd *hcd); 1326irqreturn_t xhci_irq(struct usb_hcd *hcd);
1267int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev); 1327int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev);
1268void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev); 1328void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev);
1329int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev,
1330 struct usb_host_endpoint **eps, unsigned int num_eps,
1331 unsigned int num_streams, gfp_t mem_flags);
1332int xhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev,
1333 struct usb_host_endpoint **eps, unsigned int num_eps,
1334 gfp_t mem_flags);
1269int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev); 1335int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev);
1270int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, 1336int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
1271 struct usb_tt *tt, gfp_t mem_flags); 1337 struct usb_tt *tt, gfp_t mem_flags);