Re: wi0_cmd: busy bit won't clear
Ian Dowse <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.mobile |
|---|---|
| Message-ID | <[email protected]> |
In message <[email protected]>, Daniel Eischen writes: >Hmm, some of us get it in the reverse -- when the machine boots >with the card in, we get that message. Removing and reinserting >the card after boot seems to work better, but perhaps that's >just my imagination -- I still sometimes have the same problem >when reinserting the card. I have found it almost impossible to determine if any particular change helps or not, as invariably when I do find something that survives 5 or 10 removal/reinsert cycles, I get the error again a few days later and the error frequency seems unchanged. FYI, I use the collection of fairly arbitrary changes in the following patch. This does not fix the problem, but it shortens the hard hangs to about 1 second instead of minutes, and I think some of the extra DELAY() calls help to reduce the frequency of the errors, but that may just my imagination too (certainly most of them make no difference whatsoever). The "!= WI_INTERSIL" bit fixes the "bad alloc" errors by reverting revision 1.142. Ian Index: if_wi.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/dev/wi/if_wi.c,v retrieving revision 1.151 diff -u -r1.151 if_wi.c --- if_wi.c 5 Sep 2003 22:29:30 -0000 1.151 +++ if_wi.c 7 Sep 2003 16:17:23 -0000 @@ -502,7 +502,7 @@ WI_LOCK(sc); /* check if device was removed */ - sc->wi_gone = !bus_child_present(dev); + sc->wi_gone |= !bus_child_present(dev); wi_stop(ifp, 0); @@ -751,6 +751,7 @@ } sc->sc_txcur = sc->sc_txnext = 0; + DELAY(10000); /* Enable desired port */ wi_cmd(sc, WI_CMD_ENABLE | sc->sc_portnum, 0, 0, 0); @@ -808,10 +809,14 @@ WI_LOCK(sc); + DELAY(50000); + ieee80211_new_state(ic, IEEE80211_S_INIT, -1); if (sc->sc_enabled && !sc->wi_gone) { CSR_WRITE_2(sc, WI_INT_EN, 0); + DELAY(10000); wi_cmd(sc, WI_CMD_DISABLE | sc->sc_portnum, 0, 0, 0); + DELAY(10000); if (disable) { #ifdef __NetBSD__ if (sc->sc_disable) @@ -983,7 +988,7 @@ int tries; /* Symbol firmware cannot be initialized more than once */ - if (sc->sc_firmware_type != WI_INTERSIL && sc->sc_reset) + if (sc->sc_firmware_type == WI_SYMBOL && sc->sc_reset) return (0); if (sc->sc_firmware_type == WI_SYMBOL) tries = 1; @@ -1002,12 +1007,15 @@ return (error); } + DELAY(10 * 1000); CSR_WRITE_2(sc, WI_INT_EN, 0); CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); /* Calibrate timer. */ wi_write_val(sc, WI_RID_TICK_TIME, 8); + DELAY(10 * 1000); + return (0); #undef WI_INIT_TRIES } @@ -1597,6 +1605,9 @@ struct ifnet *ifp = &ic->ic_if; int fid, cur; + if (sc->wi_gone) + return; + fid = CSR_READ_2(sc, WI_ALLOC_FID); CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC); @@ -2363,18 +2374,22 @@ int i, s = 0; static volatile int count = 0; + if (sc->wi_gone) + return (ENODEV); + if (count > 0) panic("Hey partner, hold on there!"); count++; /* wait for the busy bit to clear */ - for (i = 500; i > 0; i--) { /* 5s */ + for (i = 500; i > 0; i--) { /* 500ms */ if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) break; - DELAY(10*1000); /* 10 m sec */ + DELAY(1*1000); /* 1ms */ } if (i == 0) { device_printf(sc->sc_dev, "wi_cmd: busy bit won't clear.\n" ); + sc->wi_gone = 1; count--; return(ETIMEDOUT); } @@ -2411,8 +2426,12 @@ if (i == WI_TIMEOUT) { device_printf(sc->sc_dev, "timeout in wi_cmd 0x%04x; event status 0x%04x\n", cmd, s); + if (s == 0xffff) + sc->wi_gone = 1; return(ETIMEDOUT); } + if (cmd == WI_CMD_INI) + DELAY(5000); return (0); } @@ -2432,6 +2451,8 @@ device_printf(sc->sc_dev, "timeout in wi_seek to %x/%x\n", id, off); sc->sc_bap_off = WI_OFF_ERR; /* invalidate */ + if (status == 0xffff) + sc->wi_gone = 1; return ETIMEDOUT; } DELAY(1); _______________________________________________ [email protected] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-mobile To unsubscribe, send any mail to "[email protected]"