The following diff replaces the hand rolled code to deal with
really long mbuf chains with the use of m_defrag().


Index: fxp.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/fxp.c,v
retrieving revision 1.100
diff -u -p -r1.100 fxp.c
--- fxp.c       15 Oct 2009 17:54:54 -0000      1.100
+++ fxp.c       24 Dec 2009 19:40:44 -0000
@@ -678,8 +678,8 @@ fxp_start(struct ifnet *ifp)
        struct fxp_softc *sc = ifp->if_softc;
        struct fxp_txsw *txs = sc->sc_cbt_prod;
        struct fxp_cb_tx *txc;
-       struct mbuf *m0, *m = NULL;
-       int cnt = sc->sc_cbt_cnt, seg;
+       struct mbuf *m0;
+       int cnt = sc->sc_cbt_cnt, seg, error;
 
        if ((ifp->if_flags & (IFF_OACTIVE | IFF_RUNNING)) != IFF_RUNNING)
                return;
@@ -696,33 +696,22 @@ fxp_start(struct ifnet *ifp)
                if (m0 == NULL)
                        break;
 
-               if (bus_dmamap_load_mbuf(sc->sc_dmat, txs->tx_map,
-                   m0, BUS_DMA_NOWAIT) != 0) {
-                       MGETHDR(m, M_DONTWAIT, MT_DATA);
-                       if (m == NULL)
+               error = bus_dmamap_load_mbuf(sc->sc_dmat, txs->tx_map,
+                   m0, BUS_DMA_NOWAIT);
+               if (error != 0 && error != EFBIG)
+                       break;
+               if (error != 0) {
+                       if (m_defrag(m0, M_DONTWAIT))
                                break;
-                       if (m0->m_pkthdr.len > MHLEN) {
-                               MCLGET(m, M_DONTWAIT);
-                               if (!(m->m_flags & M_EXT)) {
-                                       m_freem(m);
-                                       break;
-                               }
-                       }
-                       m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
-                       m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
                        if (bus_dmamap_load_mbuf(sc->sc_dmat, txs->tx_map,
-                           m, BUS_DMA_NOWAIT) != 0) {
-                               m_freem(m);
+                           m0, BUS_DMA_NOWAIT) != 0)
                                break;
-                       }
                }
 
+               /*
+                * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET. 
+                */
                IFQ_DEQUEUE(&ifp->if_snd, m0);
-               if (m != NULL) {
-                       m_freem(m0);
-                       m0 = m;
-                       m = NULL;
-               }
 
                txs->tx_mbuf = m0;
 

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

Reply via email to