diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-01-09 18:53:17 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-01-09 18:53:17 +0000 |
commit | 0c0ef2f45a5d5a5a68abfbcec8d3cf66c28c6d0f (patch) | |
tree | 87bdc2bb7179ab22074ec9f65c0bd4d8d33ef9d0 /sys | |
parent | 91c895836d1842819b43b7f949dbfd469d2b5c1f (diff) |
Make sure we move an interrupt vector to the "lowest" priority level if
necessary. Fixes a nasty bug with establishing interrupts "late". Also
make sure we skip the handler being removed when calculating the new "lowest"
and "highest" priority level when disestablishing interrupts. Remove dmesg
spam when freeing vectors.
tested by many, ok marco@, beck@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/i386/i386/ioapic.c | 20 |
1 files changed, 8 insertions, 12 deletions
diff --git a/sys/arch/i386/i386/ioapic.c b/sys/arch/i386/i386/ioapic.c index cc6b3b9dfaf..cea19a78fcb 100644 --- a/sys/arch/i386/i386/ioapic.c +++ b/sys/arch/i386/i386/ioapic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ioapic.c,v 1.19 2008/10/21 21:52:07 brad Exp $ */ +/* $OpenBSD: ioapic.c,v 1.20 2009/01/09 18:53:16 kettenis Exp $ */ /* $NetBSD: ioapic.c,v 1.7 2003/07/14 22:32:40 lukem Exp $ */ /*- @@ -442,7 +442,7 @@ apic_vectorset(struct ioapic_softc *sc, int pin, int minlevel, int maxlevel) pp->ip_minlevel = 0xff; /* XXX magic */ pp->ip_maxlevel = 0; /* XXX magic */ pp->ip_vector = 0; - } else if (maxlevel != pp->ip_maxlevel) { + } else if (minlevel != pp->ip_minlevel) { #ifdef MPVERBOSE if (minlevel != maxlevel) printf("%s: pin %d shares different IPL interrupts " @@ -458,7 +458,6 @@ apic_vectorset(struct ioapic_softc *sc, int pin, int minlevel, int maxlevel) * as appropriate. */ nvector = idt_vec_alloc(minlevel, minlevel+15); - if (nvector == 0) { /* * XXX XXX we should be able to deal here.. @@ -468,16 +467,14 @@ apic_vectorset(struct ioapic_softc *sc, int pin, int minlevel, int maxlevel) panic("%s: can't alloc vector for pin %d at level %x", sc->sc_dev.dv_xname, pin, maxlevel); } - apic_maxlevel[nvector] = maxlevel; - /* - * XXX want special handler for the maxlevel != minlevel - * case here! - */ + idt_vec_set(nvector, apichandler[nvector & 0xf]); - pp->ip_vector = nvector; pp->ip_minlevel = minlevel; - pp->ip_maxlevel = maxlevel; + pp->ip_vector = nvector; } + + pp->ip_maxlevel = maxlevel; + apic_maxlevel[pp->ip_vector] = maxlevel; apic_intrhand[pp->ip_vector] = pp->ip_handler; if (ovector && ovector != pp->ip_vector) { @@ -496,7 +493,6 @@ apic_vectorset(struct ioapic_softc *sc, int pin, int minlevel, int maxlevel) */ apic_intrhand[ovector] = NULL; idt_vec_free(ovector); - printf("freed vector %x\n", ovector); } apic_set_redir(sc, pin); @@ -726,7 +722,7 @@ apic_intr_disestablish(void *arg) *p = q->ih_next; else panic("intr_disestablish: handler not registered"); - for (; q != NULL; q = q->ih_next) { + for (q = *p; q != NULL; q = q->ih_next) { if (q->ih_level > maxlevel) maxlevel = q->ih_level; if (q->ih_level < minlevel) |