diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2004-11-19 22:10:25 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2004-11-19 22:10:25 +0000 |
commit | 099fce09a94b52f4d15f25678f1ed1a1ab2e3fc7 (patch) | |
tree | ab9cedf940ee81926f6c45dad27a594b910d033f /sys/arch/mvmeppc/dev | |
parent | a7a0b85a1c2ac027736ef666440330998e095187 (diff) |
Better i8259 slave handling:
- check for spurious interrupt conditions.
- do not ack the slave irq on the master unless there are really no more
interrupts to be serviced on the slave.
Diffstat (limited to 'sys/arch/mvmeppc/dev')
-rw-r--r-- | sys/arch/mvmeppc/dev/openpic.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/sys/arch/mvmeppc/dev/openpic.c b/sys/arch/mvmeppc/dev/openpic.c index e80a327829a..08a9b734478 100644 --- a/sys/arch/mvmeppc/dev/openpic.c +++ b/sys/arch/mvmeppc/dev/openpic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: openpic.c,v 1.17 2004/07/14 11:37:07 miod Exp $ */ +/* $OpenBSD: openpic.c,v 1.18 2004/11/19 22:10:24 miod Exp $ */ /*- * Copyright (c) 1995 Per Fogelstrom @@ -103,7 +103,7 @@ void i8259_init(void); int i8259_intr(void); void i8259_enable_irq(int, int); void i8259_disable_irq(int); -static __inline void i8259_eoi(int); +void i8259_eoi(int); void *i8259_intr_establish(void *, int, int, int, int (*)(void *), void *, char *); void i8259_set_irq_mask(void); @@ -818,7 +818,7 @@ i8259_enable_irq(irq, type) } } -static __inline void +void i8259_eoi(int irq) { #ifdef DIAGNOSTIC @@ -831,7 +831,14 @@ i8259_eoi(int irq) outb(IO_ICU1, 0x60 | irq); else { outb(IO_ICU2, 0x60 | (irq - 8)); - outb(IO_ICU1, 0x60 | IRQ_SLAVE); + /* + * Do not ack on the master unless there are no + * other interrupts pending on the slave + * controller! + */ + outb(IO_ICU2, 0x0b); + if (inb(IO_ICU2) == 0) + outb(IO_ICU1, 0x60 | IRQ_SLAVE); } } @@ -897,6 +904,15 @@ i8259_intr(void) */ outb(IO_ICU2, 0x0c); irq = (inb(IO_ICU2) & 7) + 8; + if (irq == 15) { + outb(IO_ICU2, 0x0b); + if ((inb(IO_ICU2) & 0x80) == 0) { +#ifdef DIAGNOSTIC + printf("spurious interrupt on ICU2\n"); +#endif + return PIC_SPURIOUS; + } + } } else if (irq == 7) { /* * This may be a spurious interrupt |