return (ENXIO); /* failure */
}
+static void
+zyd_drain_mbufq(struct zyd_softc *sc)
+{
+ struct mbuf *m;
+ struct ieee80211_node *ni;
+
+ ZYD_LOCK_ASSERT(sc, MA_OWNED);
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
+ ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
+ m->m_pkthdr.rcvif = NULL;
+ ieee80211_free_node(ni);
+ m_freem(m);
+ }
+}
+
+
static int
zyd_detach(device_t dev)
{
*/
ZYD_LOCK(sc);
sc->sc_flags |= ZYD_FLAG_DETACHED;
+ zyd_drain_mbufq(sc);
STAILQ_INIT(&sc->tx_q);
STAILQ_INIT(&sc->tx_free);
ZYD_UNLOCK(sc);
if (ic->ic_softc == sc)
ieee80211_ifdetach(ic);
- mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
k = ieee80211_crypto_encap(ni, m0);
if (k == NULL) {
- m_freem(m0);
return (ENOBUFS);
}
/* packet header may have moved, reset our local pointer */
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
if (zyd_tx_start(sc, m, ni) != 0) {
ieee80211_free_node(ni);
+ m_freem(m);
if_inc_counter(ni->ni_vap->iv_ifp,
IFCOUNTER_OERRORS, 1);
break;
if (zyd_tx_start(sc, m, ni) != 0) {
ZYD_UNLOCK(sc);
ieee80211_free_node(ni);
+ m_freem(m);
return (EIO);
}
ZYD_UNLOCK(sc);
ZYD_LOCK_ASSERT(sc, MA_OWNED);
sc->sc_flags &= ~ZYD_FLAG_RUNNING;
+ zyd_drain_mbufq(sc);
/*
* Drain all the transfers, if not already drained: