Index: if_ndis.c =================================================================== RCS file: /home/cvs/src/sys/dev/if_ndis/if_ndis.c,v retrieving revision 1.171 diff -u -r1.171 if_ndis.c --- if_ndis.c 2 Nov 2009 11:07:42 -0000 1.171 +++ if_ndis.c 17 Nov 2009 15:37:59 -0000 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -170,7 +171,8 @@ int); static int ndis_nettype_chan (uint32_t); static int ndis_nettype_mode (uint32_t); -static void ndis_scan (void *); +static void ndis_scan (void *, int); +static void ndis_scan_schedule (void *); static void ndis_scan_results (struct ndis_softc *); static void ndis_scan_start (struct ieee80211com *); static void ndis_scan_end (struct ieee80211com *); @@ -556,7 +558,7 @@ InitializeListHead(&sc->ndis_shlist); InitializeListHead(&sc->ndisusb_tasklist); InitializeListHead(&sc->ndisusb_xferdonelist); - callout_init(&sc->ndis_stat_callout, CALLOUT_MPSAFE); + callout_init_mtx(&sc->ndis_stat_callout, &sc->ndis_mtx, 0); if (sc->ndis_iftype == PCMCIABus) { error = ndis_alloc_amem(sc); @@ -734,6 +736,7 @@ int r; callout_init(&sc->ndis_scan_callout, CALLOUT_MPSAFE); + TASK_INIT(&sc->ndis_scan_task, 0, ndis_scan, sc); ifp->if_ioctl = ndis_ioctl_80211; ic->ic_ifp = ifp; @@ -1011,6 +1014,7 @@ ndis_stop(sc); callout_drain(&sc->ndis_scan_callout); + taskqueue_drain(taskqueue_thread, &sc->ndis_scan_task); ieee80211_vap_detach(vap); free(nvp, M_80211_VAP); } @@ -1031,13 +1035,9 @@ driver_object *drv; sc = device_get_softc(dev); - NDIS_LOCK(sc); ifp = sc->ifp; - if (ifp != NULL) - ifp->if_flags &= ~IFF_UP; if (device_is_attached(dev)) { - NDIS_UNLOCK(sc); ndis_stop(sc); if (ifp != NULL) { if (sc->ndis_80211) @@ -1045,9 +1045,9 @@ else ether_ifdetach(ifp); } - } else - NDIS_UNLOCK(sc); + } + callout_drain(&sc->ndis_stat_callout); if (sc->ndis_tickitem != NULL) IoFreeWorkItem(sc->ndis_tickitem); if (sc->ndis_startitem != NULL) @@ -1656,6 +1656,7 @@ struct ndis_softc *sc; sc = xsc; + NDIS_LOCK_ASSERT(sc, MA_OWNED); if (sc->ndis_hang_timer && --sc->ndis_hang_timer == 0) { IoQueueWorkItem(sc->ndis_tickitem, @@ -3136,9 +3137,9 @@ int i; ifp = sc->ifp; - callout_drain(&sc->ndis_stat_callout); NDIS_LOCK(sc); + callout_stop(&sc->ndis_stat_callout); sc->ndis_tx_timer = 0; sc->ndis_link = 0; ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); @@ -3220,7 +3221,15 @@ } static void -ndis_scan(void *arg) +ndis_scan_schedule(void *arg) +{ + struct ndis_softc *sc = arg; + + taskqueue_enqueue(taskqueue_thread, &sc->ndis_scan_task); +} + +static void +ndis_scan(void *arg, int pending) { struct ndis_softc *sc = arg; struct ieee80211com *ic; @@ -3377,7 +3386,7 @@ return; } /* Set a timer to collect the results */ - callout_reset(&sc->ndis_scan_callout, hz * 3, ndis_scan, sc); + callout_reset(&sc->ndis_scan_callout, hz * 3, ndis_scan_schedule, sc); } static void Index: if_ndisvar.h =================================================================== RCS file: /home/cvs/src/sys/dev/if_ndis/if_ndisvar.h,v retrieving revision 1.41 diff -u -r1.41 if_ndisvar.h --- if_ndisvar.h 29 May 2009 18:46:57 -0000 1.41 +++ if_ndisvar.h 27 Sep 2009 21:34:49 -0000 @@ -180,6 +180,7 @@ ndis_miniport_block *ndis_block; ndis_miniport_characteristics *ndis_chars; interface_type ndis_type; + struct task ndis_scan_task; struct callout ndis_scan_callout; struct callout ndis_stat_callout; int ndis_maxpkts;