The following diff replaces the hand rolled code to deal with
really long mbuf chains with the use of m_defrag().
Index: aic6915.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/aic6915.c,v
retrieving revision 1.9
diff -u -p -r1.9 aic6915.c
--- aic6915.c 10 Aug 2009 20:29:54 -0000 1.9
+++ aic6915.c 24 Dec 2009 19:43:37 -0000
@@ -343,7 +343,7 @@ void
sf_start(struct ifnet *ifp)
{
struct sf_softc *sc = ifp->if_softc;
- struct mbuf *m0, *m;
+ struct mbuf *m0;
struct sf_txdesc0 *txd;
struct sf_descsoft *ds;
bus_dmamap_t dmamap;
@@ -373,7 +373,6 @@ sf_start(struct ifnet *ifp)
IFQ_POLL(&ifp->if_snd, m0);
if (m0 == NULL)
break;
- m = NULL;
/*
* Get the transmit descriptor.
@@ -390,40 +389,18 @@ sf_start(struct ifnet *ifp)
*/
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) {
- printf("%s: unable to allocate Tx mbuf\n",
- sc->sc_dev.dv_xname);
+ if (m_defrag(m0, M_DONTWAIT))
break;
- }
- if (m0->m_pkthdr.len > MHLEN) {
- MCLGET(m, M_DONTWAIT);
- if ((m->m_flags & M_EXT) == 0) {
- printf("%s: unable to allocate Tx "
- "cluster\n", sc->sc_dev.dv_xname);
- 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) {
- printf("%s: unable to load Tx buffer, "
- "error = %d\n", sc->sc_dev.dv_xname, error);
+ m0, BUS_DMA_WRITE|BUS_DMA_NOWAIT);
+ if (error)
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 descriptor. */
txd->td_word0 =
--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.