aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorTai-hwa Liang <avatar@FreeBSD.org>2007-11-27 08:22:37 +0000
committerTai-hwa Liang <avatar@FreeBSD.org>2007-11-27 08:22:37 +0000
commit93d321a90c1cb078c8b6a8cfda63e4dc2ac063aa (patch)
tree5e3774537abf394a54e51bd49f3b91e4352c56fa /sys/dev
parent78fe41192060658861164621a153e5e9d4e40b55 (diff)
Notes
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/an/if_an.c23
-rw-r--r--sys/dev/an/if_anreg.h2
2 files changed, 14 insertions, 11 deletions
diff --git a/sys/dev/an/if_an.c b/sys/dev/an/if_an.c
index f10f30e95c5b..767305f08e81 100644
--- a/sys/dev/an/if_an.c
+++ b/sys/dev/an/if_an.c
@@ -810,7 +810,7 @@ an_attach(sc, unit, flags)
*/
ether_ifattach(ifp, sc->an_caps.an_oemaddr);
- callout_handle_init(&sc->an_stat_ch);
+ callout_init_mtx(&sc->an_stat_ch, &sc->an_mtx, 0);
return(0);
fail:;
@@ -837,6 +837,7 @@ an_detach(device_t dev)
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
AN_UNLOCK(sc);
ether_ifdetach(ifp);
+ callout_drain(&sc->an_stat_ch);
if_free(ifp);
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
an_release_resources(dev);
@@ -1158,6 +1159,8 @@ an_txeof(sc, status)
* is important because we don't want to allow transmissions until
* the NIC has synchronized to the current cell (either as the master
* in an ad-hoc group, or as a station connected to an access point).
+ *
+ * Note that this function will be called via callout(9) with a lock held.
*/
static void
an_stats_update(xsc)
@@ -1167,12 +1170,13 @@ an_stats_update(xsc)
struct ifnet *ifp;
sc = xsc;
- AN_LOCK(sc);
+ AN_LOCK_ASSERT(sc);
ifp = sc->an_ifp;
sc->an_status.an_type = AN_RID_STATUS;
sc->an_status.an_len = sizeof(struct an_ltv_status);
- an_read_record(sc, (struct an_ltv_gen *)&sc->an_status);
+ if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_status))
+ return;
if (sc->an_status.an_opmode & AN_STATUS_OPMODE_IN_SYNC)
sc->an_associated = 1;
@@ -1181,17 +1185,16 @@ an_stats_update(xsc)
/* Don't do this while we're transmitting */
if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
- sc->an_stat_ch = timeout(an_stats_update, sc, hz);
- AN_UNLOCK(sc);
+ callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
return;
}
sc->an_stats.an_len = sizeof(struct an_ltv_stats);
sc->an_stats.an_type = AN_RID_32BITS_CUM;
- an_read_record(sc, (struct an_ltv_gen *)&sc->an_stats.an_len);
+ if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_stats.an_len))
+ return;
- sc->an_stat_ch = timeout(an_stats_update, sc, hz);
- AN_UNLOCK(sc);
+ callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
return;
}
@@ -2634,7 +2637,7 @@ an_init(xsc)
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- sc->an_stat_ch = timeout(an_stats_update, sc, hz);
+ callout_reset(&sc->an_stat_ch, hz, an_stats_update, sc);
AN_UNLOCK(sc);
return;
@@ -2849,7 +2852,7 @@ an_stop(sc)
for (i = 0; i < AN_TX_RING_CNT; i++)
an_cmd(sc, AN_CMD_DEALLOC_MEM, sc->an_rdata.an_tx_fids[i]);
- untimeout(an_stats_update, sc, sc->an_stat_ch);
+ callout_stop(&sc->an_stat_ch);
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING|IFF_DRV_OACTIVE);
diff --git a/sys/dev/an/if_anreg.h b/sys/dev/an/if_anreg.h
index 44a702af7642..0a96ee30f3f0 100644
--- a/sys/dev/an/if_anreg.h
+++ b/sys/dev/an/if_anreg.h
@@ -485,7 +485,7 @@ struct an_softc {
int an_have_rssimap;
struct an_ltv_rssi_map an_rssimap;
#endif
- struct callout_handle an_stat_ch;
+ struct callout an_stat_ch;
struct mtx an_mtx;
device_t an_dev;
struct ifmedia an_ifmedia;