The following diff replaces the hand rolled code to deal with
really long mbuf chains with the use of m_defrag().
Index: smc83c170.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/smc83c170.c,v
retrieving revision 1.14
diff -u -p -r1.14 smc83c170.c
--- smc83c170.c 10 Aug 2009 20:29:54 -0000 1.14
+++ smc83c170.c 24 Dec 2009 20:03:42 -0000
@@ -334,7 +334,7 @@ void
epic_start(struct ifnet *ifp)
{
struct epic_softc *sc = ifp->if_softc;
- struct mbuf *m0, *m;
+ struct mbuf *m0;
struct epic_txdesc *txd;
struct epic_descsoft *ds;
struct epic_fraglist *fr;
@@ -361,7 +361,6 @@ epic_start(struct ifnet *ifp)
IFQ_POLL(&ifp->if_snd, m0);
if (m0 == NULL)
break;
- m = NULL;
/*
* Get the last and next available transmit descriptor.
@@ -378,35 +377,27 @@ epic_start(struct ifnet *ifp)
* short on resources. In this case, we'll copy and try
* again.
*/
- if ((error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
- BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 ||
- (m0->m_pkthdr.len < ETHER_PAD_LEN &&
- dmamap-> dm_nsegs == EPIC_NFRAGS)) {
+ 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 || (m0->m_pkthdr.len < ETHER_PAD_LEN &&
+ dmamap->dm_nsegs == EPIC_NFRAGS)) {
if (error == 0)
bus_dmamap_unload(sc->sc_dmat, dmamap);
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
+ 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;
}
+
+ /*
+ * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET.
+ */
IFQ_DEQUEUE(&ifp->if_snd, m0);
- if (m != NULL) {
- m_freem(m0);
- m0 = m;
- }
/* Initialize the fraglist. */
for (seg = 0; seg < dmamap->dm_nsegs; seg++) {
--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.