summaryrefslogtreecommitdiff
path: root/sys/arch/alpha/pci/pci_550.c
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2006-06-15 20:08:30 +0000
committerBrad Smith <brad@cvs.openbsd.org>2006-06-15 20:08:30 +0000
commit3c18738eebc3ab152ffb51145446e53abd3236d3 (patch)
tree65edf799ed5992b4b991b8ce6eeff4ef74f2e0b7 /sys/arch/alpha/pci/pci_550.c
parentfd293392db098cbdef234cf36ac226873023a403 (diff)
Rework the interrupt code, shaving some cycles off in the process.
Rather than an "iointr" routine that decomposes a vector into an IRQ, we maintain a vector table directly, hooking up each "iointr" routine at the correct vector. This also allows us to hook device interrupts up to specific vectors. From thorpej NetBSD Tested by myself and a number of end-users.
Diffstat (limited to 'sys/arch/alpha/pci/pci_550.c')
-rw-r--r--sys/arch/alpha/pci/pci_550.c46
1 files changed, 19 insertions, 27 deletions
diff --git a/sys/arch/alpha/pci/pci_550.c b/sys/arch/alpha/pci/pci_550.c
index afecb9d760e..b7c712a9f30 100644
--- a/sys/arch/alpha/pci/pci_550.c
+++ b/sys/arch/alpha/pci/pci_550.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_550.c,v 1.15 2006/03/26 20:23:08 brad Exp $ */
+/* $OpenBSD: pci_550.c,v 1.16 2006/06/15 20:08:29 brad Exp $ */
/* $NetBSD: pci_550.c,v 1.18 2000/06/29 08:58:48 mrg Exp $ */
/*-
@@ -126,7 +126,7 @@ void dec_550_pciide_compat_intr_disestablish(void *, void *);
struct alpha_shared_intr *dec_550_pci_intr;
-void dec_550_iointr(void *framep, unsigned long vec);
+void dec_550_iointr(void *arg, unsigned long vec);
void dec_550_intr_enable(int irq);
void dec_550_intr_disable(int irq);
@@ -171,8 +171,6 @@ pci_550_pickintr(ccp)
#if NSIO
sio_intr_setup(pc, iot);
#endif
-
- set_iointr(dec_550_iointr);
}
int
@@ -319,8 +317,11 @@ dec_550_intr_establish(ccv, ih, level, func, arg, name)
cookie = alpha_shared_intr_establish(dec_550_pci_intr, ih, IST_LEVEL,
level, func, arg, name);
- if (cookie != NULL && alpha_shared_intr_isactive(dec_550_pci_intr, ih))
+ if (cookie != NULL &&
+ alpha_shared_intr_firstactive(dec_550_pci_intr, ih)) {
+ scb_set(0x900 + SCB_IDXTOVEC(ih), dec_550_iointr, NULL);
dec_550_intr_enable(ih);
+ }
return (cookie);
}
@@ -354,6 +355,7 @@ dec_550_intr_disestablish(ccv, cookie)
dec_550_intr_disable(irq);
alpha_shared_intr_set_dfltsharetype(dec_550_pci_intr, irq,
IST_NONE);
+ scb_free(0x900 + SCB_IDXTOVEC(irq));
}
splx(s);
@@ -397,34 +399,24 @@ dec_550_pciide_compat_intr_disestablish(v, cookie)
}
void
-dec_550_iointr(framep, vec)
- void *framep;
+dec_550_iointr(arg, vec)
+ void *arg;
unsigned long vec;
{
int irq;
- if (vec >= 0x900) {
- irq = ((vec - 0x900) >> 4);
+ irq = SCB_VECTOIDX(vec - 0x900);
- if (irq >= DEC_550_MAX_IRQ)
- panic("550_iointr: vec 0x%lx out of range", vec);
+ if (irq >= DEC_550_MAX_IRQ)
+ panic("550_iointr: vec 0x%lx out of range\n", vec);
- if (!alpha_shared_intr_dispatch(dec_550_pci_intr, irq)) {
- alpha_shared_intr_stray(dec_550_pci_intr, irq,
- "dec 550 irq");
- if (ALPHA_SHARED_INTR_DISABLE(dec_550_pci_intr, irq))
- dec_550_intr_disable(irq);
- } else
- alpha_shared_intr_reset_strays(dec_550_pci_intr, irq);
- return;
- }
-#if NSIO
- if (vec >= 0x800) {
- sio_iointr(framep, vec);
- return;
- }
-#endif
- panic("dec_550_iointr: weird vec 0x%lx", vec);
+ if (!alpha_shared_intr_dispatch(dec_550_pci_intr, irq)) {
+ alpha_shared_intr_stray(dec_550_pci_intr, irq,
+ "dec 550 irq");
+ if (ALPHA_SHARED_INTR_DISABLE(dec_550_pci_intr, irq))
+ dec_550_intr_disable(irq);
+ } else
+ alpha_shared_intr_reset_strays(dec_550_pci_intr, irq);
}
void