diff options
author | jhb <jhb@FreeBSD.org> | 2006-10-31 17:05:02 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2006-10-31 17:05:02 +0000 |
commit | 9f9db205d0af3a7b7cb824059ead004677127664 (patch) | |
tree | 0bb2b6eab3a31fbbe1d0a239209d776357abbca8 /sys/dev | |
parent | e4a98dda3af452e3fec170247ad9853b29acd86d (diff) | |
download | FreeBSD-src-9f9db205d0af3a7b7cb824059ead004677127664.zip FreeBSD-src-9f9db205d0af3a7b7cb824059ead004677127664.tar.gz |
- Use callout_init_mtx() to close various callout-related races.
- Drain the two timers in detach.
- Check IFF_DRV_RUNNING in the link task and bail w/o doing anything if
it is clear.
Reviewed by: jfv, scottl
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/em/if_em.c | 31 |
1 files changed, 13 insertions, 18 deletions
diff --git a/sys/dev/em/if_em.c b/sys/dev/em/if_em.c index 803341e..2afb5e4 100644 --- a/sys/dev/em/if_em.c +++ b/sys/dev/em/if_em.c @@ -255,7 +255,6 @@ static int em_82547_fifo_workaround(struct adapter *, int); static void em_82547_update_fifo_head(struct adapter *, int); static int em_82547_tx_fifo_reset(struct adapter *); static void em_82547_move_tail(void *arg); -static void em_82547_move_tail_locked(struct adapter *); static int em_dma_malloc(struct adapter *, bus_size_t, struct em_dma_alloc *, int); static void em_dma_free(struct adapter *, struct em_dma_alloc *); @@ -421,8 +420,8 @@ em_attach(device_t dev) OID_AUTO, "stats", CTLTYPE_INT|CTLFLAG_RW, adapter, 0, em_sysctl_stats, "I", "Statistics"); - callout_init(&adapter->timer, CALLOUT_MPSAFE); - callout_init(&adapter->tx_fifo_timer, CALLOUT_MPSAFE); + callout_init_mtx(&adapter->timer, &adapter->mtx, 0); + callout_init_mtx(&adapter->tx_fifo_timer, &adapter->mtx, 0); /* Determine hardware revision */ em_identify_hardware(adapter); @@ -628,6 +627,9 @@ em_detach(device_t dev) EM_UNLOCK(adapter); ether_ifdetach(adapter->ifp); + callout_drain(&adapter->timer); + callout_drain(&adapter->tx_fifo_timer); + em_free_pci_resources(adapter); bus_generic_detach(dev); if_free(ifp); @@ -1249,6 +1251,10 @@ em_handle_link(void *context, int pending) ifp = adapter->ifp; EM_LOCK(adapter); + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + EM_UNLOCK(adapter); + return; + } callout_stop(&adapter->timer); adapter->hw.get_link_status = 1; @@ -1765,7 +1771,7 @@ em_encap(struct adapter *adapter, struct mbuf **m_headp) if (adapter->hw.mac_type == em_82547 && adapter->link_duplex == HALF_DUPLEX) - em_82547_move_tail_locked(adapter); + em_82547_move_tail(adapter); else { E1000_WRITE_REG(&adapter->hw, TDT, i); if (adapter->hw.mac_type == em_82547) @@ -1784,8 +1790,9 @@ em_encap(struct adapter *adapter, struct mbuf **m_headp) * **********************************************************************/ static void -em_82547_move_tail_locked(struct adapter *adapter) +em_82547_move_tail(void *arg) { + struct adapter *adapter = arg; uint16_t hw_tdt; uint16_t sw_tdt; struct em_tx_desc *tx_desc; @@ -1818,16 +1825,6 @@ em_82547_move_tail_locked(struct adapter *adapter) } } -static void -em_82547_move_tail(void *arg) -{ - struct adapter *adapter = arg; - - EM_LOCK(adapter); - em_82547_move_tail_locked(adapter); - EM_UNLOCK(adapter); -} - static int em_82547_fifo_workaround(struct adapter *adapter, int len) { @@ -2016,7 +2013,7 @@ em_local_timer(void *arg) struct adapter *adapter = arg; struct ifnet *ifp = adapter->ifp; - EM_LOCK(adapter); + EM_LOCK_ASSERT(adapter); em_check_for_link(&adapter->hw); em_update_link_status(adapter); @@ -2026,8 +2023,6 @@ em_local_timer(void *arg) em_smartspeed(adapter); callout_reset(&adapter->timer, hz, em_local_timer, adapter); - - EM_UNLOCK(adapter); } static void |