Dug up my old i386 again. This applies cleanly and works fine with some light testing (v4 NFS/ftp, v6 ssh/ftp, basic multicast).
fxp0 at pci2 dev 1 function 0 "Intel 8255x" rev 0x08, i82559: apic 2 int 17 (irq 12), address 00:02:b3:19:8b:4b inphy0 at fxp0 phy 1: i82555 10/100 PHY, rev. 4 Paul 'WEiRD' de Weerd On Thu, Dec 24, 2009 at 02:50:52PM -0500, Brad wrote: | 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. | -- >++++++++[<++++++++++>-]<+++++++.>+++[<------>-]<.>+++[<+ +++++++++++>-]<.>++[<------------>-]<+.--------------.[-] http://www.weirdnet.nl/