summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2006-12-11 00:35:51 +0000
committersam <sam@FreeBSD.org>2006-12-11 00:35:51 +0000
commit559b88d1c8f6977d912401da0aec406fd7ba892f (patch)
treed40dcc549435472c2ca96cda980bd9217c47d6ab
parent02d21702b760c4e2ac09dc97d6fcc5298c51ce51 (diff)
downloadFreeBSD-src-559b88d1c8f6977d912401da0aec406fd7ba892f.zip
FreeBSD-src-559b88d1c8f6977d912401da0aec406fd7ba892f.tar.gz
split wi_start int locked+unlocked variants and use the unlocked
one from the isr to eliminate a recursive lock MFC after: 1 month
-rw-r--r--sys/dev/wi/if_wi.c23
-rw-r--r--sys/dev/wi/if_wivar.h1
2 files changed, 15 insertions, 9 deletions
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c
index e2ef447..872c896 100644
--- a/sys/dev/wi/if_wi.c
+++ b/sys/dev/wi/if_wi.c
@@ -112,6 +112,7 @@ __FBSDID("$FreeBSD$");
#include <dev/wi/if_wireg.h>
#include <dev/wi/if_wivar.h>
+static void wi_start_locked(struct ifnet *);
static void wi_start(struct ifnet *);
static int wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr,
struct mbuf *m0);
@@ -632,7 +633,7 @@ wi_intr(void *arg)
if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
(sc->sc_flags & WI_FLAGS_OUTRANGE) == 0 &&
!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- wi_start(ifp);
+ wi_start_locked(ifp);
/* Re-enable interrupts. */
CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
@@ -877,7 +878,7 @@ wi_stop(struct ifnet *ifp, int disable)
}
static void
-wi_start(struct ifnet *ifp)
+wi_start_locked(struct ifnet *ifp)
{
struct wi_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
@@ -888,16 +889,12 @@ wi_start(struct ifnet *ifp)
struct wi_frame frmhdr;
int cur;
- WI_LOCK(sc);
+ WI_LOCK_ASSERT(sc);
- if (sc->wi_gone) {
- WI_UNLOCK(sc);
+ if (sc->wi_gone)
return;
- }
- if (sc->sc_flags & WI_FLAGS_OUTRANGE) {
- WI_UNLOCK(sc);
+ if (sc->sc_flags & WI_FLAGS_OUTRANGE)
return;
- }
memset(&frmhdr, 0, sizeof(frmhdr));
cur = sc->sc_txnext;
@@ -1001,7 +998,15 @@ wi_start(struct ifnet *ifp)
continue;
sc->sc_txnext = cur = (cur + 1) % sc->sc_ntxbuf;
}
+}
+
+static void
+wi_start(struct ifnet *ifp)
+{
+ struct wi_softc *sc = ifp->if_softc;
+ WI_LOCK(sc);
+ wi_start_locked(ifp);
WI_UNLOCK(sc);
}
diff --git a/sys/dev/wi/if_wivar.h b/sys/dev/wi/if_wivar.h
index a1dc803..a437f96 100644
--- a/sys/dev/wi/if_wivar.h
+++ b/sys/dev/wi/if_wivar.h
@@ -220,6 +220,7 @@ struct wi_card_ident {
#define WI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define WI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
+#define WI_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
int wi_attach(device_t);
int wi_detach(device_t);
OpenPOWER on IntegriCloud