Module Name:    src
Committed By:   sborrill
Date:           Fri Nov 18 23:25:40 UTC 2011

Modified Files:
        src/sys/dev/pci [netbsd-5]: if_age.c

Log Message:
Pull up the following revisions(s) (requested by bouyer in ticket #1694):
        sys/dev/pci/if_age.c:   revision 1.40 via patch

- age_init() is called from age_watchdog() which is in interrupt context; we
can't sleep here or we get a DIAGNOSTIC panic when age_watchdog() fires.
- More correct bus_dma(9) usage in age_encap()
- Introduce a age_shutdown() to be called by pmf(9) at shutdown time,
to stop the DMA engine.
- Be consistent in WAIT/NOWAIT use in init routines
- Use BUS_DMA_COHERENT where appropriate
- Rework the interrupt routine a bit, and ACK but do not disable interrupts
here. There seems to be a race where interrupts would not be properly
reenabled after this, leading do watchdog timeouts.


To generate a diff of this commit:
cvs rdiff -u -r1.28.2.5 -r1.28.2.6 src/sys/dev/pci/if_age.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_age.c
diff -u src/sys/dev/pci/if_age.c:1.28.2.5 src/sys/dev/pci/if_age.c:1.28.2.6
--- src/sys/dev/pci/if_age.c:1.28.2.5	Sun Nov  8 22:03:32 2009
+++ src/sys/dev/pci/if_age.c	Fri Nov 18 23:25:40 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_age.c,v 1.28.2.5 2009/11/08 22:03:32 snj Exp $ */
+/*	$NetBSD: if_age.c,v 1.28.2.6 2011/11/18 23:25:40 sborrill Exp $ */
 /*	$OpenBSD: if_age.c,v 1.1 2009/01/16 05:00:34 kevlo Exp $	*/
 
 /*-
@@ -31,7 +31,7 @@
 /* Driver for Attansic Technology Corp. L1 Gigabit Ethernet. */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_age.c,v 1.28.2.5 2009/11/08 22:03:32 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_age.c,v 1.28.2.6 2011/11/18 23:25:40 sborrill Exp $");
 
 #include "bpfilter.h"
 #include "vlan.h"
@@ -93,6 +93,7 @@ static int	age_init(struct ifnet *);
 static int	age_ioctl(struct ifnet *, u_long, void *);
 static void	age_start(struct ifnet *);
 static void	age_watchdog(struct ifnet *);
+static bool	age_shutdown(device_t, int);
 static void	age_mediastatus(struct ifnet *, struct ifmediareq *);
 static int	age_mediachange(struct ifnet *);
 
@@ -287,7 +288,7 @@ age_attach(device_t parent, device_t sel
 	if_attach(ifp);
 	ether_ifattach(ifp, sc->sc_enaddr);
 
-	if (!pmf_device_register(self, NULL, age_resume))
+	if (!pmf_device_register1(self, NULL, age_resume, age_shutdown))
 		aprint_error_dev(self, "couldn't establish power handler\n");
 	else
 		pmf_class_network_register(self, ifp);
@@ -495,65 +496,61 @@ age_intr(void *arg)
 	cmb = sc->age_rdata.age_cmb_block;
 	if (cmb == NULL) {
 		/* Happens when bringing up the interface
-		 * w/o having a carrier. Ack. the interrupt.
+		 * w/o having a carrier. Ack the interrupt.
 		 */
 		CSR_WRITE_4(sc, AGE_INTR_STATUS, status);
 		return 0;
 	}
 
-	/* Disable interrupts. */
-	CSR_WRITE_4(sc, AGE_INTR_STATUS, status | INTR_DIS_INT);
-		
-	bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_cmb_block_map, 0,
-	    sc->age_cdata.age_cmb_block_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
-	status = le32toh(cmb->intr_status);
-	if ((status & AGE_INTRS) == 0)
-		goto back;
-
-	sc->age_tpd_cons = (le32toh(cmb->tpd_cons) & TPD_CONS_MASK) >>
-	    TPD_CONS_SHIFT;
-	sc->age_rr_prod = (le32toh(cmb->rprod_cons) & RRD_PROD_MASK) >>
-	    RRD_PROD_SHIFT;
-
-	/* Let hardware know CMB was served. */
-	cmb->intr_status = 0;
 	bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_cmb_block_map, 0,
 	    sc->age_cdata.age_cmb_block_map->dm_mapsize,
-	    BUS_DMASYNC_PREWRITE);
-
-	if (ifp->if_flags & IFF_RUNNING) {
-		if (status & INTR_CMB_RX)
-			age_rxintr(sc, sc->age_rr_prod);
-
-		if (status & INTR_CMB_TX)
-			age_txintr(sc, sc->age_tpd_cons);
-
-		if (status & (INTR_DMA_RD_TO_RST | INTR_DMA_WR_TO_RST)) {
-			if (status & INTR_DMA_RD_TO_RST)
-				printf("%s: DMA read error! -- resetting\n",
-				    device_xname(sc->sc_dev));
-			if (status & INTR_DMA_WR_TO_RST)
-				printf("%s: DMA write error! -- resetting\n",
-				    device_xname(sc->sc_dev));
-			age_init(ifp);
-		}
+	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
+	status = le32toh(cmb->intr_status);
+	/* ACK/reenable interrupts */
+	CSR_WRITE_4(sc, AGE_INTR_STATUS, status);
+	while ((status & AGE_INTRS) != 0) {
+		sc->age_tpd_cons = (le32toh(cmb->tpd_cons) & TPD_CONS_MASK) >>
+		    TPD_CONS_SHIFT;
+		sc->age_rr_prod = (le32toh(cmb->rprod_cons) & RRD_PROD_MASK) >>
+		    RRD_PROD_SHIFT;
+
+		/* Let hardware know CMB was served. */
+		cmb->intr_status = 0;
+		bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_cmb_block_map, 0,
+		    sc->age_cdata.age_cmb_block_map->dm_mapsize,
+		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
+
+		if (ifp->if_flags & IFF_RUNNING) {
+			if (status & INTR_CMB_RX)
+				age_rxintr(sc, sc->age_rr_prod);
+
+			if (status & INTR_CMB_TX)
+				age_txintr(sc, sc->age_tpd_cons);
+
+			if (status & (INTR_DMA_RD_TO_RST | INTR_DMA_WR_TO_RST)) {
+				if (status & INTR_DMA_RD_TO_RST)
+					printf("%s: DMA read error! -- "
+					    "resetting\n",
+					    device_xname(sc->sc_dev));
+				if (status & INTR_DMA_WR_TO_RST)
+					printf("%s: DMA write error! -- "
+					    "resetting\n",
+					    device_xname(sc->sc_dev));
+				age_init(ifp);
+			}
 
-		if (!IFQ_IS_EMPTY(&ifp->if_snd))
 			age_start(ifp);
 
-		if (status & INTR_SMB)
-			age_stats_update(sc);
+			if (status & INTR_SMB)
+				age_stats_update(sc);
+		}
+		/* check if more interrupts did came in */
+		bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_cmb_block_map, 0,
+		    sc->age_cdata.age_cmb_block_map->dm_mapsize,
+		    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
+		status = le32toh(cmb->intr_status);
 	}
 
-	/* Check whether CMB was updated while serving Tx/Rx/SMB handler. */
-	bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_cmb_block_map, 0,
-	    sc->age_cdata.age_cmb_block_map->dm_mapsize,
-	    BUS_DMASYNC_POSTREAD);
-
-back:
-	/* Re-enable interrupts. */
-	CSR_WRITE_4(sc, AGE_INTR_STATUS, 0);
-
 	return 1;
 }
 
@@ -702,7 +699,7 @@ age_dma_alloc(struct age_softc *sc)
 	/* Allocate DMA'able memory for TX ring */
 	error = bus_dmamem_alloc(sc->sc_dmat, AGE_TX_RING_SZ, 
 	    ETHER_ALIGN, 0, &sc->age_rdata.age_tx_ring_seg, 1, 
-	    &nsegs, BUS_DMA_WAITOK);
+	    &nsegs, BUS_DMA_NOWAIT);
 	if (error) {
 		printf("%s: could not allocate DMA'able memory for Tx ring, "
 		    "error = %i\n", device_xname(sc->sc_dev), error);
@@ -711,7 +708,7 @@ age_dma_alloc(struct age_softc *sc)
 
 	error = bus_dmamem_map(sc->sc_dmat, &sc->age_rdata.age_tx_ring_seg,
 	    nsegs, AGE_TX_RING_SZ, (void **)&sc->age_rdata.age_tx_ring,
-	    BUS_DMA_NOWAIT);
+	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
 	if (error) 
 		return ENOBUFS;
 
@@ -719,7 +716,7 @@ age_dma_alloc(struct age_softc *sc)
 
 	/*  Load the DMA map for Tx ring. */
 	error = bus_dmamap_load(sc->sc_dmat, sc->age_cdata.age_tx_ring_map,
-	    sc->age_rdata.age_tx_ring, AGE_TX_RING_SZ, NULL, BUS_DMA_WAITOK);
+	    sc->age_rdata.age_tx_ring, AGE_TX_RING_SZ, NULL, BUS_DMA_NOWAIT);
 	if (error) {
 		printf("%s: could not load DMA'able memory for Tx ring, "
 		    "error = %i\n", device_xname(sc->sc_dev), error);
@@ -744,7 +741,7 @@ age_dma_alloc(struct age_softc *sc)
 	/* Allocate DMA'able memory for RX ring */
 	error = bus_dmamem_alloc(sc->sc_dmat, AGE_RX_RING_SZ, 
 	    ETHER_ALIGN, 0, &sc->age_rdata.age_rx_ring_seg, 1, 
-	    &nsegs, BUS_DMA_WAITOK);
+	    &nsegs, BUS_DMA_NOWAIT);
 	if (error) {
 		printf("%s: could not allocate DMA'able memory for Rx ring, "
 		    "error = %i.\n", device_xname(sc->sc_dev), error);
@@ -753,7 +750,7 @@ age_dma_alloc(struct age_softc *sc)
 
 	error = bus_dmamem_map(sc->sc_dmat, &sc->age_rdata.age_rx_ring_seg,
 	    nsegs, AGE_RX_RING_SZ, (void **)&sc->age_rdata.age_rx_ring,
-	    BUS_DMA_NOWAIT);
+	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
 	if (error)
 		return ENOBUFS;
 
@@ -761,7 +758,7 @@ age_dma_alloc(struct age_softc *sc)
 
 	/* Load the DMA map for Rx ring. */
 	error = bus_dmamap_load(sc->sc_dmat, sc->age_cdata.age_rx_ring_map,
-	    sc->age_rdata.age_rx_ring, AGE_RX_RING_SZ, NULL, BUS_DMA_WAITOK);
+	    sc->age_rdata.age_rx_ring, AGE_RX_RING_SZ, NULL, BUS_DMA_NOWAIT);
 	if (error) {
 		printf("%s: could not load DMA'able memory for Rx ring, "
 		    "error = %i.\n", device_xname(sc->sc_dev), error);
@@ -786,7 +783,7 @@ age_dma_alloc(struct age_softc *sc)
 	/* Allocate DMA'able memory for RX return ring */
 	error = bus_dmamem_alloc(sc->sc_dmat, AGE_RR_RING_SZ, 
 	    ETHER_ALIGN, 0, &sc->age_rdata.age_rr_ring_seg, 1, 
-	    &nsegs, BUS_DMA_WAITOK);
+	    &nsegs, BUS_DMA_NOWAIT);
 	if (error) {
 		printf("%s: could not allocate DMA'able memory for Rx "
 		    "return ring, error = %i.\n",
@@ -796,7 +793,7 @@ age_dma_alloc(struct age_softc *sc)
 
 	error = bus_dmamem_map(sc->sc_dmat, &sc->age_rdata.age_rr_ring_seg,
 	    nsegs, AGE_RR_RING_SZ, (void **)&sc->age_rdata.age_rr_ring,
-	    BUS_DMA_NOWAIT);
+	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
 	if (error)
 		return ENOBUFS;
 
@@ -804,7 +801,7 @@ age_dma_alloc(struct age_softc *sc)
 
 	/*  Load the DMA map for Rx return ring. */
 	error = bus_dmamap_load(sc->sc_dmat, sc->age_cdata.age_rr_ring_map,
-	    sc->age_rdata.age_rr_ring, AGE_RR_RING_SZ, NULL, BUS_DMA_WAITOK);
+	    sc->age_rdata.age_rr_ring, AGE_RR_RING_SZ, NULL, BUS_DMA_NOWAIT);
 	if (error) {
 		printf("%s: could not load DMA'able memory for Rx return ring, "
 		    "error = %i\n", device_xname(sc->sc_dev), error);
@@ -830,7 +827,7 @@ age_dma_alloc(struct age_softc *sc)
 	/* Allocate DMA'able memory for CMB block */
 	error = bus_dmamem_alloc(sc->sc_dmat, AGE_CMB_BLOCK_SZ, 
 	    ETHER_ALIGN, 0, &sc->age_rdata.age_cmb_block_seg, 1, 
-	    &nsegs, BUS_DMA_WAITOK);
+	    &nsegs, BUS_DMA_NOWAIT);
 	if (error) {
 		printf("%s: could not allocate DMA'able memory for "
 		    "CMB block, error = %i\n", device_xname(sc->sc_dev), error);
@@ -839,7 +836,7 @@ age_dma_alloc(struct age_softc *sc)
 
 	error = bus_dmamem_map(sc->sc_dmat, &sc->age_rdata.age_cmb_block_seg,
 	    nsegs, AGE_CMB_BLOCK_SZ, (void **)&sc->age_rdata.age_cmb_block,
-	    BUS_DMA_NOWAIT);
+	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
 	if (error)
 		return ENOBUFS;
 
@@ -848,7 +845,7 @@ age_dma_alloc(struct age_softc *sc)
 	/*  Load the DMA map for CMB block. */
 	error = bus_dmamap_load(sc->sc_dmat, sc->age_cdata.age_cmb_block_map,
 	    sc->age_rdata.age_cmb_block, AGE_CMB_BLOCK_SZ, NULL, 
-	    BUS_DMA_WAITOK);
+	    BUS_DMA_NOWAIT);
 	if (error) {
 		printf("%s: could not load DMA'able memory for CMB block, "
 		    "error = %i\n", device_xname(sc->sc_dev), error);
@@ -874,7 +871,7 @@ age_dma_alloc(struct age_softc *sc)
 	/* Allocate DMA'able memory for SMB block */
 	error = bus_dmamem_alloc(sc->sc_dmat, AGE_SMB_BLOCK_SZ, 
 	    ETHER_ALIGN, 0, &sc->age_rdata.age_smb_block_seg, 1, 
-	    &nsegs, BUS_DMA_WAITOK);
+	    &nsegs, BUS_DMA_NOWAIT);
 	if (error) {
 		printf("%s: could not allocate DMA'able memory for "
 		    "SMB block, error = %i\n", device_xname(sc->sc_dev), error);
@@ -883,7 +880,7 @@ age_dma_alloc(struct age_softc *sc)
 
 	error = bus_dmamem_map(sc->sc_dmat, &sc->age_rdata.age_smb_block_seg,
 	    nsegs, AGE_SMB_BLOCK_SZ, (void **)&sc->age_rdata.age_smb_block,
-	    BUS_DMA_NOWAIT);
+	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
 	if (error)
 		return ENOBUFS;
 
@@ -892,7 +889,7 @@ age_dma_alloc(struct age_softc *sc)
 	/*  Load the DMA map for SMB block */
 	error = bus_dmamap_load(sc->sc_dmat, sc->age_cdata.age_smb_block_map,
 	    sc->age_rdata.age_smb_block, AGE_SMB_BLOCK_SZ, NULL, 
-	    BUS_DMA_WAITOK);
+	    BUS_DMA_NOWAIT);
 	if (error) {
 		printf("%s: could not load DMA'able memory for SMB block, "
 		    "error = %i\n", device_xname(sc->sc_dev), error);
@@ -1034,6 +1031,10 @@ age_start(struct ifnet *ifp)
 
 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
 		return;
+	if ((sc->age_flags & AGE_FLAG_LINK) == 0)
+		return;
+	if (IFQ_IS_EMPTY(&ifp->if_snd))
+		return;
 
 	enq = 0;
 	for (;;) {
@@ -1089,19 +1090,30 @@ age_watchdog(struct ifnet *ifp)
 	if (sc->age_cdata.age_tx_cnt == 0) {
 		printf("%s: watchdog timeout (missed Tx interrupts) "
 		    "-- recovering\n", device_xname(sc->sc_dev));
-		if (!IFQ_IS_EMPTY(&ifp->if_snd))
-			age_start(ifp);
+		age_start(ifp);
 		return;
 	}
 
 	printf("%s: watchdog timeout\n", device_xname(sc->sc_dev));
 	ifp->if_oerrors++;
 	age_init(ifp);
-
-	if (!IFQ_IS_EMPTY(&ifp->if_snd))
-		age_start(ifp);
+	age_start(ifp);
 }
 
+static bool 
+age_shutdown(device_t self, int howto) 
+{
+	struct age_softc *sc;
+	struct ifnet *ifp;
+
+	sc = device_private(self);
+	ifp = &sc->sc_ec.ec_if;
+	age_stop(ifp, 1); 
+
+	return true;
+}       
+
+
 static int
 age_ioctl(struct ifnet *ifp, u_long cmd, void *data)
 {
@@ -1237,6 +1249,8 @@ age_encap(struct age_softc *sc, struct m
 		bus_dmamap_unload(sc->sc_dmat, map);
 		return ENOBUFS;
 	}
+	bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
+	    BUS_DMASYNC_PREWRITE);
 
 	m = *m_head;
 	/* Configure Tx IP/TCP/UDP checksum offload. */
@@ -1260,36 +1274,46 @@ age_encap(struct age_softc *sc, struct m
 #endif
 
 	desc = NULL;
-	for (i = 0; i < nsegs; i++) {
+	KASSERT(nsegs > 0);
+	for (i = 0; ; i++) {
 		desc = &sc->age_rdata.age_tx_ring[prod];
 		desc->addr = htole64(map->dm_segs[i].ds_addr);
 		desc->len = 
 		    htole32(AGE_TX_BYTES(map->dm_segs[i].ds_len) | vtag);
 		desc->flags = htole32(cflags);
 		sc->age_cdata.age_tx_cnt++;
+		if (i == (nsegs - 1))
+			break;
+		
+		/* sync this descriptor and go to the next one */
+		bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_tx_ring_map,
+		    prod * sizeof(struct tx_desc), sizeof(struct tx_desc),
+		    BUS_DMASYNC_PREWRITE);
 		AGE_DESC_INC(prod, AGE_TX_RING_CNT);
 	}
 
-	/* Update producer index. */
-	sc->age_cdata.age_tx_prod = prod;
-
-	/* Set EOP on the last descriptor. */
-	prod = (prod + AGE_TX_RING_CNT - 1) % AGE_TX_RING_CNT;
-	desc = &sc->age_rdata.age_tx_ring[prod];
+	/* Set EOP on the last descriptor and sync it. */
 	desc->flags |= htole32(AGE_TD_EOP);
+	bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_tx_ring_map,
+	    prod * sizeof(struct tx_desc), sizeof(struct tx_desc),
+	    BUS_DMASYNC_PREWRITE);
 
-	/* Swap dmamap of the first and the last. */
-	txd = &sc->age_cdata.age_txdesc[prod];
-	map = txd_last->tx_dmamap;
-	txd_last->tx_dmamap = txd->tx_dmamap;
-	txd->tx_dmamap = map;
-	txd->tx_m = m;
+	if (nsegs > 1) {
+		/* Swap dmamap of the first and the last. */
+		txd = &sc->age_cdata.age_txdesc[prod];
+		map = txd_last->tx_dmamap;
+		txd_last->tx_dmamap = txd->tx_dmamap;
+		txd->tx_dmamap = map;
+		txd->tx_m = m;
+		KASSERT(txd_last->tx_m == NULL);
+	} else {
+		KASSERT(txd_last == &sc->age_cdata.age_txdesc[prod]);
+		txd_last->tx_m = m;
+	}
 
-	/* Sync descriptors. */
-	bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
-	    BUS_DMASYNC_PREWRITE);
-	bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_tx_ring_map, 0,
-	    sc->age_cdata.age_tx_ring_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
+	/* Update producer index. */
+	AGE_DESC_INC(prod, AGE_TX_RING_CNT);
+	sc->age_cdata.age_tx_prod = prod;
 
 	return 0;
 }
@@ -1301,8 +1325,13 @@ age_txintr(struct age_softc *sc, int tpd
 	struct age_txdesc *txd;
 	int cons, prog;
 
-	bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_tx_ring_map, 0,
-	    sc->age_cdata.age_tx_ring_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
+
+	if (sc->age_cdata.age_tx_cnt <= 0) {
+		if (ifp->if_timer != 0)
+			printf("timer running without packets\n");
+		if (sc->age_cdata.age_tx_cnt)
+			printf("age_tx_cnt corrupted\n");
+	}
 
 	/*
 	 * Go through our Tx list and free mbufs for those
@@ -1320,6 +1349,9 @@ age_txintr(struct age_softc *sc, int tpd
 		 * Clear Tx descriptors, it's not required but would
 		 * help debugging in case of Tx issues.
 		 */
+		bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_tx_ring_map,
+		    cons * sizeof(struct tx_desc), sizeof(struct tx_desc),
+		    BUS_DMASYNC_POSTWRITE);
 		txd->tx_desc->addr = 0;
 		txd->tx_desc->len = 0;
 		txd->tx_desc->flags = 0;
@@ -1341,10 +1373,6 @@ age_txintr(struct age_softc *sc, int tpd
 		 */
 		if (sc->age_cdata.age_tx_cnt == 0)
 			ifp->if_timer = 0;
-
-		bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_tx_ring_map, 0,
-		    sc->age_cdata.age_tx_ring_map->dm_mapsize,
-		    BUS_DMASYNC_PREWRITE);
 	}
 }
 
@@ -1957,7 +1985,8 @@ age_stats_update(struct age_softc *sc)
 	stat = &sc->age_stat;
 
 	bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_smb_block_map, 0,
-	    sc->age_cdata.age_smb_block_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
+	    sc->age_cdata.age_smb_block_map->dm_mapsize,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 
 	smb = sc->age_rdata.age_smb_block;
 	if (smb->updated == 0)
@@ -2038,7 +2067,8 @@ age_stats_update(struct age_softc *sc)
 	smb->updated = 0;
 
 	bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_smb_block_map, 0,
-	    sc->age_cdata.age_smb_block_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
+	    sc->age_cdata.age_smb_block_map->dm_mapsize,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 }
 
 static void
@@ -2163,7 +2193,8 @@ age_init_cmb_block(struct age_softc *sc)
 	rd = &sc->age_rdata;
 	memset(rd->age_cmb_block, 0, AGE_CMB_BLOCK_SZ);
 	bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_cmb_block_map, 0,
-	    sc->age_cdata.age_cmb_block_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
+	    sc->age_cdata.age_cmb_block_map->dm_mapsize,
+	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 }
 
 static void
@@ -2185,10 +2216,10 @@ age_newbuf(struct age_softc *sc, struct 
 	bus_dmamap_t map;
 	int error;
 
-	MGETHDR(m, init ? M_WAITOK : M_DONTWAIT, MT_DATA);
+	MGETHDR(m, M_DONTWAIT, MT_DATA);
 	if (m == NULL)
 		return ENOBUFS;
-	MCLGET(m, init ? M_WAITOK : M_DONTWAIT);
+	MCLGET(m, M_DONTWAIT);
 	if (!(m->m_flags & M_EXT)) {
 		 m_freem(m);
 		 return ENOBUFS;

Reply via email to