From owner-svn-src-all@FreeBSD.ORG Wed Jun 17 04:15:20 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1C7961065675; Wed, 17 Jun 2009 04:15:20 +0000 (UTC) (envelope-from weongyo@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 0ABC98FC1B; Wed, 17 Jun 2009 04:15:20 +0000 (UTC) (envelope-from weongyo@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n5H4FJdk062183; Wed, 17 Jun 2009 04:15:19 GMT (envelope-from weongyo@svn.freebsd.org) Received: (from weongyo@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n5H4FJpd062181; Wed, 17 Jun 2009 04:15:19 GMT (envelope-from weongyo@svn.freebsd.org) Message-Id: <200906170415.n5H4FJpd062181@svn.freebsd.org> From: Weongyo Jeong Date: Wed, 17 Jun 2009 04:15:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r194329 - head/sys/dev/usb/wlan X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Jun 2009 04:15:20 -0000 Author: weongyo Date: Wed Jun 17 04:15:19 2009 New Revision: 194329 URL: http://svn.freebsd.org/changeset/base/194329 Log: reorders the sequence when the device is detached. After detaching the interface is completed then it'll process other parts to avoid a race condition. Pointed by: jhb Modified: head/sys/dev/usb/wlan/if_uath.c Modified: head/sys/dev/usb/wlan/if_uath.c ============================================================================== --- head/sys/dev/usb/wlan/if_uath.c Wed Jun 17 03:29:00 2009 (r194328) +++ head/sys/dev/usb/wlan/if_uath.c Wed Jun 17 04:15:19 2009 (r194329) @@ -513,14 +513,17 @@ uath_detach(device_t dev) if (!device_is_attached(dev)) return (0); + UATH_LOCK(sc); sc->sc_flags |= UATH_FLAG_INVALID; + UATH_UNLOCK(sc); + + ieee80211_ifdetach(ic); uath_stop(ifp); callout_drain(&sc->stat_ch); callout_drain(&sc->watchdog_ch); usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS); - ieee80211_ifdetach(ic); /* free buffers */ UATH_LOCK(sc); @@ -1857,7 +1860,8 @@ uath_raw_xmit(struct ieee80211_node *ni, struct uath_softc *sc = ifp->if_softc; /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if ((sc->sc_flags & UATH_FLAG_INVALID) || + !(ifp->if_drv_flags & IFF_DRV_RUNNING)) { m_freem(m); ieee80211_free_node(ni); return (ENETDOWN); @@ -1907,6 +1911,11 @@ uath_set_channel(struct ieee80211com *ic struct uath_softc *sc = ifp->if_softc; UATH_LOCK(sc); + if ((sc->sc_flags & UATH_FLAG_INVALID) || + (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + UATH_UNLOCK(sc); + return; + } (void)uath_switch_channel(sc, ic->ic_curchan); UATH_UNLOCK(sc); } @@ -1923,6 +1932,11 @@ uath_update_mcast(struct ifnet *ifp) struct uath_softc *sc = ifp->if_softc; UATH_LOCK(sc); + if ((sc->sc_flags & UATH_FLAG_INVALID) || + (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + UATH_UNLOCK(sc); + return; + } /* * this is for avoiding the race condition when we're try to * connect to the AP with WPA. @@ -1938,6 +1952,11 @@ uath_update_promisc(struct ifnet *ifp) struct uath_softc *sc = ifp->if_softc; UATH_LOCK(sc); + if ((sc->sc_flags & UATH_FLAG_INVALID) || + (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + UATH_UNLOCK(sc); + return; + } if (sc->sc_flags & UATH_FLAG_INITDONE) { uath_set_rxfilter(sc, UATH_FILTER_RX_UCAST | UATH_FILTER_RX_MCAST | @@ -2649,7 +2668,8 @@ uath_data_rxeof(struct usb_xfer *xfer, s } /* there are a lot more fields in the RX descriptor */ - if (ieee80211_radiotap_active(ic)) { + if ((sc->sc_flags & UATH_FLAG_INVALID) == 0 && + ieee80211_radiotap_active(ic)) { struct uath_rx_radiotap_header *tap = &sc->sc_rxtap; uint32_t tsf_hi = be32toh(desc->tstamp_high); uint32_t tsf_lo = be32toh(desc->tstamp_low); @@ -2717,6 +2737,11 @@ setup: * ieee80211_input() because here is at the end of a USB * callback and safe to unlock. */ + if (sc->sc_flags & UATH_FLAG_INVALID) { + if (m != NULL) + m_freem(m); + return; + } UATH_UNLOCK(sc); if (m != NULL && desc != NULL) { wh = mtod(m, struct ieee80211_frame *); @@ -2769,7 +2794,8 @@ uath_data_txeof(struct usb_xfer *xfer, s */ if (data->m) { m = data->m; - if (m->m_flags & M_TXCB) { + if (m->m_flags & M_TXCB && + (sc->sc_flags & UATH_FLAG_INVALID) == 0) { /* XXX status? */ ieee80211_process_callback(data->ni, m, 0); } @@ -2777,7 +2803,8 @@ uath_data_txeof(struct usb_xfer *xfer, s data->m = NULL; } if (data->ni) { - ieee80211_free_node(data->ni); + if ((sc->sc_flags & UATH_FLAG_INVALID) == 0) + ieee80211_free_node(data->ni); data->ni = NULL; } sc->sc_tx_timer = 0; @@ -2831,7 +2858,8 @@ setup: if (data == NULL) goto setup; if (data->ni != NULL) { - ieee80211_free_node(data->ni); + if ((sc->sc_flags & UATH_FLAG_INVALID) == 0) + ieee80211_free_node(data->ni); data->ni = NULL; ifp->if_oerrors++; }