diff options
author | oleg <oleg@FreeBSD.org> | 2006-12-19 08:57:46 +0000 |
---|---|---|
committer | oleg <oleg@FreeBSD.org> | 2006-12-19 08:57:46 +0000 |
commit | 5ce6905b904d4519790b59520e6592e4eaa3910d (patch) | |
tree | 95935e77876c58271573b075203c49e1b3425544 /sys/dev | |
parent | 967a981a72e6c247291631c0ba88111fd72dd0bb (diff) | |
download | FreeBSD-src-5ce6905b904d4519790b59520e6592e4eaa3910d.zip FreeBSD-src-5ce6905b904d4519790b59520e6592e4eaa3910d.tar.gz |
- Add missing callout_drain() call.
- Synchronize bge_tick() with callout_reset/callout_stop() calls.
- Avoid using bge_tick() inside bge_link_upd(), use mii_pollstat() instead.
MFC after: 2 month
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/bge/if_bge.c | 22 |
1 files changed, 10 insertions, 12 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 2bae618..1035083 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -2482,6 +2482,8 @@ bge_detach(device_t dev) bge_reset(sc); BGE_UNLOCK(sc); + callout_drain(&sc->bge_stat_ch); + ether_ifdetach(ifp); if (sc->bge_flags & BGE_FLAG_TBI) { @@ -3045,6 +3047,11 @@ bge_tick(void *xsc) BGE_LOCK_ASSERT(sc); + /* Synchronize with possible callout reset/stop. */ + if (callout_pending(&sc->bge_stat_ch) || + !callout_active(&sc->bge_stat_ch)) + return; + if (BGE_IS_5705_PLUS(sc)) bge_stats_update_regs(sc); else @@ -3870,12 +3877,7 @@ bge_stop(struct bge_softc *sc) sc->bge_tx_saved_considx = BGE_TXCONS_UNSET; - /* - * We can't just call bge_link_upd() cause chip is almost stopped so - * bge_link_upd -> bge_tick_locked -> bge_stats_update sequence may - * lead to hardware deadlock. So we just clearing MAC's link state - * (PHY may still have link UP). - */ + /* Clear MAC's link state (PHY may still have link UP). */ if (bootverbose && sc->bge_link) if_printf(sc->bge_ifp, "link DOWN\n"); sc->bge_link = 0; @@ -3962,10 +3964,8 @@ bge_link_upd(struct bge_softc *sc) sc->bge_chipid != BGE_CHIPID_BCM5700_B2) { status = CSR_READ_4(sc, BGE_MAC_STS); if (status & BGE_MACSTAT_MI_INTERRUPT) { - callout_stop(&sc->bge_stat_ch); - bge_tick(sc); - mii = device_get_softc(sc->bge_miibus); + mii_pollstat(mii); if (!sc->bge_link && mii->mii_media_status & IFM_ACTIVE && IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { @@ -4021,10 +4021,8 @@ bge_link_upd(struct bge_softc *sc) if (link != sc->bge_link || sc->bge_asicrev == BGE_ASICREV_BCM5700) { - callout_stop(&sc->bge_stat_ch); - bge_tick(sc); - mii = device_get_softc(sc->bge_miibus); + mii_pollstat(mii); if (!sc->bge_link && mii->mii_media_status & IFM_ACTIVE && IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { |