diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index 993f9a2..06d1162 100644 --- sys/dev/if_ndis/if_ndis.c +++ sys/dev/if_ndis/if_ndis.c @@ -161,7 +161,7 @@ static void ndis_scan_curchan (struct ieee80211_scan_state *, unsigned long); static void ndis_scan_mindwell (struct ieee80211_scan_state *); static void ndis_init (void *); static void ndis_stop (struct ndis_softc *); -static void ndis_watchdog (struct ifnet *); +static void ndis_watchdog (void *); static int ndis_ifmedia_upd (struct ifnet *); static void ndis_ifmedia_sts (struct ifnet *, struct ifmediareq *); static void ndis_auth (void *, int); @@ -690,12 +690,14 @@ ndis_attach(dev) /* Check for task offload support. */ ndis_probe_offload(sc); + /* Initialize the Watchdog callout. */ + callout_init(&sc->ndis_timer, CALLOUT_MPSAFE); + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_mtu = ETHERMTU; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = ndis_ioctl; ifp->if_start = ndis_start; - ifp->if_watchdog = ndis_watchdog; ifp->if_init = ndis_init; ifp->if_baudrate = 10000000; IFQ_SET_MAXLEN(&ifp->if_snd, 50); @@ -994,6 +996,7 @@ ndis_detach(dev) driver_object *drv; sc = device_get_softc(dev); + NDIS_LOCK(sc); ifp = sc->ifp; ifp->if_flags &= ~IFF_UP; @@ -1008,6 +1011,9 @@ ndis_detach(dev) } else NDIS_UNLOCK(sc); + /* Remove any pending callouts. */ + callout_drain(&sc->ndis_timer); + if (sc->ndis_80211) { taskqueue_drain(sc->ndis_tq, &sc->ndis_scantask); taskqueue_drain(sc->ndis_tq, &sc->ndis_authtask); @@ -1540,7 +1546,7 @@ ndis_txeof(adapter, packet, status) else ifp->if_oerrors++; - ifp->if_timer = 0; + callout_stop(&sc->ndis_timer); ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; NDIS_UNLOCK(sc); @@ -1888,7 +1894,7 @@ ndis_start(ifp) /* * Set a timeout in case the chip goes out to lunch. */ - ifp->if_timer = 5; + callout_reset(&sc->ndis_timer, 5 * hz, ndis_watchdog, sc); NDIS_UNLOCK(sc); @@ -3113,15 +3119,12 @@ ndis_resettask(d, arg) } static void -ndis_watchdog(ifp) - struct ifnet *ifp; +ndis_watchdog (void *arg) { - struct ndis_softc *sc; - - sc = ifp->if_softc; + struct ndis_softc *sc = arg; NDIS_LOCK(sc); - ifp->if_oerrors++; + sc->ifp->if_oerrors++; device_printf(sc->ndis_dev, "watchdog timeout\n"); NDIS_UNLOCK(sc); @@ -3130,7 +3133,7 @@ ndis_watchdog(ifp) WORKQUEUE_CRITICAL, sc); IoQueueWorkItem(sc->ndis_startitem, (io_workitem_func)ndis_starttask_wrap, - WORKQUEUE_CRITICAL, ifp); + WORKQUEUE_CRITICAL, sc->ifp); return; } @@ -3150,7 +3153,7 @@ ndis_stop(sc) callout_drain(&sc->ndis_stat_callout); NDIS_LOCK(sc); - ifp->if_timer = 0; + callout_stop(&sc->ndis_timer); sc->ndis_link = 0; ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); NDIS_UNLOCK(sc); diff --git a/sys/dev/if_ndis/if_ndisvar.h b/sys/dev/if_ndis/if_ndisvar.h index bf4f056..be8bf0a 100644 --- sys/dev/if_ndis/if_ndisvar.h +++ sys/dev/if_ndis/if_ndisvar.h @@ -181,6 +181,7 @@ struct ndis_softc { struct task ndis_assoctask; int (*ndis_newstate)(struct ieee80211com *, enum ieee80211_state, int); + struct callout ndis_timer; }; #define NDIS_LOCK(_sc) KeAcquireSpinLock(&(_sc)->ndis_spinlock, \