rum: fix possible panic on device detach (similar to r302034).
Tested with WUSB54GC, STA/AP modes.
This commit is contained in:
parent
339ab66e8f
commit
b98d0ca75c
@ -165,6 +165,8 @@ static int rum_cmd_sleepable(struct rum_softc *, const void *,
|
||||
size_t, uint8_t, CMD_FUNC_PROTO);
|
||||
static void rum_tx_free(struct rum_tx_data *, int);
|
||||
static void rum_setup_tx_list(struct rum_softc *);
|
||||
static void rum_reset_tx_list(struct rum_softc *,
|
||||
struct ieee80211vap *);
|
||||
static void rum_unsetup_tx_list(struct rum_softc *);
|
||||
static void rum_beacon_miss(struct ieee80211vap *);
|
||||
static void rum_sta_recv_mgmt(struct ieee80211_node *,
|
||||
@ -723,12 +725,22 @@ rum_vap_delete(struct ieee80211vap *vap)
|
||||
{
|
||||
struct rum_vap *rvp = RUM_VAP(vap);
|
||||
struct ieee80211com *ic = vap->iv_ic;
|
||||
struct rum_softc *sc = ic->ic_softc;
|
||||
|
||||
/* Put vap into INIT state. */
|
||||
ieee80211_new_state(vap, IEEE80211_S_INIT, -1);
|
||||
ieee80211_draintask(ic, &vap->iv_nstate_task);
|
||||
|
||||
RUM_LOCK(sc);
|
||||
/* Cancel any unfinished Tx. */
|
||||
rum_reset_tx_list(sc, vap);
|
||||
RUM_UNLOCK(sc);
|
||||
|
||||
m_freem(rvp->bcn_mbuf);
|
||||
usb_callout_drain(&rvp->ratectl_ch);
|
||||
ieee80211_draintask(ic, &rvp->ratectl_task);
|
||||
ieee80211_ratectl_deinit(vap);
|
||||
ieee80211_vap_detach(vap);
|
||||
m_freem(rvp->bcn_mbuf);
|
||||
free(rvp, M_80211_VAP);
|
||||
}
|
||||
|
||||
@ -815,6 +827,30 @@ rum_setup_tx_list(struct rum_softc *sc)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rum_reset_tx_list(struct rum_softc *sc, struct ieee80211vap *vap)
|
||||
{
|
||||
struct rum_tx_data *data, *tmp;
|
||||
|
||||
KASSERT(vap != NULL, ("%s: vap is NULL\n", __func__));
|
||||
|
||||
STAILQ_FOREACH_SAFE(data, &sc->tx_q, next, tmp) {
|
||||
if (data->ni != NULL && data->ni->ni_vap == vap) {
|
||||
ieee80211_free_node(data->ni);
|
||||
data->ni = NULL;
|
||||
|
||||
KASSERT(data->m != NULL, ("%s: m is NULL\n",
|
||||
__func__));
|
||||
m_freem(data->m);
|
||||
data->m = NULL;
|
||||
|
||||
STAILQ_REMOVE(&sc->tx_q, data, rum_tx_data, next);
|
||||
STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
|
||||
sc->tx_nfree++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rum_unsetup_tx_list(struct rum_softc *sc)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user