Commit 124c3937 authored by Mathias Nyman's avatar Mathias Nyman Committed by Greg Kroah-Hartman

xhci: use boolean to indicate last trb in td remainder calculation

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: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5a83f04a
...@@ -3092,7 +3092,7 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -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, static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred,
int trb_buff_len, unsigned int td_total_len, 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; u32 maxp, total_packet_count;
...@@ -3101,7 +3101,7 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred, ...@@ -3101,7 +3101,7 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred,
return ((td_total_len - transferred) >> 10); return ((td_total_len - transferred) >> 10);
/* One TRB with a zero-length data packet. */ /* 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) trb_buff_len == td_total_len)
return 0; return 0;
...@@ -3216,7 +3216,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3216,7 +3216,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
field |= TRB_CHAIN; field |= TRB_CHAIN;
} else { } else {
field |= TRB_IOC; field |= TRB_IOC;
more_trbs_coming = need_zero_pkt; more_trbs_coming = false;
td->last_trb = ring->enqueue; td->last_trb = ring->enqueue;
} }
...@@ -3227,13 +3227,12 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -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. */ /* Set the TRB length, TD size, and interrupter fields. */
remainder = xhci_td_remainder(xhci, running_total, remainder = xhci_td_remainder(xhci, running_total,
trb_buff_len, full_len, trb_buff_len, full_len,
urb, num_trbs - i - 1); urb, more_trbs_coming);
length_field = TRB_LEN(trb_buff_len) | length_field = TRB_LEN(trb_buff_len) |
TRB_TD_SIZE(remainder) | TRB_TD_SIZE(remainder) |
TRB_INTR_TARGET(0); 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), lower_32_bits(addr),
upper_32_bits(addr), upper_32_bits(addr),
length_field, length_field,
...@@ -3657,7 +3656,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -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. */ /* Set the TRB length, TD size, & interrupter fields. */
remainder = xhci_td_remainder(xhci, running_total, remainder = xhci_td_remainder(xhci, running_total,
trb_buff_len, td_len, trb_buff_len, td_len,
urb, trbs_per_td - j - 1); urb, more_trbs_coming);
length_field = TRB_LEN(trb_buff_len) | length_field = TRB_LEN(trb_buff_len) |
TRB_INTR_TARGET(0); TRB_INTR_TARGET(0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment