]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/2.6.33.2/usb-ehci-fix-itd-list-order.patch
5.0-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 2.6.33.2 / usb-ehci-fix-itd-list-order.patch
1 From 92bc3648e6027384479852b770a542722fadee7c Mon Sep 17 00:00:00 2001
2 From: Clemens Ladisch <clemens@ladisch.de>
3 Date: Mon, 1 Mar 2010 09:12:50 +0100
4 Subject: USB: EHCI: fix ITD list order
5
6 From: Clemens Ladisch <clemens@ladisch.de>
7
8 commit 92bc3648e6027384479852b770a542722fadee7c upstream.
9
10 When isochronous URBs are shorter than one frame and when more than one
11 ITD in a frame has been completed before the interrupt can be handled,
12 scan_periodic() completes the URBs in the order in which they are found
13 in the descriptor list. Therefore, the descriptor list must contain the
14 ITDs in the correct order, i.e., a new ITD must be linked in after any
15 previous ITDs of the same endpoint.
16
17 This should fix garbled capture data in the USB audio drivers.
18
19 Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
20 Reported-by: Colin Fletcher <colin.m.fletcher@googlemail.com>
21 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
22
23 ---
24 drivers/usb/host/ehci-sched.c | 24 +++++++++++++++++++-----
25 1 file changed, 19 insertions(+), 5 deletions(-)
26
27 --- a/drivers/usb/host/ehci-sched.c
28 +++ b/drivers/usb/host/ehci-sched.c
29 @@ -1563,13 +1563,27 @@ itd_patch(
30 static inline void
31 itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd)
32 {
33 - /* always prepend ITD/SITD ... only QH tree is order-sensitive */
34 - itd->itd_next = ehci->pshadow [frame];
35 - itd->hw_next = ehci->periodic [frame];
36 - ehci->pshadow [frame].itd = itd;
37 + union ehci_shadow *prev = &ehci->pshadow[frame];
38 + __hc32 *hw_p = &ehci->periodic[frame];
39 + union ehci_shadow here = *prev;
40 + __hc32 type = 0;
41 +
42 + /* skip any iso nodes which might belong to previous microframes */
43 + while (here.ptr) {
44 + type = Q_NEXT_TYPE(ehci, *hw_p);
45 + if (type == cpu_to_hc32(ehci, Q_TYPE_QH))
46 + break;
47 + prev = periodic_next_shadow(ehci, prev, type);
48 + hw_p = shadow_next_periodic(ehci, &here, type);
49 + here = *prev;
50 + }
51 +
52 + itd->itd_next = here;
53 + itd->hw_next = *hw_p;
54 + prev->itd = itd;
55 itd->frame = frame;
56 wmb ();
57 - ehci->periodic[frame] = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
58 + *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
59 }
60
61 /* fit urb's itds into the selected schedule slot; activate as needed */