summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2010-03-15 18:59:10 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2010-03-15 18:59:10 +0000
commit455e8dcce9b0b381da802c383bc89753e338c5cc (patch)
tree18ba1d439f1bf77df046e5a86ed3b162647e6928 /sys
parentd9205c1f635ca1642badf4bcdfd8bf7b1e672877 (diff)
Do not leak mbuf in the TX path when a TX error occurs; found the hard way
by syuu@; ok kettenis@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sgi/dev/if_iec.c30
-rw-r--r--sys/arch/sgi/dev/if_mec.c22
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. */