Subject: kern/9029: elinkxl [ex] Ethernet driver appears to fail to acknowledge an interrupt
To: None <gnats-bugs@gnats.netbsd.org>
From: None <mhitch@montana.edu>
List: netbsd-bugs
Date: 12/19/1999 11:15:39
>Number: 9029
>Category: kern
>Synopsis: The elinkxl driver appears to not acknowedge an interrupt at times.
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Dec 19 11:15:00 1999
>Last-Modified:
>Originator: Michael L. Hitch
>Organization:
Montana State University
>Release: <NetBSD-current source date> December 4, 1999
>Environment:
System: NetBSD alpha.msu.montana.edu 1.4P NetBSD 1.4P (PC164) #991204-7: Sat Dec 18 10:47:03 MST 1999 mhitch@alpha.msu.montana.edu:/usr/cvsroot/src/sys/arch/alpha/compile/PC164 alpha
>Description:
On my PC164, the 3Com 3c905B and 3c980 Ethernet cards would stop working after
relatively heavy network traffic. This would usually happen when I was
running xscreensaver on the PC164 and displaying on my Amiga. After finally
noticing a "stray interrupt" log message, I found that the alpha interrupt
handler was disabling the interrupt when no driver handled that interrupt.
Further investigation showed that the Ethernet cards appeared to be
generating an interrupt, and only the S_INTR_LATCH was set in the status
register (which was not considered an interrupt condition).
>How-To-Repeat:
Install a 3Com 3c980 or 3c905B Ethernet card in an Alpha PC164, run lots
of network traffic over that adapter for a while, and wait for the driver
to stop functioning because the interrupt gets disabled.
>Fix:
Possibly include the S_INTR_LATCH in interrupt status bits, since that
status bit appears to be abled to be cleared by the software.
The following patch separately checks for the S_INTR_LATCH status bit being
set when no other interrupt status was present, displays a console message,
clears the S_INTR_LATCH status, and indicates the driver handled the interrupt.
The interfaces now periodically report this message, and continue to function.
--- elinkxl.c.orig Sun Dec 19 11:51:06 1999
+++ elinkxl.c Sun Dec 19 12:09:38 1999
@@ -1109,8 +1116,15 @@
}
for (;;) {
stat = bus_space_read_2(iot, ioh, ELINK_STATUS);
- if (!(stat & S_MASK))
+ if (!(stat & S_MASK)) {
+ if (ret == 0 && (stat & S_INTR_LATCH) != 0) {
+ printf("%s: %x intr_latch set, clearing\n",
+ sc->sc_dev.dv_xname, stat);
+ bus_space_write_2(iot, ioh, ELINK_COMMAND, C_INTR_LATCH);
+ ret = 1;
+ }
break;
+ }
/*
* Acknowledge interrupts.
*/
>Audit-Trail:
>Unformatted: