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.