rum: fix possible panic on device detach (similar to r302034).

Tested with WUSB54GC, STA/AP modes.
This commit is contained in:
Andriy Voskoboinyk 2016-09-07 16:19:20 +00:00
parent 9a6eb971a1
commit d204cea9f8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=305544

View File

@ -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)
{