Discussion:
[patch 4/8] ohci-hcd.c:ohci_irq() locking fix
a***@linux-foundation.org
2007-12-14 00:15:30 UTC
Permalink
From: Alan Stern <***@rowland.harvard.edu>

Taken from http://bugzilla.kernel.org/show_bug.cgi?id=9335, awaiting testing
results.

Cc: Marcus Better <***@better.se>
Cc: Greg KH <***@kroah.com>
Signed-off-by: Andrew Morton <***@linux-foundation.org>
---

drivers/usb/host/ohci-hcd.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)

diff -puN drivers/usb/host/ohci-hcd.c~ohci-hcdcohci_irq-locking-fix drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c~ohci-hcdcohci_irq-locking-fix
+++ a/drivers/usb/host/ohci-hcd.c
@@ -731,6 +731,7 @@ static irqreturn_t ohci_irq (struct usb_
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
struct ohci_regs __iomem *regs = ohci->regs;
int ints;
+ unsigned long flags;

/* we can eliminate a (slow) ohci_readl()
* if _only_ WDH caused this irq
@@ -798,9 +799,9 @@ static irqreturn_t ohci_irq (struct usb_
ohci_writel(ohci, OHCI_INTR_RD, &regs->intrstatus);
hcd->poll_rh = 1;
if (ohci->autostop) {
- spin_lock (&ohci->lock);
+ spin_lock_irqsave(&ohci->lock, flags);
ohci_rh_resume (ohci);
- spin_unlock (&ohci->lock);
+ spin_unlock_irqrestore(&ohci->lock, flags);
} else
usb_hcd_resume_root_hub(hcd);
}
@@ -808,15 +809,15 @@ static irqreturn_t ohci_irq (struct usb_
if (ints & OHCI_INTR_WDH) {
if (HC_IS_RUNNING(hcd->state))
ohci_writel (ohci, OHCI_INTR_WDH, &regs->intrdisable);
- spin_lock (&ohci->lock);
+ spin_lock_irqsave(&ohci->lock, flags);
dl_done_list (ohci);
- spin_unlock (&ohci->lock);
+ spin_unlock_irqrestore(&ohci->lock, flags);
if (HC_IS_RUNNING(hcd->state))
ohci_writel (ohci, OHCI_INTR_WDH, &regs->intrenable);
}

if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) {
- spin_lock(&ohci->lock);
+ spin_lock_irqsave(&ohci->lock, flags);
if (ohci->ed_to_check) {
struct ed *ed = ohci->ed_to_check;

@@ -837,7 +838,7 @@ static irqreturn_t ohci_irq (struct usb_
} else
ohci->ed_to_check = NULL;
}
- spin_unlock(&ohci->lock);
+ spin_unlock_irqrestore(&ohci->lock, flags);
}

/* could track INTR_SO to reduce available PCI/... bandwidth */
@@ -845,7 +846,7 @@ static irqreturn_t ohci_irq (struct usb_
/* handle any pending URB/ED unlinks, leaving INTR_SF enabled
* when there's still unlinking to be done (next frame).
*/
- spin_lock (&ohci->lock);
+ spin_lock_irqsave(&ohci->lock, flags);
if (ohci->ed_rm_list)
finish_unlinks (ohci, ohci_frame_no(ohci));
if ((ints & OHCI_INTR_SF) != 0
@@ -853,7 +854,7 @@ static irqreturn_t ohci_irq (struct usb_
&& !ohci->ed_to_check
&& HC_IS_RUNNING(hcd->state))
ohci_writel (ohci, OHCI_INTR_SF, &regs->intrdisable);
- spin_unlock (&ohci->lock);
+ spin_unlock_irqrestore(&ohci->lock, flags);

if (HC_IS_RUNNING(hcd->state)) {
ohci_writel (ohci, ints, &regs->intrstatus);
_

-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services
for just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
linux-usb-***@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Loading...