Google
  Web www.spinics.net

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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


From: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>

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

Cc: Marcus Better <marcus@xxxxxxxxx>
Cc: Greg KH <greg@xxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 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-devel@xxxxxxxxxxxxxxxxxxxxx
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

[Home]     [Video for Linux]     [Photo]     [Yosemite Forum]     [Yosemite Photos]    [Video Projectors]     [PDAs]     [Hacking TiVo]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Devices]     [Big List of Linux Books]     [Free Dating]

  Powered by Linux