Andrew Thompson wrote:
Author: thompsa
Date: Fri May  8 13:44:33 2009
New Revision: 191912
URL: http://svn.freebsd.org/changeset/base/191912

Log:
  Drain the tasks before the interface stop call in case a restart was queued.

Actually, you have to drain it after if_detach() so you can safely destroy the lock. The proper order should be something like this:

        bpfdetach(ifp);
        ieee80211_ifdetach(ic);

        ipw_stop(sc);

        callout_drain();
        ieee80211_draintask();

        ipw_release(sc);

This is the order other NIC drivers use where they do something like:

        ether_ifdetach(ifp);
        FOO_LOCK(sc);
        foo_stop(sc);           // calls callout_stop()
        FOO_UNLOCK(sc);

        callout_drain();
        taskqueue_drain();      // only if it uses tasks

        if_free();
        mtx_destroy();


Modified:
  head/sys/dev/ipw/if_ipw.c
  head/sys/dev/iwi/if_iwi.c

Modified: head/sys/dev/ipw/if_ipw.c
==============================================================================
--- head/sys/dev/ipw/if_ipw.c   Fri May  8 03:19:57 2009        (r191911)
+++ head/sys/dev/ipw/if_ipw.c   Fri May  8 13:44:33 2009        (r191912)
@@ -404,13 +404,13 @@ ipw_detach(device_t dev)
        struct ifnet *ifp = sc->sc_ifp;
        struct ieee80211com *ic = ifp->if_l2com;
+ ieee80211_draintask(ic, &sc->sc_init_task);
        ipw_stop(sc);
bpfdetach(ifp);
        ieee80211_ifdetach(ic);
callout_drain(&sc->sc_wdtimer);
-       ieee80211_draintask(ic, &sc->sc_init_task);
ipw_release(sc);
Modified: head/sys/dev/iwi/if_iwi.c
==============================================================================
--- head/sys/dev/iwi/if_iwi.c   Fri May  8 03:19:57 2009        (r191911)
+++ head/sys/dev/iwi/if_iwi.c   Fri May  8 13:44:33 2009        (r191912)
@@ -459,17 +459,17 @@ iwi_detach(device_t dev)
        struct ifnet *ifp = sc->sc_ifp;
        struct ieee80211com *ic = ifp->if_l2com;
- iwi_stop(sc);
-
-       bpfdetach(ifp);
-       ieee80211_ifdetach(ic);
-
        /* NB: do early to drain any pending tasks */
        ieee80211_draintask(ic, &sc->sc_radiontask);
        ieee80211_draintask(ic, &sc->sc_radiofftask);
        ieee80211_draintask(ic, &sc->sc_restarttask);
        ieee80211_draintask(ic, &sc->sc_disassoctask);
+ iwi_stop(sc);
+
+       bpfdetach(ifp);
+       ieee80211_ifdetach(ic);
+
        iwi_put_firmware(sc);
        iwi_release_fw_dma(sc);


--
John Baldwin
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to