diff options
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
| -rw-r--r-- | drivers/usb/host/xhci-ring.c | 11 | 
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 23b4aefd103..8275645889d 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -885,6 +885,17 @@ static void update_ring_for_set_deq_completion(struct xhci_hcd *xhci,  	num_trbs_free_temp = ep_ring->num_trbs_free;  	dequeue_temp = ep_ring->dequeue; +	/* If we get two back-to-back stalls, and the first stalled transfer +	 * ends just before a link TRB, the dequeue pointer will be left on +	 * the link TRB by the code in the while loop.  So we have to update +	 * the dequeue pointer one segment further, or we'll jump off +	 * the segment into la-la-land. +	 */ +	if (last_trb(xhci, ep_ring, ep_ring->deq_seg, ep_ring->dequeue)) { +		ep_ring->deq_seg = ep_ring->deq_seg->next; +		ep_ring->dequeue = ep_ring->deq_seg->trbs; +	} +  	while (ep_ring->dequeue != dev->eps[ep_index].queued_deq_ptr) {  		/* We have more usable TRBs */  		ep_ring->num_trbs_free++;  |