Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/eisa Don't blindly establish our interrupt handler a...
details: https://anonhg.NetBSD.org/src/rev/476b34ec32ed
branches: trunk
changeset: 984807:476b34ec32ed
user: thorpej <thorpej%NetBSD.org@localhost>
date: Sat Jul 24 15:52:16 2021 +0000
description:
Don't blindly establish our interrupt handler as IST_LEVEL. If the INTDEF
register has the INTHIGH bit set, the controller is going to keep the
line low when *not* asserting an interrupt, and since EISA level-tiggered
interrupts are active-low, this would result in a forever-interrupt-storm.
So, if INTHIGH is set in INTDEF, establish our interrupt handler as
IST_EDGE, which will program the EISA PIC to detect the interrupt on
the rising edge of the IRQ line.
diffstat:
sys/dev/eisa/ahb.c | 32 ++++++++++++++++++++++++++------
1 files changed, 26 insertions(+), 6 deletions(-)
diffs (88 lines):
diff -r 1e46be7cf011 -r 476b34ec32ed sys/dev/eisa/ahb.c
--- a/sys/dev/eisa/ahb.c Sat Jul 24 15:44:16 2021 +0000
+++ b/sys/dev/eisa/ahb.c Sat Jul 24 15:52:16 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ahb.c,v 1.66 2021/04/24 23:36:53 thorpej Exp $ */
+/* $NetBSD: ahb.c,v 1.67 2021/07/24 15:52:16 thorpej Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -46,7 +46,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ahb.c,v 1.66 2021/04/24 23:36:53 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahb.c,v 1.67 2021/07/24 15:52:16 thorpej Exp $");
#include "opt_ddb.h"
@@ -112,6 +112,7 @@
struct ahb_probe_data {
int sc_irq;
+ int sc_ist;
int sc_scsi_dev;
};
@@ -251,7 +252,7 @@
return;
}
intrstr = eisa_intr_string(ec, ih, intrbuf, sizeof(intrbuf));
- sc->sc_ih = eisa_intr_establish(ec, ih, IST_LEVEL, IPL_BIO,
+ sc->sc_ih = eisa_intr_establish(ec, ih, apd.sc_ist, IPL_BIO,
ahbintr, sc);
if (sc->sc_ih == NULL) {
aprint_error_dev(sc->sc_dev, "couldn't establish interrupt");
@@ -260,8 +261,11 @@
aprint_error("\n");
return;
}
- if (intrstr != NULL)
- aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);
+ if (intrstr != NULL) {
+ aprint_normal_dev(sc->sc_dev,
+ "interrupting at %s (%s trigger)\n", intrstr,
+ apd.sc_ist == IST_EDGE ? "edge" : "level");
+ }
/*
* ask the adapter what subunits are present
@@ -609,7 +613,7 @@
struct ahb_probe_data *sc)
{
u_char intdef;
- int i, irq, busid;
+ int i, irq, ist, busid;
int wait = 1000; /* 1 sec enough? */
bus_space_write_1(iot, ioh, PORTADDR, PORTADDR_ENHANCED);
@@ -676,6 +680,21 @@
return EIO;
}
+ /*
+ * On EISA, edge triggered interrupts are signalled by the rising
+ * edge of the interrupt signal, while level tiggered interrupts
+ * are signalled so long as the interrupt signal is driven low.
+ *
+ * So, if the controller is configured for active-high interrupts,
+ * that is "edge trigger" in our parlance, while active-low would
+ * be "level trigger".
+ */
+ if (intdef & INTHIGH) {
+ ist = IST_EDGE;
+ } else {
+ ist = IST_LEVEL;
+ }
+
bus_space_write_1(iot, ioh, INTDEF, (intdef | INTEN)); /* make sure we can interrupt */
/* who are we on the scsi bus? */
@@ -684,6 +703,7 @@
/* if we want to return data, do so now */
if (sc) {
sc->sc_irq = irq;
+ sc->sc_ist = ist;
sc->sc_scsi_dev = busid;
}
Home |
Main Index |
Thread Index |
Old Index