diff options
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
| -rw-r--r-- | drivers/usb/host/xhci-mem.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index c09539bad1e..d64f5724bfc 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
| @@ -582,6 +582,19 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev, | |||
| 582 | return EP_INTERVAL(interval); | 582 | return EP_INTERVAL(interval); |
| 583 | } | 583 | } |
| 584 | 584 | ||
| 585 | /* The "Mult" field in the endpoint context is only set for SuperSpeed devices. | ||
| 586 | * High speed endpoint descriptors can define "the number of additional | ||
| 587 | * transaction opportunities per microframe", but that goes in the Max Burst | ||
| 588 | * endpoint context field. | ||
| 589 | */ | ||
| 590 | static inline u32 xhci_get_endpoint_mult(struct usb_device *udev, | ||
| 591 | struct usb_host_endpoint *ep) | ||
| 592 | { | ||
| 593 | if (udev->speed != USB_SPEED_SUPER || !ep->ss_ep_comp) | ||
| 594 | return 0; | ||
| 595 | return ep->ss_ep_comp->desc.bmAttributes; | ||
| 596 | } | ||
| 597 | |||
| 585 | static inline u32 xhci_get_endpoint_type(struct usb_device *udev, | 598 | static inline u32 xhci_get_endpoint_type(struct usb_device *udev, |
| 586 | struct usb_host_endpoint *ep) | 599 | struct usb_host_endpoint *ep) |
| 587 | { | 600 | { |
| @@ -612,6 +625,36 @@ static inline u32 xhci_get_endpoint_type(struct usb_device *udev, | |||
| 612 | return type; | 625 | return type; |
| 613 | } | 626 | } |
| 614 | 627 | ||
| 628 | /* Return the maximum endpoint service interval time (ESIT) payload. | ||
| 629 | * Basically, this is the maxpacket size, multiplied by the burst size | ||
| 630 | * and mult size. | ||
| 631 | */ | ||
| 632 | static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci, | ||
| 633 | struct usb_device *udev, | ||
| 634 | struct usb_host_endpoint *ep) | ||
| 635 | { | ||
| 636 | int max_burst; | ||
| 637 | int max_packet; | ||
| 638 | |||
| 639 | /* Only applies for interrupt or isochronous endpoints */ | ||
| 640 | if (usb_endpoint_xfer_control(&ep->desc) || | ||
| 641 | usb_endpoint_xfer_bulk(&ep->desc)) | ||
| 642 | return 0; | ||
| 643 | |||
| 644 | if (udev->speed == USB_SPEED_SUPER) { | ||
| 645 | if (ep->ss_ep_comp) | ||
| 646 | return ep->ss_ep_comp->desc.wBytesPerInterval; | ||
| 647 | xhci_warn(xhci, "WARN no SS endpoint companion descriptor.\n"); | ||
| 648 | /* Assume no bursts, no multiple opportunities to send. */ | ||
| 649 | return ep->desc.wMaxPacketSize; | ||
| 650 | } | ||
| 651 | |||
| 652 | max_packet = ep->desc.wMaxPacketSize & 0x3ff; | ||
| 653 | max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11; | ||
| 654 | /* A 0 in max burst means 1 transfer per ESIT */ | ||
| 655 | return max_packet * (max_burst + 1); | ||
| 656 | } | ||
| 657 | |||
| 615 | int xhci_endpoint_init(struct xhci_hcd *xhci, | 658 | int xhci_endpoint_init(struct xhci_hcd *xhci, |
| 616 | struct xhci_virt_device *virt_dev, | 659 | struct xhci_virt_device *virt_dev, |
| 617 | struct usb_device *udev, | 660 | struct usb_device *udev, |
| @@ -623,6 +666,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, | |||
| 623 | struct xhci_ring *ep_ring; | 666 | struct xhci_ring *ep_ring; |
| 624 | unsigned int max_packet; | 667 | unsigned int max_packet; |
| 625 | unsigned int max_burst; | 668 | unsigned int max_burst; |
| 669 | u32 max_esit_payload; | ||
| 626 | 670 | ||
| 627 | ep_index = xhci_get_endpoint_index(&ep->desc); | 671 | ep_index = xhci_get_endpoint_index(&ep->desc); |
| 628 | ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); | 672 | ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); |
| @@ -644,6 +688,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, | |||
| 644 | ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state; | 688 | ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state; |
| 645 | 689 | ||
| 646 | ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep); | 690 | ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep); |
| 691 | ep_ctx->ep_info |= EP_MULT(xhci_get_endpoint_mult(udev, ep)); | ||
| 647 | 692 | ||
| 648 | /* FIXME dig Mult and streams info out of ep companion desc */ | 693 | /* FIXME dig Mult and streams info out of ep companion desc */ |
| 649 | 694 | ||
| @@ -689,6 +734,26 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, | |||
| 689 | default: | 734 | default: |
| 690 | BUG(); | 735 | BUG(); |
| 691 | } | 736 | } |
| 737 | max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep); | ||
| 738 | ep_ctx->tx_info = MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload); | ||
| 739 | |||
| 740 | /* | ||
| 741 | * XXX no idea how to calculate the average TRB buffer length for bulk | ||
| 742 | * endpoints, as the driver gives us no clue how big each scatter gather | ||
| 743 | * list entry (or buffer) is going to be. | ||
| 744 | * | ||
| 745 | * For isochronous and interrupt endpoints, we set it to the max | ||
| 746 | * available, until we have new API in the USB core to allow drivers to | ||
| 747 | * declare how much bandwidth they actually need. | ||
| 748 | * | ||
| 749 | * Normally, it would be calculated by taking the total of the buffer | ||
| 750 | * lengths in the TD and then dividing by the number of TRBs in a TD, | ||
| 751 | * including link TRBs, No-op TRBs, and Event data TRBs. Since we don't | ||
| 752 | * use Event Data TRBs, and we don't chain in a link TRB on short | ||
| 753 | * transfers, we're basically dividing by 1. | ||
| 754 | */ | ||
| 755 | ep_ctx->tx_info |= AVG_TRB_LENGTH_FOR_EP(max_esit_payload); | ||
| 756 | |||
| 692 | /* FIXME Debug endpoint context */ | 757 | /* FIXME Debug endpoint context */ |
| 693 | return 0; | 758 | return 0; |
| 694 | } | 759 | } |
