Skip to content

Commit

Permalink
xhci: use boolean to indicate last trb in td remainder calculation
Browse files Browse the repository at this point in the history
We only need to know if we are queuing the last trb for a TD when
calculating the td remainder field.
The total number of trbs left is not used.

We won't be able to trust the pre-calculated number of trbs used if we
need to align trb data by splitting or merging trbs in order to satisfy
comply with data alignment requirements in xhci specs section 4.11.7.1.

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Mathias Nyman authored and Greg Kroah-Hartman committed Jun 26, 2016
1 parent 5a83f04 commit 124c393
Showing 1 changed file with 6 additions and 7 deletions.
13 changes: 6 additions & 7 deletions drivers/usb/host/xhci-ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -3092,7 +3092,7 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
*/
static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred,
int trb_buff_len, unsigned int td_total_len,
struct urb *urb, unsigned int num_trbs_left)
struct urb *urb, bool more_trbs_coming)
{
u32 maxp, total_packet_count;

Expand All @@ -3101,7 +3101,7 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred,
return ((td_total_len - transferred) >> 10);

/* One TRB with a zero-length data packet. */
if (num_trbs_left == 0 || (transferred == 0 && trb_buff_len == 0) ||
if (!more_trbs_coming || (transferred == 0 && trb_buff_len == 0) ||
trb_buff_len == td_total_len)
return 0;

Expand Down Expand Up @@ -3216,7 +3216,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
field |= TRB_CHAIN;
} else {
field |= TRB_IOC;
more_trbs_coming = need_zero_pkt;
more_trbs_coming = false;
td->last_trb = ring->enqueue;
}

Expand All @@ -3227,13 +3227,12 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
/* Set the TRB length, TD size, and interrupter fields. */
remainder = xhci_td_remainder(xhci, running_total,
trb_buff_len, full_len,
urb, num_trbs - i - 1);

urb, more_trbs_coming);
length_field = TRB_LEN(trb_buff_len) |
TRB_TD_SIZE(remainder) |
TRB_INTR_TARGET(0);

queue_trb(xhci, ring, more_trbs_coming,
queue_trb(xhci, ring, more_trbs_coming | need_zero_pkt,
lower_32_bits(addr),
upper_32_bits(addr),
length_field,
Expand Down Expand Up @@ -3657,7 +3656,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
/* Set the TRB length, TD size, & interrupter fields. */
remainder = xhci_td_remainder(xhci, running_total,
trb_buff_len, td_len,
urb, trbs_per_td - j - 1);
urb, more_trbs_coming);

length_field = TRB_LEN(trb_buff_len) |
TRB_INTR_TARGET(0);
Expand Down

0 comments on commit 124c393

Please sign in to comment.