diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2010-03-15 18:59:10 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2010-03-15 18:59:10 +0000 |
commit | 455e8dcce9b0b381da802c383bc89753e338c5cc (patch) | |
tree | 18ba1d439f1bf77df046e5a86ed3b162647e6928 | |
parent | d9205c1f635ca1642badf4bcdfd8bf7b1e672877 (diff) |
Do not leak mbuf in the TX path when a TX error occurs; found the hard way
by syuu@; ok kettenis@
-rw-r--r-- | sys/arch/sgi/dev/if_iec.c | 30 | ||||
-rw-r--r-- | sys/arch/sgi/dev/if_mec.c | 22 |
2 files changed, 25 insertions, 27 deletions
diff --git a/sys/arch/sgi/dev/if_iec.c b/sys/arch/sgi/dev/if_iec.c index 8e461770772..11b2b4a5d47 100644 --- a/sys/arch/sgi/dev/if_iec.c +++ b/sys/arch/sgi/dev/if_iec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iec.c,v 1.6 2009/11/08 13:11:17 miod Exp $ */ +/* $OpenBSD: if_iec.c,v 1.7 2010/03/15 18:59:09 miod Exp $ */ /* * Copyright (c) 2009 Miodrag Vallat. @@ -1354,6 +1354,15 @@ iec_txintr(struct iec_softc *sc, uint32_t stat) once = 0; for (i = sc->sc_txdirty; i != last && sc->sc_txpending != 0; i = IEC_NEXTTX(i), sc->sc_txpending--) { + txs = &sc->sc_txsoft[i]; + if ((txs->txs_flags & IEC_TXCMD_PTR0_V) != 0) { + dmamap = txs->txs_dmamap; + bus_dmamap_sync(sc->sc_dmat, dmamap, 0, + dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->sc_dmat, dmamap); + m_freem(txs->txs_mbuf); + txs->txs_mbuf = NULL; + } if ((stat & IOC3_ENET_ISR_TX_EXPLICIT) == 0) { if (stat == IOC3_ENET_ISR_TX_EMPTY) @@ -1364,22 +1373,11 @@ iec_txintr(struct iec_softc *sc, uint32_t stat) once = 1; } ifp->if_oerrors++; - continue; - } - - txs = &sc->sc_txsoft[i]; - if ((txs->txs_flags & IEC_TXCMD_PTR0_V) != 0) { - dmamap = txs->txs_dmamap; - bus_dmamap_sync(sc->sc_dmat, dmamap, 0, - dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->sc_dmat, dmamap); - m_freem(txs->txs_mbuf); - txs->txs_mbuf = NULL; + } else { + ifp->if_collisions += IOC3_ENET_TCDC_COLLISION_MASK & + bus_space_read_4(st, sh, IOC3_ENET_TCDC); + ifp->if_opackets++; } - - ifp->if_collisions += bus_space_read_4(st, sh, IOC3_ENET_TCDC) & - IOC3_ENET_TCDC_COLLISION_MASK; - ifp->if_opackets++; } /* Update the dirty TX buffer pointer. */ diff --git a/sys/arch/sgi/dev/if_mec.c b/sys/arch/sgi/dev/if_mec.c index c7075dc0e2d..c069c5a5df7 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.22 2009/10/26 18:00:06 miod Exp $ */ +/* $OpenBSD: if_mec.c,v 1.23 2010/03/15 18:59:09 miod Exp $ */ /* $NetBSD: if_mec_mace.c,v 1.5 2004/08/01 06:36:36 tsutsui Exp $ */ /* @@ -1376,13 +1376,6 @@ mec_txintr(struct mec_softc *sc, uint32_t stat) break; } - if ((txstat & MEC_TXSTAT_SUCCESS) == 0) { - printf("%s: TX error: txstat = 0x%llx\n", - sc->sc_dev.dv_xname, txstat); - ifp->if_oerrors++; - continue; - } - txs = &sc->sc_txsoft[i]; if ((txs->txs_flags & MEC_TXS_TXDPTR1) != 0) { dmamap = txs->txs_dmamap; @@ -1393,9 +1386,16 @@ mec_txintr(struct mec_softc *sc, uint32_t stat) txs->txs_mbuf = NULL; } - col = (txstat & MEC_TXSTAT_COLCNT) >> MEC_TXSTAT_COLCNT_SHIFT; - ifp->if_collisions += col; - ifp->if_opackets++; + if ((txstat & MEC_TXSTAT_SUCCESS) == 0) { + printf("%s: TX error: txstat = 0x%llx\n", + sc->sc_dev.dv_xname, txstat); + ifp->if_oerrors++; + } else { + col = (txstat & MEC_TXSTAT_COLCNT) >> + MEC_TXSTAT_COLCNT_SHIFT; + ifp->if_collisions += col; + ifp->if_opackets++; + } } /* Update the dirty TX buffer pointer. */ |