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


Index: aic6915.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/aic6915.c,v
retrieving revision 1.9
diff -u -p -r1.9 aic6915.c
--- aic6915.c   10 Aug 2009 20:29:54 -0000      1.9
+++ aic6915.c   24 Dec 2009 19:43:37 -0000
@@ -343,7 +343,7 @@ void
 sf_start(struct ifnet *ifp)
 {
        struct sf_softc *sc = ifp->if_softc;
-       struct mbuf *m0, *m;
+       struct mbuf *m0;
        struct sf_txdesc0 *txd;
        struct sf_descsoft *ds;
        bus_dmamap_t dmamap;
@@ -373,7 +373,6 @@ sf_start(struct ifnet *ifp)
                IFQ_POLL(&ifp->if_snd, m0);
                if (m0 == NULL)
                        break;
-               m = NULL;
 
                /*
                 * Get the transmit descriptor.
@@ -390,40 +389,18 @@ sf_start(struct ifnet *ifp)
                 */
                if (bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
                    BUS_DMA_WRITE|BUS_DMA_NOWAIT) != 0) {
-                       MGETHDR(m, M_DONTWAIT, MT_DATA);
-                       if (m == NULL) {
-                               printf("%s: unable to allocate Tx mbuf\n",
-                                   sc->sc_dev.dv_xname);
+                       if (m_defrag(m0, M_DONTWAIT))
                                break;
-                       }
-                       if (m0->m_pkthdr.len > MHLEN) {
-                               MCLGET(m, M_DONTWAIT);
-                               if ((m->m_flags & M_EXT) == 0) {
-                                       printf("%s: unable to allocate Tx "
-                                           "cluster\n", sc->sc_dev.dv_xname);
-                                       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;
                        error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap,
-                           m, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
-                       if (error) {
-                               printf("%s: unable to load Tx buffer, "
-                                   "error = %d\n", sc->sc_dev.dv_xname, error);
+                           m0, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
+                       if (error)
                                break;
-                       }
                }
 
                /*
                 * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET.
                 */
                IFQ_DEQUEUE(&ifp->if_snd, m0);
-               if (m != NULL) {
-                       m_freem(m0);
-                       m0 = m;
-               }
 
                /* Initialize the descriptor. */
                txd->td_word0 =

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

Reply via email to