summaryrefslogtreecommitdiffstats
path: root/sys/pci/if_xl.c
diff options
context:
space:
mode:
authormux <mux@FreeBSD.org>2003-01-07 01:01:20 +0000
committermux <mux@FreeBSD.org>2003-01-07 01:01:20 +0000
commit33c32074e66c524b687bf1ac1c122c8371116ad6 (patch)
tree4da0f7b06d0077fcb0fab6da2a0844bf723dc122 /sys/pci/if_xl.c
parentf35cb3a504b5968f3b257944a0edda784a0da4fb (diff)
downloadFreeBSD-src-33c32074e66c524b687bf1ac1c122c8371116ad6.zip
FreeBSD-src-33c32074e66c524b687bf1ac1c122c8371116ad6.tar.gz
o Only try to recopy the mbuf into an mbuf cluster if
bus_dmamap_load_mbuf() returned EFBIG. o Fix mbuf leaks in an error (rare) code path. o Reuse the TX descriptor if xl_encap() failed instead of just picking the next one. o Better error messages.
Diffstat (limited to 'sys/pci/if_xl.c')
-rw-r--r--sys/pci/if_xl.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/sys/pci/if_xl.c b/sys/pci/if_xl.c
index f82fb44..cc0e275 100644
--- a/sys/pci/if_xl.c
+++ b/sys/pci/if_xl.c
@@ -1944,7 +1944,7 @@ xl_newbuf(sc, c)
MCLBYTES, xl_dma_map_addr, &c->xl_ptr->xl_frag.xl_addr, 0);
if (error) {
m_freem(m_new);
- printf("xl%d: can't map mbuf\n", sc->xl_unit);
+ printf("xl%d: can't map mbuf (error %d)\n", sc->xl_unit, error);
return(error);
}
bus_dmamap_sync(sc->xl_mtag, c->xl_map, BUS_DMASYNC_PREWRITE);
@@ -2386,10 +2386,15 @@ xl_encap(sc, c, m_head)
* the fragment pointers. Stop when we run out
* of fragments or hit the end of the mbuf chain.
*/
-
error = bus_dmamap_load_mbuf(sc->xl_mtag, c->xl_map, m_head,
xl_dma_map_txbuf, c->xl_ptr, 0);
+ if (error && error != EFBIG) {
+ m_freem(m_head);
+ printf("xl%d: can't map mbuf (error %d)\n", sc->xl_unit, error);
+ return(1);
+ }
+
/*
* Handle special case: we used up all 63 fragments,
* but we have more mbufs left in the chain. Copy the
@@ -2398,15 +2403,12 @@ xl_encap(sc, c, m_head)
* pointers/counters; it wouldn't gain us anything,
* and would waste cycles.
*/
- /*
- * XXX It's not really possible to tell if the error
- * we got was because we had more than 63 mbufs.
- */
if (error) {
struct mbuf *m_new = NULL;
MGETHDR(m_new, M_DONTWAIT, MT_DATA);
if (m_new == NULL) {
+ m_freem(m_head);
printf("xl%d: no memory for tx list\n", sc->xl_unit);
return(1);
}
@@ -2414,6 +2416,7 @@ xl_encap(sc, c, m_head)
MCLGET(m_new, M_DONTWAIT);
if (!(m_new->m_flags & M_EXT)) {
m_freem(m_new);
+ m_freem(m_head);
printf("xl%d: no memory for tx list\n",
sc->xl_unit);
return(1);
@@ -2430,7 +2433,8 @@ xl_encap(sc, c, m_head)
&f->xl_addr, 0);
if (error) {
m_freem(m_new);
- printf("xl%d: can't map mbuf\n", sc->xl_unit);
+ printf("xl%d: can't map mbuf (error %d)\n",
+ sc->xl_unit, error);
return(1);
}
f->xl_len = m_new->m_len | XL_LAST_FRAG;
@@ -2469,6 +2473,7 @@ xl_start(ifp)
struct xl_softc *sc;
struct mbuf *m_head = NULL;
struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx;
+ int error;
sc = ifp->if_softc;
XL_LOCK(sc);
@@ -2495,12 +2500,14 @@ xl_start(ifp)
/* Pick a descriptor off the free list. */
cur_tx = sc->xl_cdata.xl_tx_free;
- sc->xl_cdata.xl_tx_free = cur_tx->xl_next;
-
- cur_tx->xl_next = NULL;
/* Pack the data into the descriptor. */
- xl_encap(sc, cur_tx, m_head);
+ error = xl_encap(sc, cur_tx, m_head);
+ if (error)
+ continue;
+
+ sc->xl_cdata.xl_tx_free = cur_tx->xl_next;
+ cur_tx->xl_next = NULL;
/* Chain it together. */
if (prev != NULL) {
@@ -2591,7 +2598,7 @@ xl_start_90xB(ifp)
struct xl_softc *sc;
struct mbuf *m_head = NULL;
struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx;
- int idx;
+ int error, idx;
sc = ifp->if_softc;
XL_LOCK(sc);
@@ -2618,7 +2625,9 @@ xl_start_90xB(ifp)
cur_tx = &sc->xl_cdata.xl_tx_chain[idx];
/* Pack the data into the descriptor. */
- xl_encap(sc, cur_tx, m_head);
+ error = xl_encap(sc, cur_tx, m_head);
+ if (error)
+ continue;
/* Chain it together. */
if (prev != NULL)
OpenPOWER on IntegriCloud