Hi,

This diff makes the pcn driver use m_defrag for fragmented mbuf chains,

cheers,
Kim

Index: if_pcn.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_pcn.c,v
retrieving revision 1.36
diff -u -p -r1.36 if_pcn.c
--- if_pcn.c    14 Mar 2015 03:38:48 -0000      1.36
+++ if_pcn.c    27 Mar 2015 12:17:24 -0000
@@ -851,25 +851,23 @@ pcn_start(struct ifnet *ifp)
                 * were short on resources.  In this case, we'll copy
                 * and try again.
                 */
-               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)
-                               break;
-                       if (m0->m_pkthdr.len > MHLEN) {
-                               MCLGET(m, M_DONTWAIT);
-                               if ((m->m_flags & M_EXT) == 0) {
-                                       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)
-                               break;
-               }
+                error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
+                    BUS_DMA_WRITE|BUS_DMA_NOWAIT);
+                switch (error) {
+                case 0:
+                        break; 
+                case EFBIG:
+                        if ((error = m_defrag(m0, M_DONTWAIT)) == 0 &&
+                            (error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap,
+                             m0, BUS_DMA_WRITE|BUS_DMA_NOWAIT)) == 0)
+                                break;
+
+                        /* FALLTHROUGH */
+                default:
+                       IFQ_DEQUEUE(&ifp->if_snd, m0);
+                       m_freem(m);
+                       continue;
+                }
 
                /*
                 * Ensure we have enough descriptors free to describe

Reply via email to