aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
-rw-r--r--drivers/usb/host/xhci-mem.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index d299ffad806b..5711048708d7 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -353,8 +353,19 @@ struct xhci_stream_ctx *xhci_alloc_stream_ctx(struct xhci_hcd *xhci,
353 mem_flags, dma); 353 mem_flags, dma);
354} 354}
355 355
356struct xhci_ring *xhci_dma_to_transfer_ring(
357 struct xhci_virt_ep *ep,
358 u64 address)
359{
360 if (ep->ep_state & EP_HAS_STREAMS)
361 return radix_tree_lookup(&ep->stream_info->trb_address_map,
362 address >> SEGMENT_SHIFT);
363 return ep->ring;
364}
365
366/* Only use this when you know stream_info is valid */
356#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING 367#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
357struct xhci_ring *dma_to_stream_ring( 368static struct xhci_ring *dma_to_stream_ring(
358 struct xhci_stream_info *stream_info, 369 struct xhci_stream_info *stream_info,
359 u64 address) 370 u64 address)
360{ 371{
@@ -363,6 +374,66 @@ struct xhci_ring *dma_to_stream_ring(
363} 374}
364#endif /* CONFIG_USB_XHCI_HCD_DEBUGGING */ 375#endif /* CONFIG_USB_XHCI_HCD_DEBUGGING */
365 376
377struct xhci_ring *xhci_stream_id_to_ring(
378 struct xhci_virt_device *dev,
379 unsigned int ep_index,
380 unsigned int stream_id)
381{
382 struct xhci_virt_ep *ep = &dev->eps[ep_index];
383
384 if (stream_id == 0)
385 return ep->ring;
386 if (!ep->stream_info)
387 return NULL;
388
389 if (stream_id > ep->stream_info->num_streams)
390 return NULL;
391 return ep->stream_info->stream_rings[stream_id];
392}
393
394struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci,
395 unsigned int slot_id, unsigned int ep_index,
396 unsigned int stream_id)
397{
398 struct xhci_virt_ep *ep;
399
400 ep = &xhci->devs[slot_id]->eps[ep_index];
401 /* Common case: no streams */
402 if (!(ep->ep_state & EP_HAS_STREAMS))
403 return ep->ring;
404
405 if (stream_id == 0) {
406 xhci_warn(xhci,
407 "WARN: Slot ID %u, ep index %u has streams, "
408 "but URB has no stream ID.\n",
409 slot_id, ep_index);
410 return NULL;
411 }
412
413 if (stream_id < ep->stream_info->num_streams)
414 return ep->stream_info->stream_rings[stream_id];
415
416 xhci_warn(xhci,
417 "WARN: Slot ID %u, ep index %u has "
418 "stream IDs 1 to %u allocated, "
419 "but stream ID %u is requested.\n",
420 slot_id, ep_index,
421 ep->stream_info->num_streams - 1,
422 stream_id);
423 return NULL;
424}
425
426/* Get the right ring for the given URB.
427 * If the endpoint supports streams, boundary check the URB's stream ID.
428 * If the endpoint doesn't support streams, return the singular endpoint ring.
429 */
430struct xhci_ring *xhci_urb_to_transfer_ring(struct xhci_hcd *xhci,
431 struct urb *urb)
432{
433 return xhci_triad_to_transfer_ring(xhci, urb->dev->slot_id,
434 xhci_get_endpoint_index(&urb->ep->desc), urb->stream_id);
435}
436
366#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING 437#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
367static int xhci_test_radix_tree(struct xhci_hcd *xhci, 438static int xhci_test_radix_tree(struct xhci_hcd *xhci,
368 unsigned int num_streams, 439 unsigned int num_streams,
@@ -515,6 +586,7 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci,
515 cur_ring = stream_info->stream_rings[cur_stream]; 586 cur_ring = stream_info->stream_rings[cur_stream];
516 if (!cur_ring) 587 if (!cur_ring)
517 goto cleanup_rings; 588 goto cleanup_rings;
589 cur_ring->stream_id = cur_stream;
518 /* Set deq ptr, cycle bit, and stream context type */ 590 /* Set deq ptr, cycle bit, and stream context type */
519 addr = cur_ring->first_seg->dma | 591 addr = cur_ring->first_seg->dma |
520 SCT_FOR_CTX(SCT_PRI_TR) | 592 SCT_FOR_CTX(SCT_PRI_TR) |