aboutsummaryrefslogtreecommitdiffstats
path: root/usb.current/usb-xhci-update-ring-dequeue-pointer-when-process-missed-tds.patch
diff options
Diffstat (limited to 'usb.current/usb-xhci-update-ring-dequeue-pointer-when-process-missed-tds.patch')
-rw-r--r--usb.current/usb-xhci-update-ring-dequeue-pointer-when-process-missed-tds.patch47
1 files changed, 47 insertions, 0 deletions
diff --git a/usb.current/usb-xhci-update-ring-dequeue-pointer-when-process-missed-tds.patch b/usb.current/usb-xhci-update-ring-dequeue-pointer-when-process-missed-tds.patch
new file mode 100644
index 00000000000000..3eb90ecb6ea85b
--- /dev/null
+++ b/usb.current/usb-xhci-update-ring-dequeue-pointer-when-process-missed-tds.patch
@@ -0,0 +1,47 @@
+From linux-usb-owner@vger.kernel.org Thu Aug 19 10:39:27 2010
+Date: Mon, 9 Aug 2010 13:56:15 -0700
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+To: Greg KH <gregkh@suse.de>
+Cc: linux-usb@vger.kernel.org,
+ Sander Eikelenboom <linux@eikelenboom.it>,
+ Andiry Xu <andiry.xu@amd.com>
+Subject: USB: xHCI: update ring dequeue pointer when process missed tds
+Message-ID: <20100809205615.GA2515@xanatos>
+Content-Disposition: inline
+
+From: Andiry Xu <andiry.xu@amd.com>
+
+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@eikelenboom.it>
+Tested-by: Sander Eikelenboom <linux@eikelenboom.it>
+Signed-off-by: Andiry Xu <andiry.xu@amd.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-ring.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1551,6 +1551,10 @@ static int process_isoc_td(struct xhci_h
+ /* 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);
+ }
+