]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.8.4/usb-ehci-don-t-check-dma-values-in-qh-overlays.patch
Linux 4.14.95
[thirdparty/kernel/stable-queue.git] / releases / 3.8.4 / usb-ehci-don-t-check-dma-values-in-qh-overlays.patch
CommitLineData
34a069e8
GKH
1From feca7746d5d9e84b105a613b7f3b6ad00d327372 Mon Sep 17 00:00:00 2001
2From: Alan Stern <stern@rowland.harvard.edu>
3Date: Fri, 1 Mar 2013 10:51:15 -0500
4Subject: USB: EHCI: don't check DMA values in QH overlays
5
6From: Alan Stern <stern@rowland.harvard.edu>
7
8commit feca7746d5d9e84b105a613b7f3b6ad00d327372 upstream.
9
10This patch (as1661) fixes a rather obscure bug in ehci-hcd. In a
11couple of places, the driver compares the DMA address stored in a QH's
12overlay region with the address of a particular qTD, in order to see
13whether that qTD is the one currently being processed by the hardware.
14(If it is then the status in the QH's overlay region is more
15up-to-date than the status in the qTD, and if it isn't then the
16overlay's value needs to be adjusted when the QH is added back to the
17active schedule.)
18
19However, DMA address in the overlay region isn't always valid. It
20sometimes will contain a stale value, which may happen by coincidence
21to be equal to a qTD's DMA address. Instead of checking the DMA
22address, we should check whether the overlay region is active and
23valid. The patch tests the ACTIVE bit in the overlay, and clears this
24bit when the overlay becomes invalid (which happens when the
25currently-executing URB is unlinked).
26
27This is the second part of a fix for the regression reported at:
28
29 https://bugs.launchpad.net/bugs/1088733
30
31Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
32Reported-by: Joseph Salisbury <joseph.salisbury@canonical.com>
33Reported-and-tested-by: Stephen Thirlwall <sdt@dr.com>
34Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
35
36---
37 drivers/usb/host/ehci-q.c | 18 +++++++++++++-----
38 1 file changed, 13 insertions(+), 5 deletions(-)
39
40--- a/drivers/usb/host/ehci-q.c
41+++ b/drivers/usb/host/ehci-q.c
42@@ -135,7 +135,7 @@ qh_refresh (struct ehci_hcd *ehci, struc
43 * qtd is updated in qh_completions(). Update the QH
44 * overlay here.
45 */
46- if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) {
47+ if (qh->hw->hw_token & ACTIVE_BIT(ehci)) {
48 qh->hw->hw_qtd_next = qtd->hw_next;
49 qtd = NULL;
50 }
51@@ -449,11 +449,19 @@ qh_completions (struct ehci_hcd *ehci, s
52 else if (last_status == -EINPROGRESS && !urb->unlinked)
53 continue;
54
55- /* qh unlinked; token in overlay may be most current */
56- if (state == QH_STATE_IDLE
57- && cpu_to_hc32(ehci, qtd->qtd_dma)
58- == hw->hw_current) {
59+ /*
60+ * If this was the active qtd when the qh was unlinked
61+ * and the overlay's token is active, then the overlay
62+ * hasn't been written back to the qtd yet so use its
63+ * token instead of the qtd's. After the qtd is
64+ * processed and removed, the overlay won't be valid
65+ * any more.
66+ */
67+ if (state == QH_STATE_IDLE &&
68+ qh->qtd_list.next == &qtd->qtd_list &&
69+ (hw->hw_token & ACTIVE_BIT(ehci))) {
70 token = hc32_to_cpu(ehci, hw->hw_token);
71+ hw->hw_token &= ~ACTIVE_BIT(ehci);
72
73 /* An unlink may leave an incomplete
74 * async transaction in the TT buffer.