From 329532e54ea5f515afdf909016d206299bd7d945 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Sat, 12 Aug 2006 01:30:38 +0000 Subject: [PATCH] Fix invalid reference of mbuf chains. Use proper pointer dereference to inform modified mbuf chains to caller. While I'm here perform checksum offload setup after loading DMA maps. In collaboration with: glebius --- sys/dev/ti/if_ti.c | 62 +++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/sys/dev/ti/if_ti.c b/sys/dev/ti/if_ti.c index b6031030d02..898fe140752 100644 --- a/sys/dev/ti/if_ti.c +++ b/sys/dev/ti/if_ti.c @@ -2955,7 +2955,7 @@ ti_encap(sc, m_head) struct ti_txdesc *txd; struct ti_tx_desc *f; struct ti_tx_desc txdesc; - struct mbuf *m, *n; + struct mbuf *m; struct m_tag *mtag; bus_dma_segment_t txsegs[TI_MAXTXSEGS]; u_int16_t csum_flags; @@ -2964,6 +2964,36 @@ ti_encap(sc, m_head) if ((txd = STAILQ_FIRST(&sc->ti_cdata.ti_txfreeq)) == NULL) return (ENOBUFS); + error = bus_dmamap_load_mbuf_sg(sc->ti_mbuftx_dmat, txd->tx_dmamap, + *m_head, txsegs, &nseg, 0); + if (error == EFBIG) { + m = m_defrag(*m_head, M_DONTWAIT); + if (m == NULL) { + m_freem(*m_head); + *m_head = NULL; + return (ENOMEM); + } + *m_head = m; + error = bus_dmamap_load_mbuf_sg(sc->ti_mbuftx_dmat, + txd->tx_dmamap, *m_head, txsegs, &nseg, 0); + if (error) { + m_freem(*m_head); + *m_head = NULL; + return (error); + } + } else if (error != 0) + return (error); + if (nseg == 0) { + m_freem(*m_head); + *m_head = NULL; + return (EIO); + } + + if (sc->ti_txcnt + nseg >= TI_TX_RING_CNT) { + bus_dmamap_unload(sc->ti_mbuftx_dmat, txd->tx_dmamap); + return (ENOBUFS); + } + m = *m_head; csum_flags = 0; if (m->m_pkthdr.csum_flags) { @@ -2977,36 +3007,6 @@ ti_encap(sc, m_head) csum_flags |= TI_BDFLAG_IP_FRAG; } - error = bus_dmamap_load_mbuf_sg(sc->ti_mbuftx_dmat, txd->tx_dmamap, - m, txsegs, &nseg, 0); - if (error == EFBIG) { - n = m_defrag(m, M_DONTWAIT); - if (n == NULL) { - m_freem(m); - m = NULL; - return (ENOMEM); - } - m = n; - error = bus_dmamap_load_mbuf_sg(sc->ti_mbuftx_dmat, - txd->tx_dmamap, m, txsegs, &nseg, 0); - if (error) { - m_freem(m); - m = NULL; - return (error); - } - } else if (error != 0) - return (error); - if (nseg == 0) { - m_freem(m); - m = NULL; - return (EIO); - } - - if (sc->ti_txcnt + nseg >= TI_TX_RING_CNT) { - bus_dmamap_unload(sc->ti_mbuftx_dmat, txd->tx_dmamap); - return (ENOBUFS); - } - bus_dmamap_sync(sc->ti_mbuftx_dmat, txd->tx_dmamap, BUS_DMASYNC_PREWRITE); bus_dmamap_sync(sc->ti_rdata_dmat, sc->ti_rdata_dmamap,