summaryrefslogtreecommitdiffstats
path: root/sys/dev/wpi
diff options
context:
space:
mode:
authorbschmidt <bschmidt@FreeBSD.org>2010-12-30 18:29:22 +0000
committerbschmidt <bschmidt@FreeBSD.org>2010-12-30 18:29:22 +0000
commit543d6f8f19d01a1c2b2c7ae511afd03acf3176d2 (patch)
treef3836dc3d1d3d56285c300a054d76d4b58925b5c /sys/dev/wpi
parent7a575413cdc4c11c26f5d9578b5458a6cbaecdbd (diff)
downloadFreeBSD-src-543d6f8f19d01a1c2b2c7ae511afd03acf3176d2.zip
FreeBSD-src-543d6f8f19d01a1c2b2c7ae511afd03acf3176d2.tar.gz
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
Diffstat (limited to 'sys/dev/wpi')
-rw-r--r--sys/dev/wpi/if_wpi.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c
index b4f94e0..b68451d 100644
--- a/sys/dev/wpi/if_wpi.c
+++ b/sys/dev/wpi/if_wpi.c
@@ -1052,9 +1052,18 @@ wpi_free_rx_ring(struct wpi_softc *sc, struct wpi_rx_ring *ring)
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 wpi_rx_desc *desc,
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 wpi_rx_desc *desc,
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);
OpenPOWER on IntegriCloud