This is a note to let you know that I've just added the patch titled

    USB: UHCI: fix IRQ race during initialization

to my usb git tree which can be found at
    git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
in the usb-linus branch.

The patch will show up in the next release of the linux-next tree
(usually sometime within the next 24 hours during the week.)

The patch will hopefully also be merged in Linus's tree for the
next -rc kernel release.

If you have any questions about this process, please let me know.


>From 0f815a0a700bc10547449bde6c106051a035a1b9 Mon Sep 17 00:00:00 2001
From: Alan Stern <[email protected]>
Date: Tue, 22 Jan 2013 11:37:35 -0500
Subject: USB: UHCI: fix IRQ race during initialization

This patch (as1644) fixes a race that occurs during startup in
uhci-hcd.  If the IRQ line is shared with other devices, it's possible
for the handler routine to be called before the data structures are
fully initialized.

The problem is fixed by adding a check to the IRQ handler routine.  If
the initialization hasn't finished yet, the routine will return
immediately.

Signed-off-by: Alan Stern <[email protected]>
Reported-by: Don Zickus <[email protected]>
Tested-by: "Huang, Adrian (ISS Linux TW)" <[email protected]>
Cc: stable <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
 drivers/usb/host/uhci-hcd.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 4b9e9ab..4f64d24 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -447,6 +447,10 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd)
                return IRQ_NONE;
        uhci_writew(uhci, status, USBSTS);              /* Clear it */
 
+       spin_lock(&uhci->lock);
+       if (unlikely(!uhci->is_initialized))    /* not yet configured */
+               goto done;
+
        if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) {
                if (status & USBSTS_HSE)
                        dev_err(uhci_dev(uhci), "host system error, "
@@ -455,7 +459,6 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd)
                        dev_err(uhci_dev(uhci), "host controller process "
                                        "error, something bad happened!\n");
                if (status & USBSTS_HCH) {
-                       spin_lock(&uhci->lock);
                        if (uhci->rh_state >= UHCI_RH_RUNNING) {
                                dev_err(uhci_dev(uhci),
                                        "host controller halted, "
@@ -473,15 +476,15 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd)
                                 * pending unlinks */
                                mod_timer(&hcd->rh_timer, jiffies);
                        }
-                       spin_unlock(&uhci->lock);
                }
        }
 
-       if (status & USBSTS_RD)
+       if (status & USBSTS_RD) {
+               spin_unlock(&uhci->lock);
                usb_hcd_poll_rh_status(hcd);
-       else {
-               spin_lock(&uhci->lock);
+       } else {
                uhci_scan_schedule(uhci);
+ done:
                spin_unlock(&uhci->lock);
        }
 
@@ -662,9 +665,9 @@ static int uhci_start(struct usb_hcd *hcd)
         */
        mb();
 
+       spin_lock_irq(&uhci->lock);
        configure_hc(uhci);
        uhci->is_initialized = 1;
-       spin_lock_irq(&uhci->lock);
        start_rh(uhci);
        spin_unlock_irq(&uhci->lock);
        return 0;
-- 
1.8.1.rc1.5.g7e0651a


--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to