diff options
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 27 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 1 |
2 files changed, 27 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 27d690d889af..cc5963263a65 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -3123,6 +3123,27 @@ static int count_isoc_trbs_needed(struct xhci_hcd *xhci, | |||
3123 | return num_trbs; | 3123 | return num_trbs; |
3124 | } | 3124 | } |
3125 | 3125 | ||
3126 | /* | ||
3127 | * The transfer burst count field of the isochronous TRB defines the number of | ||
3128 | * bursts that are required to move all packets in this TD. Only SuperSpeed | ||
3129 | * devices can burst up to bMaxBurst number of packets per service interval. | ||
3130 | * This field is zero based, meaning a value of zero in the field means one | ||
3131 | * burst. Basically, for everything but SuperSpeed devices, this field will be | ||
3132 | * zero. Only xHCI 1.0 host controllers support this field. | ||
3133 | */ | ||
3134 | static unsigned int xhci_get_burst_count(struct xhci_hcd *xhci, | ||
3135 | struct usb_device *udev, | ||
3136 | struct urb *urb, unsigned int total_packet_count) | ||
3137 | { | ||
3138 | unsigned int max_burst; | ||
3139 | |||
3140 | if (xhci->hci_version < 0x100 || udev->speed != USB_SPEED_SUPER) | ||
3141 | return 0; | ||
3142 | |||
3143 | max_burst = urb->ep->ss_ep_comp.bMaxBurst; | ||
3144 | return roundup(total_packet_count, max_burst + 1) - 1; | ||
3145 | } | ||
3146 | |||
3126 | /* This is for isoc transfer */ | 3147 | /* This is for isoc transfer */ |
3127 | static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | 3148 | static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, |
3128 | struct urb *urb, int slot_id, unsigned int ep_index) | 3149 | struct urb *urb, int slot_id, unsigned int ep_index) |
@@ -3164,14 +3185,18 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
3164 | /* Queue the first TRB, even if it's zero-length */ | 3185 | /* Queue the first TRB, even if it's zero-length */ |
3165 | for (i = 0; i < num_tds; i++) { | 3186 | for (i = 0; i < num_tds; i++) { |
3166 | unsigned int total_packet_count; | 3187 | unsigned int total_packet_count; |
3188 | unsigned int burst_count; | ||
3167 | 3189 | ||
3168 | first_trb = true; | 3190 | first_trb = true; |
3169 | running_total = 0; | 3191 | running_total = 0; |
3170 | addr = start_addr + urb->iso_frame_desc[i].offset; | 3192 | addr = start_addr + urb->iso_frame_desc[i].offset; |
3171 | td_len = urb->iso_frame_desc[i].length; | 3193 | td_len = urb->iso_frame_desc[i].length; |
3172 | td_remain_len = td_len; | 3194 | td_remain_len = td_len; |
3195 | /* FIXME: Ignoring zero-length packets, can those happen? */ | ||
3173 | total_packet_count = roundup(td_len, | 3196 | total_packet_count = roundup(td_len, |
3174 | le16_to_cpu(urb->ep->desc.wMaxPacketSize)); | 3197 | le16_to_cpu(urb->ep->desc.wMaxPacketSize)); |
3198 | burst_count = xhci_get_burst_count(xhci, urb->dev, urb, | ||
3199 | total_packet_count); | ||
3175 | 3200 | ||
3176 | trbs_per_td = count_isoc_trbs_needed(xhci, urb, i); | 3201 | trbs_per_td = count_isoc_trbs_needed(xhci, urb, i); |
3177 | 3202 | ||
@@ -3185,7 +3210,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
3185 | 3210 | ||
3186 | for (j = 0; j < trbs_per_td; j++) { | 3211 | for (j = 0; j < trbs_per_td; j++) { |
3187 | u32 remainder = 0; | 3212 | u32 remainder = 0; |
3188 | field = 0; | 3213 | field = TRB_TBC(burst_count); |
3189 | 3214 | ||
3190 | if (first_trb) { | 3215 | if (first_trb) { |
3191 | /* Queue the isoc TRB */ | 3216 | /* Queue the isoc TRB */ |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 85e779808189..87ec3b079728 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -943,6 +943,7 @@ struct xhci_event_cmd { | |||
943 | /* Interrupter Target - which MSI-X vector to target the completion event at */ | 943 | /* Interrupter Target - which MSI-X vector to target the completion event at */ |
944 | #define TRB_INTR_TARGET(p) (((p) & 0x3ff) << 22) | 944 | #define TRB_INTR_TARGET(p) (((p) & 0x3ff) << 22) |
945 | #define GET_INTR_TARGET(p) (((p) >> 22) & 0x3ff) | 945 | #define GET_INTR_TARGET(p) (((p) >> 22) & 0x3ff) |
946 | #define TRB_TBC(p) (((p) & 0x3) << 7) | ||
946 | 947 | ||
947 | /* Cycle bit - indicates TRB ownership by HC or HCD */ | 948 | /* Cycle bit - indicates TRB ownership by HC or HCD */ |
948 | #define TRB_CYCLE (1<<0) | 949 | #define TRB_CYCLE (1<<0) |