Hi, Alan:

Here's one more bug I'd like to discuss.

Kimball Murray from Stratus found this oops, and it's easily reproducible
on his hardware. They have some electronic means to unplug hardware, so
running a test which plugs and unplugs in a loop causes an oops.

Apparently, there's a window when OHCI is shut down, when we shut the
controller down and freed hcca, but did not release the IRQ. On a shared
IRQ, some other device interrupts, and we oops referring to hcca.

The attached patch looks like a ham-fisted way to fix this, but it seems
like the best that can be done. I tried to rearrange the sequence of
calls, but no matter what something did not work. Also I thought about
removing this:

        /* we can eliminate a (slow) ohci_readl()
           if _only_ WDH caused this irq */
        if ((ohci->hcca->done_head != 0)
                        && ! (hc32_to_cpup (ohci, &ohci->hcca->done_head)
                                & 0x01)) {
                ints =  OHCI_INTR_WDH;

The problem though is when OHCI shares IRQ with something truly fast,
like tg3 (ok, I understand that it needs its own IRQ to be "truly" fast).

So, what do you think?

-- Pete

diff -urp -X dontdiff linux-2.6.18-rc6/drivers/usb/host/ohci.h 
linux-2.6.18-rc6-lem/drivers/usb/host/ohci.h
--- linux-2.6.18-rc6/drivers/usb/host/ohci.h    2006-01-03 20:03:35.000000000 
-0800
+++ linux-2.6.18-rc6-lem/drivers/usb/host/ohci.h        2006-09-06 
22:16:45.000000000 -0700
@@ -388,6 +388,7 @@ struct ohci_hcd {
        u32                     hc_control;     /* copy of hc control reg */
        unsigned long           next_statechange;       /* suspend/resume */
        u32                     fminterval;             /* saved register */
+       int                     irq_disabled;
 
        struct notifier_block   reboot_notifier;
 
diff -urp -X dontdiff linux-2.6.18-rc6/drivers/usb/host/ohci-hcd.c 
linux-2.6.18-rc6-lem/drivers/usb/host/ohci-hcd.c
--- linux-2.6.18-rc6/drivers/usb/host/ohci-hcd.c        2006-09-06 
21:56:32.000000000 -0700
+++ linux-2.6.18-rc6-lem/drivers/usb/host/ohci-hcd.c    2006-09-06 
22:16:45.000000000 -0700
@@ -693,6 +693,17 @@ static irqreturn_t ohci_irq (struct usb_
        struct ohci_regs __iomem *regs = ohci->regs;
        int                     ints; 
 
+       spin_lock (&ohci->lock);
+       if (ohci->irq_disabled) {
+               /*
+                * It's an interrupt from other device sharing the IRQ line
+                * with us. See code below as why we do not read intrenable.
+                */
+               spin_unlock (&ohci->lock);
+               return IRQ_NOTMINE;
+       }
+       spin_unlock (&ohci->lock);
+
        /* we can eliminate a (slow) ohci_readl()
           if _only_ WDH caused this irq */
        if ((ohci->hcca->done_head != 0)
@@ -765,6 +776,7 @@ static irqreturn_t ohci_irq (struct usb_
 static void ohci_stop (struct usb_hcd *hcd)
 {      
        struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
+       unsigned long           flags;
 
        ohci_dbg (ohci, "stop %s controller (state 0x%02x)\n",
                hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
@@ -775,7 +787,11 @@ static void ohci_stop (struct usb_hcd *h
 
        ohci_usb_reset (ohci);
        ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
-       
+       spin_lock_irqsave (&ohci->lock, flags);
+       ohci->irq_disabled = 1;
+       spin_unlock_irqrestore (&ohci->lock, flags);
+       synchronize_irq(hcd->irq);
+
        remove_debug_files (ohci);
        unregister_reboot_notifier (&ohci->reboot_notifier);
        ohci_mem_cleanup (ohci);

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to