diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2008-01-21 01:39:26 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2008-01-21 01:39:26 +0000 |
commit | 6f0a2b729e50afe86c0bbe6964fa438a0ca17541 (patch) | |
tree | c72151349d2af6887b54fc9cd62e9537e7edd3f2 /sys/arch/sgi/dev | |
parent | e857c58068679c5342cfc10de033b197151fa293 (diff) |
Fix boot time interrupt storm on mec(4) by disabling DMA when stopping the
interface. Without this we are potentially freeing TX buffers that are in
use, plus we leave DMA enabled when rebooting. This leads to an interrupt
storm at boot time if we were receiving/transmitting network traffic whilst
shutting down.
ok miod@. Tested by jasper@.
Diffstat (limited to 'sys/arch/sgi/dev')
-rw-r--r-- | sys/arch/sgi/dev/if_mec.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/sys/arch/sgi/dev/if_mec.c b/sys/arch/sgi/dev/if_mec.c index b270d5f56d0..ba096a39870 100644 --- a/sys/arch/sgi/dev/if_mec.c +++ b/sys/arch/sgi/dev/if_mec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mec.c,v 1.13 2008/01/20 16:44:03 jsing Exp $ */ +/* $OpenBSD: if_mec.c,v 1.14 2008/01/21 01:39:25 jsing Exp $ */ /* $NetBSD: if_mec_mace.c,v 1.5 2004/08/01 06:36:36 tsutsui Exp $ */ /* @@ -340,7 +340,7 @@ int mec_ioctl(struct ifnet *, u_long, caddr_t); void mec_reset(struct mec_softc *); void mec_setfilter(struct mec_softc *); int mec_intr(void *arg); -void mec_stop(struct ifnet *, int); +void mec_stop(struct ifnet *); void mec_rxintr(struct mec_softc *, uint32_t); void mec_txintr(struct mec_softc *, uint32_t); void mec_shutdown(void *); @@ -643,7 +643,7 @@ mec_init(struct ifnet *ifp) int i; /* Cancel any pending I/O. */ - mec_stop(ifp, 0); + mec_stop(ifp); /* Reset device. */ mec_reset(sc); @@ -1009,7 +1009,7 @@ mec_start(struct ifnet *ifp) } void -mec_stop(struct ifnet *ifp, int disable) +mec_stop(struct ifnet *ifp) { struct mec_softc *sc = ifp->if_softc; struct mec_txsoft *txs; @@ -1023,6 +1023,9 @@ mec_stop(struct ifnet *ifp, int disable) timeout_del(&sc->sc_tick_ch); mii_down(&sc->sc_mii); + /* Disable DMA. */ + bus_space_write_8(sc->sc_st, sc->sc_sh, MEC_DMA_CONTROL, 0); + /* Release any TX buffers. */ for (i = 0; i < MEC_NTXDESC; i++) { txs = &sc->sc_txsoft[i]; @@ -1082,7 +1085,7 @@ mec_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) if (ifp->if_flags & IFF_UP) mec_init(ifp); else if (ifp->if_flags & IFF_RUNNING) - mec_stop(ifp, 1); + mec_stop(ifp); break; case SIOCADDMULTI: @@ -1464,5 +1467,5 @@ mec_shutdown(void *arg) { struct mec_softc *sc = arg; - mec_stop(&sc->sc_ac.ac_if, 1); + mec_stop(&sc->sc_ac.ac_if); } |