Date: Sat, 20 Sep 2008 17:28:51 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 150171 for review Message-ID: <200809201728.m8KHSphW072094@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=150171 Change 150171 by hselasky@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>
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200809201728.m8KHSphW072094>