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