summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2004-11-19 22:10:25 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2004-11-19 22:10:25 +0000
commit099fce09a94b52f4d15f25678f1ed1a1ab2e3fc7 (patch)
treeab9cedf940ee81926f6c45dad27a594b910d033f /sys/arch
parenta7a0b85a1c2ac027736ef666440330998e095187 (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')
-rw-r--r--sys/arch/mvmeppc/dev/openpic.c24
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