PERFORCE change 93476 for review
Warner Losh
imp at FreeBSD.org
Fri Mar 17 22:26:08 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=93476
Change 93476 by imp at 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
More information about the p4-projects
mailing list