ChangeSet 1.1500.8.11, 2004/02/02 13:43:56-08:00, [EMAIL PROTECTED]

[PATCH] USB: fix usb hc and shared irq handling

Here is a revised version of the irqreturn_t propagation patch.
The only difference is now ohci-hcd returns IRQ_HANDLED in the remove case.


 drivers/usb/core/hcd.c      |    4 +++-
 drivers/usb/core/hcd.h      |    2 +-
 drivers/usb/host/ehci-hcd.c |    9 ++++++++-
 drivers/usb/host/ohci-hcd.c |    8 +++++---
 drivers/usb/host/uhci-hcd.c |    5 +++--
 5 files changed, 20 insertions(+), 8 deletions(-)


diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c    Mon Feb  9 14:41:01 2004
+++ b/drivers/usb/core/hcd.c    Mon Feb  9 14:41:01 2004
@@ -1516,7 +1516,9 @@
                return IRQ_NONE;
 
        hcd->saw_irq = 1;
-       hcd->driver->irq (hcd, r);
+       if (hcd->driver->irq (hcd, r) == IRQ_NONE)
+               return IRQ_NONE;
+
        if (hcd->state != start && hcd->state == USB_STATE_HALT)
                usb_hc_died (hcd);
        return IRQ_HANDLED;
diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h    Mon Feb  9 14:41:01 2004
+++ b/drivers/usb/core/hcd.h    Mon Feb  9 14:41:01 2004
@@ -163,7 +163,7 @@
        const char      *description;   /* "ehci-hcd" etc */
 
        /* irq handler */
-       void    (*irq) (struct usb_hcd *hcd, struct pt_regs *regs);
+       irqreturn_t     (*irq) (struct usb_hcd *hcd, struct pt_regs *regs);
 
        int     flags;
 #define        HCD_MEMORY      0x0001          /* HC regs use memory (else I/O) */
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c       Mon Feb  9 14:41:01 2004
+++ b/drivers/usb/host/ehci-hcd.c       Mon Feb  9 14:41:01 2004
@@ -680,7 +680,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs)
+static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
        u32                     status;
@@ -690,6 +690,12 @@
 
        status = readl (&ehci->regs->status);
 
+       /* shared irq */
+       if (status == 0) {
+               spin_unlock (&ehci->lock);
+               return IRQ_NONE;
+       }
+
        /* e.g. cardbus physical eject */
        if (status == ~(u32) 0) {
                ehci_dbg (ehci, "device removed\n");
@@ -743,6 +749,7 @@
                ehci_work (ehci, regs);
 done:
        spin_unlock (&ehci->lock);
+       return IRQ_HANDLED;
 }
 
 /*-------------------------------------------------------------------------*/
diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c       Mon Feb  9 14:41:01 2004
+++ b/drivers/usb/host/ohci-hcd.c       Mon Feb  9 14:41:01 2004
@@ -545,7 +545,7 @@
 
 /* an interrupt happens */
 
-static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
+static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
 {
        struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
        struct ohci_regs        *regs = ohci->regs;
@@ -560,11 +560,11 @@
        } else if ((ints = readl (&regs->intrstatus)) == ~(u32)0) {
                disable (ohci);
                ohci_dbg (ohci, "device removed!\n");
-               return;
+               return IRQ_HANDLED;
 
        /* interrupt for some other device? */
        } else if ((ints &= readl (&regs->intrenable)) == 0) {
-               return;
+               return IRQ_NONE;
        } 
 
        if (ints & OHCI_INTR_UE) {
@@ -604,6 +604,8 @@
                // flush those pci writes
                (void) readl (&ohci->regs->control);
        }
+
+       return IRQ_HANDLED;
 }
 
 /*-------------------------------------------------------------------------*/
diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c       Mon Feb  9 14:41:01 2004
+++ b/drivers/usb/host/uhci-hcd.c       Mon Feb  9 14:41:01 2004
@@ -1909,7 +1909,7 @@
        spin_unlock_irqrestore(&uhci->urb_remove_list_lock, flags);
 }
 
-static void uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
+static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
 {
        struct uhci_hcd *uhci = hcd_to_uhci(hcd);
        unsigned int io_addr = uhci->io_addr;
@@ -1922,7 +1922,7 @@
         */
        status = inw(io_addr + USBSTS);
        if (!status)    /* shared interrupt, not mine */
-               return;
+               return IRQ_NONE;
        outw(status, io_addr + USBSTS);         /* Clear it */
 
        if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) {
@@ -1963,6 +1963,7 @@
        spin_unlock(&uhci->urb_list_lock);
 
        uhci_finish_completion(hcd, regs);
+       return IRQ_HANDLED;
 }
 
 static void reset_hc(struct uhci_hcd *uhci)



-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to