diff options
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0008-usb-musb_host-minor-enqueue-locking-fix-v2.patch')
-rw-r--r-- | meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0008-usb-musb_host-minor-enqueue-locking-fix-v2.patch | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0008-usb-musb_host-minor-enqueue-locking-fix-v2.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0008-usb-musb_host-minor-enqueue-locking-fix-v2.patch new file mode 100644 index 0000000000..8627825b5a --- /dev/null +++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0008-usb-musb_host-minor-enqueue-locking-fix-v2.patch | |||
@@ -0,0 +1,60 @@ | |||
1 | From c3b527a21104b6bb61558fba6c65aa80f63e0772 Mon Sep 17 00:00:00 2001 | ||
2 | From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> | ||
3 | Date: Thu, 26 Mar 2009 17:36:57 -0700 | ||
4 | Subject: [PATCH] usb: musb_host, minor enqueue locking fix (v2) | ||
5 | |||
6 | Someone noted that the enqueue path used an unlocked access | ||
7 | for usb_host_endpoint->hcpriv ... fix that, by being safe | ||
8 | and always accessing it under spinlock protection. | ||
9 | |||
10 | Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> | ||
11 | --- | ||
12 | drivers/usb/musb/musb_host.c | 17 ++++++++--------- | ||
13 | 1 files changed, 8 insertions(+), 9 deletions(-) | ||
14 | |||
15 | diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c | ||
16 | index 499c431..ff09595 100644 | ||
17 | --- a/drivers/usb/musb/musb_host.c | ||
18 | +++ b/drivers/usb/musb/musb_host.c | ||
19 | @@ -1841,7 +1841,7 @@ static int musb_urb_enqueue( | ||
20 | unsigned long flags; | ||
21 | struct musb *musb = hcd_to_musb(hcd); | ||
22 | struct usb_host_endpoint *hep = urb->ep; | ||
23 | - struct musb_qh *qh = hep->hcpriv; | ||
24 | + struct musb_qh *qh; | ||
25 | struct usb_endpoint_descriptor *epd = &hep->desc; | ||
26 | int ret; | ||
27 | unsigned type_reg; | ||
28 | @@ -1853,22 +1853,21 @@ static int musb_urb_enqueue( | ||
29 | |||
30 | spin_lock_irqsave(&musb->lock, flags); | ||
31 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | ||
32 | + qh = ret ? NULL : hep->hcpriv; | ||
33 | + if (qh) | ||
34 | + urb->hcpriv = qh; | ||
35 | spin_unlock_irqrestore(&musb->lock, flags); | ||
36 | - if (ret) | ||
37 | - return ret; | ||
38 | |||
39 | /* DMA mapping was already done, if needed, and this urb is on | ||
40 | - * hep->urb_list ... so there's little to do unless hep wasn't | ||
41 | - * yet scheduled onto a live qh. | ||
42 | + * hep->urb_list now ... so we're done, unless hep wasn't yet | ||
43 | + * scheduled onto a live qh. | ||
44 | * | ||
45 | * REVISIT best to keep hep->hcpriv valid until the endpoint gets | ||
46 | * disabled, testing for empty qh->ring and avoiding qh setup costs | ||
47 | * except for the first urb queued after a config change. | ||
48 | */ | ||
49 | - if (qh) { | ||
50 | - urb->hcpriv = qh; | ||
51 | - return 0; | ||
52 | - } | ||
53 | + if (qh || ret) | ||
54 | + return ret; | ||
55 | |||
56 | /* Allocate and initialize qh, minimizing the work done each time | ||
57 | * hw_ep gets reprogrammed, or with irqs blocked. Then schedule it. | ||
58 | -- | ||
59 | 1.6.0.4 | ||
60 | |||