summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2006-10-26 22:41:11 +0000
committerBrad Smith <brad@cvs.openbsd.org>2006-10-26 22:41:11 +0000
commite05e71b51d8ff8e7ceb6372363a9bda1a32c63c4 (patch)
tree9334490700fc599c95e41f359d22dc0da74e19ec /sys/dev
parent7820cd6f0b8f30face456a8873ae37efcb8ba322 (diff)
bge_encap():
- Move TX ring full sanity check further up and check the number of DMA segments from the DMA map, instead of counting the DMA segments in the for loop and breaking out later. - Unload the DMA map if encountering an error condition. Tested by brad@ sturm@ wilfried@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_bge.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/sys/dev/pci/if_bge.c b/sys/dev/pci/if_bge.c
index 41f71b66269..359a5e32da0 100644
--- a/sys/dev/pci/if_bge.c
+++ b/sys/dev/pci/if_bge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bge.c,v 1.192 2006/10/25 02:37:50 brad Exp $ */
+/* $OpenBSD: if_bge.c,v 1.193 2006/10/26 22:41:10 brad Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
@@ -2715,6 +2715,7 @@ bge_encap(struct bge_softc *sc, struct mbuf *m_head, u_int32_t *txidx)
#endif
if (!(BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX))
goto doit;
+
/*
* bcm5700 Revision B silicon cannot handle DMA descriptors with
* less than eight bytes. If we encounter a teeny mbuf
@@ -2722,6 +2723,7 @@ bge_encap(struct bge_softc *sc, struct mbuf *m_head, u_int32_t *txidx)
*/
if (bge_compact_dma_runt(m_head) != 0)
return (ENOBUFS);
+
doit:
dma = SLIST_FIRST(&sc->txdma_list);
if (dma == NULL)
@@ -2757,20 +2759,20 @@ doit:
* of the end of the ring.
*/
if ((BGE_TX_RING_CNT - (sc->bge_txcnt + cnt)) < 16)
- return (ENOBUFS);
+ goto fail_unload;
cur = frag;
BGE_INC(frag, BGE_TX_RING_CNT);
cnt++;
}
if (i < dmamap->dm_nsegs)
- return (ENOBUFS);
+ goto fail_unload;
bus_dmamap_sync(sc->bge_dmatag, dmamap, 0, dmamap->dm_mapsize,
BUS_DMASYNC_PREWRITE);
if (frag == sc->bge_tx_saved_considx)
- return (ENOBUFS);
+ goto fail_unload;
sc->bge_rdata->bge_tx_ring[cur].bge_flags |= BGE_TXBDFLAG_END;
sc->bge_cdata.bge_tx_chain[cur] = m_head;
@@ -2781,6 +2783,11 @@ doit:
*txidx = frag;
return (0);
+
+fail_unload:
+ bus_dmamap_unload(sc->bge_dmatag, dmamap);
+
+ return (ENOBUFS);
}
/*