USB hci interface's probably will not work with shared IRQ without
this patch. The hcd core always returns IRQ_HANDLED.
The fix is to change the irq hook to return a value and propagate
result back out.
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c Tue Jan 27 14:21:15 2004
+++ b/drivers/usb/core/hcd.c Tue Jan 27 14:21:15 2004
@@ -1513,7 +1513,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 Tue Jan 27 14:21:15 2004
+++ b/drivers/usb/core/hcd.h Tue Jan 27 14:21:15 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 Tue Jan 27 14:21:15 2004
+++ b/drivers/usb/host/ehci-hcd.c Tue Jan 27 14:21:15 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 Tue Jan 27 14:21:15 2004
+++ b/drivers/usb/host/ohci-hcd.c Tue Jan 27 14:21:15 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 (®s->intrstatus)) == ~(u32)0) {
disable (ohci);
ohci_dbg (ohci, "device removed!\n");
- return;
+ return IRQ_NONE;
/* interrupt for some other device? */
} else if ((ints &= readl (®s->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 Tue Jan 27 14:21:15 2004
+++ b/drivers/usb/host/uhci-hcd.c Tue Jan 27 14:21:15 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)
--
Stephen Hemminger mailto:[EMAIL PROTECTED]
Open Source Development Lab http://developer.osdl.org/shemminger
-------------------------------------------------------
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