Subject: Re: kern/31455: ex (905[BC]) cards can hang in -current kernels
To: None <gnats-bugs@netbsd.org>
From: ITOH Yasufumi <itohy@netbsd.org>
List: netbsd-bugs
Date: 12/19/2005 23:18:26
Hello,

I have similar hang on 2.1_STABLE.  Mine is

> ex0 at pci0 dev 3 function 0: 3Com 3c556 MiniPCI 10/100 Ethernet (rev. 0x10)
> ex0: interrupting at irq 11
> ex0: MAC address 00:01:03:xx:xx:xx
> tqphy0 at ex0 phy 0: 78Q2120 10/100 media interface, rev. 11
> tqphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
> 3Com 3c556 V.90 MiniPCI Modem (miscellaneous communications, revision 0x10) at pci0 dev 3 function 1 not configured

I investigated the problem.
The device have TX_COMPLETE|INTR_LATCH status on ex_intr:

> int
> ex_intr(arg)
>	void *arg;
> {
...
>		stat = bus_space_read_2(iot, ioh, ELINK_STATUS);
"stat" is 0x2005 here.
So it calls ex_txstat (TX_COMPLETE == 4).
>		if (stat & TX_COMPLETE) {
>			ex_txstat(sc);
>		}

> static void
> ex_txstat(sc)
>	struct ex_softc *sc;
> {
...
>	while ((i = bus_space_read_2(iot, ioh, ELINK_TIMER)) & TXS_COMPLETE) {

This conditional doesn't met, and the function just returs.
Nothing done for TX_COMPLETE interrupt and the interrupt never cleared.
Hence the hang.

I tested modification like this.
By this change, the kernel doesn't hang eternally,
but short-term hang til timeout remains.

> ex0: device timeout

--- elinkxl.c.orig	Sat Oct 29 04:35:21 2005
+++ elinkxl.c	Mon Dec 19 14:53:10 2005
@@ -786,7 +786,8 @@ ex_txstat(sc)
 	 * We need to read+write TX_STATUS until we get a 0 status
 	 * in order to turn off the interrupt flag.
 	 */
-	while ((i = bus_space_read_2(iot, ioh, ELINK_TIMER)) & TXS_COMPLETE) {
+	i = bus_space_read_2(iot, ioh, ELINK_TIMER);
+	do {
 		bus_space_write_2(iot, ioh, ELINK_TIMER, 0x0);
 
 		if (i & TXS_JABBER) {
@@ -814,7 +815,7 @@ ex_txstat(sc)
 			sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE;
 		} else
 			sc->tx_succ_ok = (sc->tx_succ_ok+1) & 127;
-	}
+	} while ((i = bus_space_read_2(iot, ioh, ELINK_TIMER)) & TXS_COMPLETE);
 }
 
 int

Similar codepath exists also in 3-branch and in -current.
Any thoughts?
-- 
ITOH Yasufumi