While digging for old fxp's and xl's I came across something I should've buried a long time ago: a pcn(4) (10Mbit only, with a 10base2 connector !).
I tried the patch below, same tests (they just took a bit longer). Everything works just fine, no regressions. pcn0 at pci2 dev 1 function 0 "AMD 79c970 PCnet-PCI" rev 0x02, Am79c970, rev 1: apic 2 int 17 (irq 12), address 02:07:01:1b:b4:ac Paul 'WEiRD' de Weerd On Thu, Dec 24, 2009 at 03:15:10PM -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: if_pcn.c | =================================================================== | RCS file: /cvs/src/sys/dev/pci/if_pcn.c,v | retrieving revision 1.22 | diff -u -p -r1.22 if_pcn.c | --- if_pcn.c 13 Aug 2009 14:24:47 -0000 1.22 | +++ if_pcn.c 24 Dec 2009 20:12:39 -0000 | @@ -851,7 +851,7 @@ void | pcn_start(struct ifnet *ifp) | { | struct pcn_softc *sc = ifp->if_softc; | - struct mbuf *m0, *m; | + struct mbuf *m0; | struct pcn_txsoft *txs; | bus_dmamap_t dmamap; | int error, nexttx, lasttx = -1, ofree, seg; | @@ -875,7 +875,6 @@ pcn_start(struct ifnet *ifp) | IFQ_POLL(&ifp->if_snd, m0); | if (m0 == NULL) | break; | - m = NULL; | | /* Get a work queue entry. */ | if (sc->sc_txsfree == 0) | @@ -890,23 +889,16 @@ 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) | + error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0, | + BUS_DMA_WRITE|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) == 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) | + m0, BUS_DMA_WRITE|BUS_DMA_NOWAIT); | + if (error != 0) | break; | } | | @@ -929,20 +921,13 @@ pcn_start(struct ifnet *ifp) | */ | ifp->if_flags |= IFF_OACTIVE; | bus_dmamap_unload(sc->sc_dmat, dmamap); | - if (m != NULL) | - m_freem(m); | break; | } | | - IFQ_DEQUEUE(&ifp->if_snd, m0); | - if (m != NULL) { | - m_freem(m0); | - m0 = m; | - } | - | /* | * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET. | */ | + IFQ_DEQUEUE(&ifp->if_snd, m0); | | /* Sync the DMA map. */ | bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize, | | -- | This message has been scanned for viruses and | dangerous content by MailScanner, and is | believed to be clean. | -- >++++++++[<++++++++++>-]<+++++++.>+++[<------>-]<.>+++[<+ +++++++++++>-]<.>++[<------------>-]<+.--------------.[-] http://www.weirdnet.nl/