diff options
Diffstat (limited to 'recipes/kexecboot/linux-kexecboot-2.6.29/musb/0008-usb-musb_host-minor-enqueue-locking-fix-v2.patch')
-rw-r--r-- | recipes/kexecboot/linux-kexecboot-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/recipes/kexecboot/linux-kexecboot-2.6.29/musb/0008-usb-musb_host-minor-enqueue-locking-fix-v2.patch b/recipes/kexecboot/linux-kexecboot-2.6.29/musb/0008-usb-musb_host-minor-enqueue-locking-fix-v2.patch new file mode 100644 index 0000000000..8627825b5a --- /dev/null +++ b/recipes/kexecboot/linux-kexecboot-2.6.29/musb/0008-usb-musb_host-minor-enqueue-locking-fix-v2.patch @@ -0,0 +1,60 @@ +From c3b527a21104b6bb61558fba6c65aa80f63e0772 Mon Sep 17 00:00:00 2001 +From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> +Date: Thu, 26 Mar 2009 17:36:57 -0700 +Subject: [PATCH] usb: musb_host, minor enqueue locking fix (v2) + +Someone noted that the enqueue path used an unlocked access +for usb_host_endpoint->hcpriv ... fix that, by being safe +and always accessing it under spinlock protection. + +Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> +--- + drivers/usb/musb/musb_host.c | 17 ++++++++--------- + 1 files changed, 8 insertions(+), 9 deletions(-) + +diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c +index 499c431..ff09595 100644 +--- a/drivers/usb/musb/musb_host.c ++++ b/drivers/usb/musb/musb_host.c +@@ -1841,7 +1841,7 @@ static int musb_urb_enqueue( + unsigned long flags; + struct musb *musb = hcd_to_musb(hcd); + struct usb_host_endpoint *hep = urb->ep; +- struct musb_qh *qh = hep->hcpriv; ++ struct musb_qh *qh; + struct usb_endpoint_descriptor *epd = &hep->desc; + int ret; + unsigned type_reg; +@@ -1853,22 +1853,21 @@ static int musb_urb_enqueue( + + spin_lock_irqsave(&musb->lock, flags); + ret = usb_hcd_link_urb_to_ep(hcd, urb); ++ qh = ret ? NULL : hep->hcpriv; ++ if (qh) ++ urb->hcpriv = qh; + spin_unlock_irqrestore(&musb->lock, flags); +- if (ret) +- return ret; + + /* DMA mapping was already done, if needed, and this urb is on +- * hep->urb_list ... so there's little to do unless hep wasn't +- * yet scheduled onto a live qh. ++ * hep->urb_list now ... so we're done, unless hep wasn't yet ++ * scheduled onto a live qh. + * + * REVISIT best to keep hep->hcpriv valid until the endpoint gets + * disabled, testing for empty qh->ring and avoiding qh setup costs + * except for the first urb queued after a config change. + */ +- if (qh) { +- urb->hcpriv = qh; +- return 0; +- } ++ if (qh || ret) ++ return ret; + + /* Allocate and initialize qh, minimizing the work done each time + * hw_ep gets reprogrammed, or with irqs blocked. Then schedule it. +-- +1.6.0.4 + |