svn commit: r216824 - head/sys/dev/wpi

Bernhard Schmidt bschmidt at FreeBSD.org
Thu Dec 30 18:29:23 UTC 2010


Author: bschmidt
Date: Thu Dec 30 18:29:22 2010
New Revision: 216824
URL: http://svn.freebsd.org/changeset/base/216824

Log:
  The RX path is missing a few bus_dmamap_*() calls, this results in
  modification of memory which was already free'd and eventually in:
  wpi0: could not map mbuf (error 12)
  wpi0: wpi_rx_intr: bus_dmamap_load failed, error 12
  and an usuable device.
  
  PR:		kern/144898
  MFC after:	3 days

Modified:
  head/sys/dev/wpi/if_wpi.c

Modified: head/sys/dev/wpi/if_wpi.c
==============================================================================
--- head/sys/dev/wpi/if_wpi.c	Thu Dec 30 18:06:31 2010	(r216823)
+++ head/sys/dev/wpi/if_wpi.c	Thu Dec 30 18:29:22 2010	(r216824)
@@ -1052,9 +1052,18 @@ wpi_free_rx_ring(struct wpi_softc *sc, s
 
 	wpi_dma_contig_free(&ring->desc_dma);
 
-	for (i = 0; i < WPI_RX_RING_COUNT; i++)
-		if (ring->data[i].m != NULL)
-			m_freem(ring->data[i].m);
+	for (i = 0; i < WPI_RX_RING_COUNT; i++) {
+		struct wpi_rx_data *data = &ring->data[i];
+
+		if (data->m != NULL) {
+			bus_dmamap_sync(ring->data_dmat, data->map,
+			    BUS_DMASYNC_POSTREAD);
+			bus_dmamap_unload(ring->data_dmat, data->map);
+			m_freem(data->m);
+		}
+		if (data->map != NULL)
+			bus_dmamap_destroy(ring->data_dmat, data->map);
+	}
 }
 
 static int
@@ -1461,6 +1470,7 @@ wpi_rx_intr(struct wpi_softc *sc, struct
 		return;
 	}
 
+	bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD);
 	head = (struct wpi_rx_head *)((caddr_t)(stat + 1) + stat->len);
 	tail = (struct wpi_rx_tail *)((caddr_t)(head + 1) + le16toh(head->len));
 
@@ -1491,6 +1501,8 @@ wpi_rx_intr(struct wpi_softc *sc, struct
 		ifp->if_ierrors++;
 		return;
 	}
+	bus_dmamap_unload(ring->data_dmat, data->map);
+
 	error = bus_dmamap_load(ring->data_dmat, data->map,
 	    mtod(mnew, caddr_t), MJUMPAGESIZE,
 	    wpi_dma_map_addr, &paddr, BUS_DMA_NOWAIT);


More information about the svn-src-head mailing list