On Mon, Aug 02, 2010 at 05:56:24PM +0800, Andiry Xu wrote: > >From dd491aae154bdb3805ad823a5776799aaafb7cda Mon Sep 17 00:00:00 2001 > From: Andiry Xu <andiry.xu@xxxxxxx> > Date: Mon, 2 Aug 2010 17:35:00 +0800 > Subject: [PATCH] xHCI: update ring dequeue pointer when process missed tds > > This patch fixes a isoc transfer bug reported by Sander Eikelenboom. > When ep->skip is set, endpoint ring dequeue pointer should be updated > when processed every missed td. Although ring dequeue pointer will also > be updated when ep->skip is clear, leave it intact during missed tds > processing may cause two issues: > > 1). If the very next valid transfer following missed tds is a short > transfer, its actual_length will be miscalculated; > 2). If there are too many missed tds during transfer, new inserted tds > may found the transfer ring full and urb enqueue fails. > > Reported-by: Sander Eikelenboom <linux@xxxxxxxxxxxxxx> > Tested-by: Sander Eikelenboom <linux@xxxxxxxxxxxxxx> > Signed-off-by: Andiry Xu <andiry.xu@xxxxxxx> Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx> Thanks for tracking this down, Andiry. :) > --- > drivers/usb/host/xhci-ring.c | 4 ++++ > 1 files changed, 4 insertions(+), 0 deletions(-) > > diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c > index da3519e..f27c599 100644 > --- a/drivers/usb/host/xhci-ring.c > +++ b/drivers/usb/host/xhci-ring.c > @@ -1535,6 +1535,10 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, > /* calc actual length */ > if (ep->skip) { > td->urb->iso_frame_desc[idx].actual_length = 0; > + /* Update ring dequeue pointer */ > + while (ep_ring->dequeue != td->last_trb) > + inc_deq(xhci, ep_ring, false); > + inc_deq(xhci, ep_ring, false); > return finish_td(xhci, td, event_trb, event, ep, status, true); > } > > -- > 1.7.0.4 > > > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html