Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci newstate should be blocked network interrupt, be...
details: https://anonhg.NetBSD.org/src/rev/15b22b7af96f
branches: trunk
changeset: 350752:15b22b7af96f
user: nonaka <nonaka%NetBSD.org@localhost>
date: Thu Jan 19 11:24:05 2017 +0000
description:
newstate should be blocked network interrupt, because it called iwm_start.
diffstat:
sys/dev/pci/if_iwm.c | 94 ++++++++++++++++++++++++++++-----------------------
1 files changed, 51 insertions(+), 43 deletions(-)
diffs (240 lines):
diff -r 980451f165d5 -r 15b22b7af96f sys/dev/pci/if_iwm.c
--- a/sys/dev/pci/if_iwm.c Thu Jan 19 11:10:38 2017 +0000
+++ b/sys/dev/pci/if_iwm.c Thu Jan 19 11:24:05 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_iwm.c,v 1.64 2017/01/17 08:47:32 nonaka Exp $ */
+/* $NetBSD: if_iwm.c,v 1.65 2017/01/19 11:24:05 nonaka Exp $ */
/* OpenBSD: if_iwm.c,v 1.148 2016/11/19 21:07:08 stsp Exp */
#define IEEE80211_NO_HT
/*
@@ -107,7 +107,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.64 2017/01/17 08:47:32 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.65 2017/01/19 11:24:05 nonaka Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@@ -453,6 +453,8 @@
static int iwm_setrates(struct iwm_node *);
#endif
static int iwm_media_change(struct ifnet *);
+static int iwm_do_newstate(struct ieee80211com *, enum ieee80211_state,
+ int);
static void iwm_newstate_cb(struct work *, void *);
static int iwm_newstate(struct ieee80211com *, enum ieee80211_state, int);
static void iwm_endscan(struct iwm_softc *);
@@ -2706,7 +2708,6 @@
sc->sc_rx_ba_sessions--;
} else if (start)
ieee80211_addba_req_refuse(ic, ni, tid);
-
splx(s);
}
@@ -3750,7 +3751,8 @@
sc->qfullmsk &= ~(1 << qid);
if (sc->qfullmsk == 0 && (ifp->if_flags & IFF_OACTIVE)) {
ifp->if_flags &= ~IFF_OACTIVE;
- if_start_lock(ifp);
+ KASSERT(KERNEL_LOCKED_P());
+ iwm_start(ifp);
}
}
@@ -5837,31 +5839,15 @@
return err;
}
-static void
-iwm_newstate_cb(struct work *wk, void *v)
-{
- struct iwm_softc *sc = v;
- struct ieee80211com *ic = &sc->sc_ic;
- struct iwm_newstate_state *iwmns = (struct iwm_newstate_state *)wk;
- enum ieee80211_state nstate = iwmns->ns_nstate;
+static int
+iwm_do_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
+{
+ struct ifnet *ifp = IC2IFP(ic);
+ struct iwm_softc *sc = ifp->if_softc;
enum ieee80211_state ostate = ic->ic_state;
- int generation = iwmns->ns_generation;
struct iwm_node *in;
- int arg = iwmns->ns_arg;
int err;
- kmem_free(iwmns, sizeof(*iwmns));
-
- DPRINTF(("Prepare to switch state %d->%d\n", ostate, nstate));
- if (sc->sc_generation != generation) {
- DPRINTF(("newstate_cb: someone pulled the plug meanwhile\n"));
- if (nstate == IEEE80211_S_INIT) {
- DPRINTF(("newstate_cb: nstate == IEEE80211_S_INIT: calling sc_newstate()\n"));
- sc->sc_newstate(ic, nstate, arg);
- }
- return;
- }
-
DPRINTF(("switching state %s->%s\n", ieee80211_state_name[ostate],
ieee80211_state_name[nstate]));
@@ -5900,26 +5886,26 @@
case IEEE80211_S_SCAN:
if (ostate == nstate &&
ISSET(sc->sc_flags, IWM_FLAG_SCANNING))
- return;
+ return 0;
if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN))
err = iwm_umac_scan(sc);
else
err = iwm_lmac_scan(sc);
if (err) {
DPRINTF(("%s: could not initiate scan\n", DEVNAME(sc)));
- return;
+ return err;
}
SET(sc->sc_flags, IWM_FLAG_SCANNING);
ic->ic_state = nstate;
iwm_led_blink_start(sc);
- return;
+ return 0;
case IEEE80211_S_AUTH:
err = iwm_auth(sc);
if (err) {
DPRINTF(("%s: could not move to auth state: %d\n",
DEVNAME(sc), err));
- return;
+ return err;
}
break;
@@ -5928,7 +5914,7 @@
if (err) {
DPRINTF(("%s: failed to associate: %d\n", DEVNAME(sc),
err));
- return;
+ return err;
}
break;
@@ -5939,14 +5925,14 @@
err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_MODIFY, 1);
if (err) {
aprint_error_dev(sc->sc_dev, "failed to update MAC\n");
- return;
+ return err;
}
err = iwm_power_update_device(sc);
if (err) {
aprint_error_dev(sc->sc_dev,
"could send power command (error %d)\n", err);
- return;
+ return err;
}
#ifdef notyet
/*
@@ -5958,21 +5944,21 @@
if (err) {
aprint_error_dev(sc->sc_dev,
"could not enable beacon filter\n");
- return;
+ return err;
}
#endif
err = iwm_power_mac_update_mode(sc, in);
if (err) {
aprint_error_dev(sc->sc_dev,
"could not update MAC power (error %d)\n", err);
- return;
+ return err;
}
err = iwm_update_quotas(sc, in);
if (err) {
aprint_error_dev(sc->sc_dev,
"could not update quotas (error %d)\n", err);
- return;
+ return err;
}
ieee80211_amrr_node_init(&sc->sc_amrr, &in->in_amn);
@@ -5992,7 +5978,36 @@
break;
}
- sc->sc_newstate(ic, nstate, arg);
+ return sc->sc_newstate(ic, nstate, arg);
+}
+
+static void
+iwm_newstate_cb(struct work *wk, void *v)
+{
+ struct iwm_softc *sc = v;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct iwm_newstate_state *iwmns = (struct iwm_newstate_state *)wk;
+ enum ieee80211_state nstate = iwmns->ns_nstate;
+ int generation = iwmns->ns_generation;
+ int arg = iwmns->ns_arg;
+ int s;
+
+ kmem_free(iwmns, sizeof(*iwmns));
+
+ s = splnet();
+
+ DPRINTF(("Prepare to switch state %d->%d\n", ic->ic_state, nstate));
+ if (sc->sc_generation != generation) {
+ DPRINTF(("newstate_cb: someone pulled the plug meanwhile\n"));
+ if (nstate == IEEE80211_S_INIT) {
+ DPRINTF(("newstate_cb: nstate == IEEE80211_S_INIT: "
+ "calling sc_newstate()\n"));
+ (void) sc->sc_newstate(ic, nstate, arg);
+ }
+ } else
+ (void) iwm_do_newstate(ic, nstate, arg);
+
+ splx(s);
}
static int
@@ -6419,7 +6434,6 @@
{
struct iwm_softc *sc = ifp->if_softc;
int err;
- int s;
if (ISSET(sc->sc_flags, IWM_FLAG_HW_INITED))
return 0;
@@ -6436,10 +6450,7 @@
ifp->if_flags &= ~IFF_OACTIVE;
ifp->if_flags |= IFF_RUNNING;
- s = splnet();
ieee80211_begin_scan(&sc->sc_ic, 0);
- splx(s);
-
SET(sc->sc_flags, IWM_FLAG_HW_INITED);
return 0;
@@ -6537,7 +6548,6 @@
struct iwm_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
- int s;
sc->sc_flags &= ~IWM_FLAG_HW_INITED;
sc->sc_flags |= IWM_FLAG_STOPPED;
@@ -6547,10 +6557,8 @@
if (in)
in->in_phyctxt = NULL;
- s = splnet();
if (ic->ic_state != IEEE80211_S_INIT)
ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
- splx(s);
callout_stop(&sc->sc_calib_to);
iwm_led_blink_stop(sc);
Home |
Main Index |
Thread Index |
Old Index