Date: Fri, 17 Mar 2006 22:26:00 GMT From: Warner Losh <imp@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 93476 for review Message-ID: <200603172226.k2HMQ06R018005@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=93476 Change 93476 by imp@imp_Speedy on 2006/03/17 22:25:35 More properly handle writing more packets in atestart_locked. This fixes a race where we could overwrite sent_mbuf[0] before freeing it. Use proper interrupt mask. Single user still works! Affected files ... .. //depot/projects/arm/src/sys/arm/at91/if_ate.c#43 edit Differences ... ==== //depot/projects/arm/src/sys/arm/at91/if_ate.c#43 (text+ko) ==== @@ -752,8 +752,7 @@ WR4(sc, ETH_HSL, 0); WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETH_CTL_TE | ETH_CTL_RE); - WR4(sc, ETH_IER, /*ETH_ISR_RCOM | ETH_ISR_TCOM | ETH_ISR_RBNA*/ - 0xffffffff); + WR4(sc, ETH_IER, ETH_ISR_RCOM | ETH_ISR_TCOM | ETH_ISR_RBNA); /* * Boot loader fills in MAC address. If that's not the case, then @@ -790,52 +789,50 @@ if (ifp->if_drv_flags & IFF_DRV_OACTIVE) return; -outloop: - /* - * check to see if there's room to put another packet into the - * xmit queue. The EMAC chip has a ping-pong buffer for xmit - * packets. We use OACTIVE to indicate "we can stuff more into - * our buffers (clear) or not (set)." - */ - if (!(RD4(sc, ETH_TSR) & ETH_TSR_BNQ)) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - return; - } - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == 0) { - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - return; - } - mdefrag = m_defrag(m, M_DONTWAIT); - if (mdefrag == NULL) { - m_freem(m); - return; - } - m = mdefrag; + while (sc->txcur < ATE_MAX_TX_BUFFERS) { + /* + * check to see if there's room to put another packet into the + * xmit queue. The EMAC chip has a ping-pong buffer for xmit + * packets. We use OACTIVE to indicate "we can stuff more into + * our buffers (clear) or not (set)." + */ + if (!(RD4(sc, ETH_TSR) & ETH_TSR_BNQ)) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + return; + } + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == 0) { + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + return; + } + mdefrag = m_defrag(m, M_DONTWAIT); + if (mdefrag == NULL) { + m_freem(m); + return; + } + m = mdefrag; + if (bus_dmamap_load_mbuf_sg(sc->mtag, sc->tx_map[sc->txcur], m, + segs, &nseg, 0) != 0) { + m_freem(m); + continue; + } + bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txcur], + BUS_DMASYNC_PREWRITE); - if (bus_dmamap_load_mbuf_sg(sc->mtag, sc->tx_map[sc->txcur], m, segs, - &nseg, 0) != 0) { - m_freem(m); - goto outloop; - } - bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txcur], BUS_DMASYNC_PREWRITE); - sc->sent_mbuf[sc->txcur] = m; - sc->txcur++; - if (sc->txcur >= ATE_MAX_TX_BUFFERS) - sc->txcur = 0; - - /* - * tell the hardware to xmit the packet. - */ - WR4(sc, ETH_TAR, segs[0].ds_addr); - WR4(sc, ETH_TCR, segs[0].ds_len); + /* + * tell the hardware to xmit the packet. + */ + WR4(sc, ETH_TAR, segs[0].ds_addr); + WR4(sc, ETH_TCR, segs[0].ds_len); - /* - * Tap off here if there is a bpf listener. - */ - BPF_MTAP(ifp, m); + /* + * Tap off here if there is a bpf listener. + */ + BPF_MTAP(ifp, m); - goto outloop; + sc->sent_mbuf[sc->txcur] = m; + sc->txcur++; + } } static void
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200603172226.k2HMQ06R018005>