From owner-freebsd-mobile@FreeBSD.ORG Sun Sep 7 09:43:38 2003 Return-Path: Delivered-To: freebsd-mobile@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1ACBF16A4BF; Sun, 7 Sep 2003 09:43:38 -0700 (PDT) Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by mx1.FreeBSD.org (Postfix) with SMTP id 9A6AC43FDF; Sun, 7 Sep 2003 09:43:36 -0700 (PDT) (envelope-from iedowse@maths.tcd.ie) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id ; 7 Sep 2003 17:43:31 +0100 (BST) To: deischen@freebsd.org In-Reply-To: Your message of "Sat, 06 Sep 2003 04:48:39 EDT." Date: Sun, 07 Sep 2003 17:43:29 +0100 From: Ian Dowse Message-ID: <200309071743.aa44498@salmon.maths.tcd.ie> cc: kuku@physik.rwth-aachen.de cc: "M. Warner Losh" cc: John Birrell cc: freebsd-mobile@freebsd.org Subject: Re: wi0_cmd: busy bit won't clear X-BeenThere: freebsd-mobile@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Mobile computing with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 07 Sep 2003 16:43:38 -0000 In message , 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);