PERFORCE change 150171 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sat Sep 20 17:28:52 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=150171
Change 150171 by hselasky at hselasky_laptop001 on 2008/09/20 17:27:55
Fix some USB WLAN problems:
1) Fix a race when destroying VAP's.
2) Fix destroy of clones at device detach.
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_rum2.c#14 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_rum2_var.h#4 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_ural2.c#14 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_ural2_var.h#4 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2.c#15 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2_reg.h#5 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/usb2_wlan.h#4 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_rum2.c#14 (text+ko) ====
@@ -502,6 +502,13 @@
struct ieee80211com *ic;
struct ifnet *ifp;
+#ifdef USB_WLAN_CLONE_FIX
+ if (sc->sc_clone[0]) {
+ if (if_clone_destroy(sc->sc_clone)) {
+ DPRINTFN(0, "Could not destroy clone!\n");
+ }
+ }
+#endif
usb2_config_td_drain(&sc->sc_config_td);
mtx_lock(&sc->sc_mtx);
@@ -1501,11 +1508,12 @@
nstate = sc->sc_ns_state;
arg = sc->sc_ns_arg;
+ if (ostate == IEEE80211_S_INIT) {
+ /* We are leaving INIT. TSF sync should be off. */
+ rum_cfg_disable_tsf_sync(sc);
+ }
switch (nstate) {
case IEEE80211_S_INIT:
- if (ostate == IEEE80211_S_RUN) {
- rum_cfg_disable_tsf_sync(sc);
- }
break;
case IEEE80211_S_RUN:
@@ -1535,14 +1543,17 @@
DPRINTF("setting new state: %d\n", nstate);
+ /* Special case - cannot defer this call and cannot block ! */
+ if (nstate == IEEE80211_S_INIT) {
+ /* stop timers */
+ mtx_lock(&sc->sc_mtx);
+ sc->sc_amrr_timer = 0;
+ mtx_unlock(&sc->sc_mtx);
+ return (uvp->newstate(vap, nstate, arg));
+ }
mtx_lock(&sc->sc_mtx);
if (usb2_config_td_is_gone(&sc->sc_config_td)) {
mtx_unlock(&sc->sc_mtx);
-
- /* Special case which happens at detach. */
- if (nstate == IEEE80211_S_INIT) {
- (uvp->newstate) (vap, nstate, arg);
- }
return (0); /* nothing to do */
}
/* store next state */
@@ -1562,7 +1573,7 @@
mtx_unlock(&sc->sc_mtx);
- return EINPROGRESS;
+ return (EINPROGRESS);
}
static void
@@ -2561,6 +2572,8 @@
struct ieee80211vap *vap;
struct rum_softc *sc = ic->ic_ifp->if_softc;
+ DPRINTF("\n");
+
/* Need to sync with config thread: */
mtx_lock(&sc->sc_mtx);
if (usb2_config_td_sync(&sc->sc_config_td)) {
@@ -2595,7 +2608,17 @@
/* store current operation mode */
ic->ic_opmode = opmode;
- return vap;
+
+#ifdef USB_WLAN_CLONE_FIX
+ /*
+ * Store a copy of the clone name so we can destroy it at
+ * detach!
+ */
+ mtx_lock(&sc->sc_mtx);
+ snprintf(sc->sc_clone, sizeof(sc->sc_clone), "%s%u", name, unit);
+ mtx_unlock(&sc->sc_mtx);
+#endif
+ return (vap);
}
static void
@@ -2604,11 +2627,16 @@
struct rum_vap *rvp = RUM_VAP(vap);
struct rum_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ DPRINTF("\n");
+
/* Need to sync with config thread: */
mtx_lock(&sc->sc_mtx);
if (usb2_config_td_sync(&sc->sc_config_td)) {
/* ignore */
}
+#ifdef USB_WLAN_CLONE_FIX
+ sc->sc_clone[0] = 0; /* clone is gone */
+#endif
mtx_unlock(&sc->sc_mtx);
ieee80211_amrr_cleanup(&rvp->amrr);
==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_rum2_var.h#4 (text+ko) ====
@@ -162,10 +162,14 @@
uint8_t sc_bbp17;
uint8_t sc_hw_radio;
uint8_t sc_amrr_timer;
- uint8_t sc_name[32];
uint8_t sc_beacon_buf[0x800];
uint8_t sc_myaddr[IEEE80211_ADDR_LEN];
int8_t sc_rssi_2ghz_corr;
int8_t sc_rssi_5ghz_corr;
+
+ char sc_name[32];
+#ifdef USB_WLAN_CLONE_FIX
+ char sc_clone[IFNAMSIZ]; /* name of clone */
+#endif
};
==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_ural2.c#14 (text+ko) ====
@@ -495,6 +495,13 @@
struct ieee80211com *ic;
struct ifnet *ifp;
+#ifdef USB_WLAN_CLONE_FIX
+ if (sc->sc_clone[0]) {
+ if (if_clone_destroy(sc->sc_clone)) {
+ DPRINTFN(0, "Could not destroy clone!\n");
+ }
+ }
+#endif
usb2_config_td_drain(&sc->sc_config_td);
mtx_lock(&sc->sc_mtx);
@@ -1492,11 +1499,12 @@
nstate = sc->sc_ns_state;
arg = sc->sc_ns_arg;
+ if (ostate == IEEE80211_S_INIT) {
+ /* We are leaving INIT. TSF sync should be off. */
+ ural_cfg_disable_tsf_sync(sc);
+ }
switch (nstate) {
case IEEE80211_S_INIT:
- if (ostate == IEEE80211_S_RUN) {
- ural_cfg_disable_tsf_sync(sc);
- }
break;
case IEEE80211_S_RUN:
@@ -1518,7 +1526,8 @@
}
static int
-ural_newstate_cb(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
+ural_newstate_cb(struct ieee80211vap *vap,
+ enum ieee80211_state nstate, int arg)
{
struct ural_vap *uvp = URAL_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
@@ -1526,14 +1535,17 @@
DPRINTF("setting new state: %d\n", nstate);
+ /* Special case - cannot defer this call and cannot block ! */
+ if (nstate == IEEE80211_S_INIT) {
+ /* stop timers */
+ mtx_lock(&sc->sc_mtx);
+ sc->sc_amrr_timer = 0;
+ mtx_unlock(&sc->sc_mtx);
+ return (uvp->newstate(vap, nstate, arg));
+ }
mtx_lock(&sc->sc_mtx);
if (usb2_config_td_is_gone(&sc->sc_config_td)) {
mtx_unlock(&sc->sc_mtx);
-
- /* Special case which happens at detach. */
- if (nstate == IEEE80211_S_INIT) {
- (uvp->newstate) (vap, nstate, arg);
- }
return (0); /* nothing to do */
}
/* store next state */
@@ -1553,7 +1565,7 @@
mtx_unlock(&sc->sc_mtx);
- return EINPROGRESS;
+ return (EINPROGRESS);
}
static void
@@ -2388,7 +2400,17 @@
/* store current operation mode */
ic->ic_opmode = opmode;
- return vap;
+
+#ifdef USB_WLAN_CLONE_FIX
+ /*
+ * Store a copy of the clone name so we can destroy it at
+ * detach!
+ */
+ mtx_lock(&sc->sc_mtx);
+ snprintf(sc->sc_clone, sizeof(sc->sc_clone), "%s%u", name, unit);
+ mtx_unlock(&sc->sc_mtx);
+#endif
+ return (vap);
}
static void
@@ -2402,6 +2424,9 @@
if (usb2_config_td_sync(&sc->sc_config_td)) {
/* ignore */
}
+#ifdef USB_WLAN_CLONE_FIX
+ sc->sc_clone[0] = 0; /* clone is gone */
+#endif
mtx_unlock(&sc->sc_mtx);
ieee80211_amrr_cleanup(&uvp->amrr);
==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_ural2_var.h#4 (text+ko) ====
@@ -155,6 +155,10 @@
uint8_t sc_tx_ant;
uint8_t sc_nb_ant;
uint8_t sc_amrr_timer;
- uint8_t sc_name[32];
uint8_t sc_myaddr[IEEE80211_ADDR_LEN];
+
+ char sc_name[32];
+#ifdef USB_WLAN_CLONE_FIX
+ char sc_clone[IFNAMSIZ]; /* name of clone */
+#endif
};
==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2.c#15 (text+ko) ====
@@ -2033,6 +2033,14 @@
struct ieee80211com *ic;
struct ifnet *ifp;
+#ifdef USB_WLAN_CLONE_FIX
+ if (sc->sc_clone[0]) {
+ if (if_clone_destroy(sc->sc_clone)) {
+ DPRINTFN(0, "Could not destroy clone!\n");
+ }
+ }
+#endif
+
usb2_config_td_drain(&sc->sc_config_td);
mtx_lock(&sc->sc_mtx);
@@ -2086,9 +2094,6 @@
switch (nstate) {
case IEEE80211_S_INIT:
- if (ostate == IEEE80211_S_RUN) {
- /* do nothing */
- }
break;
case IEEE80211_S_RUN:
@@ -3037,7 +3042,17 @@
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
ic->ic_opmode = opmode;
- return vap;
+
+#ifdef USB_WLAN_CLONE_FIX
+ /*
+ * Store a copy of the clone name so we can destroy it at
+ * detach!
+ */
+ mtx_lock(&sc->sc_mtx);
+ snprintf(sc->sc_clone, sizeof(sc->sc_clone), "%s%u", name, unit);
+ mtx_unlock(&sc->sc_mtx);
+#endif
+ return (vap);
}
static void
@@ -3051,11 +3066,15 @@
if (usb2_config_td_sync(&sc->sc_config_td)) {
/* ignore */
}
+#ifdef USB_WLAN_CLONE_FIX
+ sc->sc_clone[0] = 0; /* clone is gone */
+#endif
mtx_unlock(&sc->sc_mtx);
ieee80211_amrr_cleanup(&zvp->amrr);
ieee80211_vap_detach(vap);
free(zvp, M_80211_VAP);
+ return;
}
/* ARGUSED */
==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2_reg.h#5 (text+ko) ====
@@ -1274,6 +1274,10 @@
uint8_t sc_amrr_timer;
- uint8_t sc_name[16];
uint8_t sc_myaddr[IEEE80211_ADDR_LEN];
+
+ char sc_name[16];
+#ifdef USB_WLAN_CLONE_FIX
+ char sc_clone[IFNAMSIZ]; /* name of clone */
+#endif
};
==== //depot/projects/usb/src/sys/dev/usb2/wlan/usb2_wlan.h#4 (text+ko) ====
@@ -27,6 +27,13 @@
#ifndef _USB2_WLAN_H_
#define _USB2_WLAN_H_
+/*
+ * XXX: Until further the USB WLAN drivers need to destroy the clones
+ * themselves, because the network layer will not do this. Failing to
+ * destroy the clones will results in panics.
+ */
+#define USB_WLAN_CLONE_FIX
+
#include <sys/param.h>
#include <sys/sockio.h>
#include <sys/mbuf.h>
@@ -40,6 +47,7 @@
#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/if_types.h>
+#include <net/if_clone.h>
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
More information about the p4-projects
mailing list