[patch 4/8] ohci-hcd.c:ohci_irq() locking fix

[email protected]
Newsgroups gmane.linux.usb.devel
Message-ID <[email protected]>
From: Alan Stern <[email protected]>

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

Cc: Marcus Better <[email protected]>
Cc: Greg KH <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
---

 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
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.