diff options
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index b2d654b7477e..54139a2f06ce 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -2684,6 +2684,10 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len, | |||
2684 | { | 2684 | { |
2685 | int packets_transferred; | 2685 | int packets_transferred; |
2686 | 2686 | ||
2687 | /* One TRB with a zero-length data packet. */ | ||
2688 | if (running_total == 0 && trb_buff_len == 0) | ||
2689 | return 0; | ||
2690 | |||
2687 | /* All the TRB queueing functions don't count the current TRB in | 2691 | /* All the TRB queueing functions don't count the current TRB in |
2688 | * running_total. | 2692 | * running_total. |
2689 | */ | 2693 | */ |
@@ -3125,20 +3129,15 @@ static int count_isoc_trbs_needed(struct xhci_hcd *xhci, | |||
3125 | struct urb *urb, int i) | 3129 | struct urb *urb, int i) |
3126 | { | 3130 | { |
3127 | int num_trbs = 0; | 3131 | int num_trbs = 0; |
3128 | u64 addr, td_len, running_total; | 3132 | u64 addr, td_len; |
3129 | 3133 | ||
3130 | addr = (u64) (urb->transfer_dma + urb->iso_frame_desc[i].offset); | 3134 | addr = (u64) (urb->transfer_dma + urb->iso_frame_desc[i].offset); |
3131 | td_len = urb->iso_frame_desc[i].length; | 3135 | td_len = urb->iso_frame_desc[i].length; |
3132 | 3136 | ||
3133 | running_total = TRB_MAX_BUFF_SIZE - (addr & (TRB_MAX_BUFF_SIZE - 1)); | 3137 | num_trbs = DIV_ROUND_UP(td_len + (addr & (TRB_MAX_BUFF_SIZE - 1)), |
3134 | running_total &= TRB_MAX_BUFF_SIZE - 1; | 3138 | TRB_MAX_BUFF_SIZE); |
3135 | if (running_total != 0) | 3139 | if (num_trbs == 0) |
3136 | num_trbs++; | ||
3137 | |||
3138 | while (running_total < td_len) { | ||
3139 | num_trbs++; | 3140 | num_trbs++; |
3140 | running_total += TRB_MAX_BUFF_SIZE; | ||
3141 | } | ||
3142 | 3141 | ||
3143 | return num_trbs; | 3142 | return num_trbs; |
3144 | } | 3143 | } |
@@ -3250,9 +3249,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
3250 | addr = start_addr + urb->iso_frame_desc[i].offset; | 3249 | addr = start_addr + urb->iso_frame_desc[i].offset; |
3251 | td_len = urb->iso_frame_desc[i].length; | 3250 | td_len = urb->iso_frame_desc[i].length; |
3252 | td_remain_len = td_len; | 3251 | td_remain_len = td_len; |
3253 | /* FIXME: Ignoring zero-length packets, can those happen? */ | ||
3254 | total_packet_count = roundup(td_len, | 3252 | total_packet_count = roundup(td_len, |
3255 | le16_to_cpu(urb->ep->desc.wMaxPacketSize)); | 3253 | le16_to_cpu(urb->ep->desc.wMaxPacketSize)); |
3254 | /* A zero-length transfer still involves at least one packet. */ | ||
3255 | if (total_packet_count == 0) | ||
3256 | total_packet_count++; | ||
3256 | burst_count = xhci_get_burst_count(xhci, urb->dev, urb, | 3257 | burst_count = xhci_get_burst_count(xhci, urb->dev, urb, |
3257 | total_packet_count); | 3258 | total_packet_count); |
3258 | residue = xhci_get_last_burst_packet_count(xhci, | 3259 | residue = xhci_get_last_burst_packet_count(xhci, |