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.patch | 47 |
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); + } + |
