diff options
author | Mathias Nyman <mathias.nyman@linux.intel.com> | 2016-02-12 16:40:18 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-02-14 17:03:23 -0800 |
commit | 2f6d3b653777e68bbccfdcff3de2ea8165934531 (patch) | |
tree | accaa193ee683824bf1d7551eadd80788f1aef98 /drivers/usb/host/xhci-ring.c | |
parent | 09c352ed671c156b7ce30c81a4f4424641859918 (diff) | |
download | linux-2f6d3b653777e68bbccfdcff3de2ea8165934531.tar.bz2 |
xhci: Support extended burst isoc TRB structure used by xhci 1.1 for USB 3.1
The transfer burst count (TBC) field in the Isoc TRB does not fit the new
larger burst count available for USB 3.1 SSP Isoc tranfers.
xhci 1.1 solved this by reusing the TD size field for transfer burst count.
The Mult field was outgrown as well. xhci 1.1 controllers can calculate
Mult itself and is not set if the new layout is used.
xhci 1.1 controllers that support the new Isoc TRB format expose a
Extended TBC Capability (ETC). To take the new format into use the xhci
host controller driver needs to set a Extended TBC Enable (ETE) bit.
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 3b671122106d..7cf66212ceae 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3770,12 +3770,15 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, * Prevent HW from getting the TRBs by keeping the cycle state * inverted in the first TDs isoc TRB. */ - field = TRB_TBC(burst_count) | - TRB_TYPE(TRB_ISOC) | + field = TRB_TYPE(TRB_ISOC) | TRB_TLBPC(last_burst_pkt_count) | sia_frame_id | (i ? ep_ring->cycle_state : !start_cycle); + /* xhci 1.1 with ETE uses TD_Size field for TBC, old is Rsvdz */ + if (!xep->use_extended_tbc) + field |= TRB_TBC(burst_count); + /* fill the rest of the TRB fields, and remaining normal TRBs */ for (j = 0; j < trbs_per_td; j++) { u32 remainder = 0; @@ -3784,7 +3787,6 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, if (!first_trb) field = TRB_TYPE(TRB_NORMAL) | ep_ring->cycle_state; - first_trb = false; /* Only set interrupt on short packet for IN EPs */ if (usb_urb_dir_in(urb)) @@ -3816,9 +3818,15 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, urb, trbs_per_td - j - 1); length_field = TRB_LEN(trb_buff_len) | - TRB_TD_SIZE(remainder) | TRB_INTR_TARGET(0); + /* xhci 1.1 with ETE uses TD Size field for TBC */ + if (first_trb && xep->use_extended_tbc) + length_field |= TRB_TD_SIZE_TBC(burst_count); + else + length_field |= TRB_TD_SIZE(remainder); + first_trb = false; + queue_trb(xhci, ep_ring, more_trbs_coming, lower_32_bits(addr), upper_32_bits(addr), |