summaryrefslogtreecommitdiffstats
path: root/sys/dev/alc
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2014-06-11 14:53:58 +0000
committerjhb <jhb@FreeBSD.org>2014-06-11 14:53:58 +0000
commite8769d6be243ea7d1540dd79d95893ea33393634 (patch)
tree5544dcfb2be4391a29657081ad30163d6c502e86 /sys/dev/alc
parent60cbac59442236d3d8d9a9d3475a8b1b7421ae33 (diff)
downloadFreeBSD-src-e8769d6be243ea7d1540dd79d95893ea33393634.zip
FreeBSD-src-e8769d6be243ea7d1540dd79d95893ea33393634.tar.gz
Fix various NIC drivers to properly cleanup static DMA resources.
In particular, don't check the value of the bus_dma map against NULL to determine if either bus_dmamem_alloc() or bus_dmamap_load() succeeded. Instead, assume that bus_dmamap_load() succeeeded (and thus that bus_dmamap_unload() should be called) if the bus address for a resource is non-zero, and assume that bus_dmamem_alloc() succeeded (and thus that bus_dmamem_free() should be called) if the virtual address for a resource is not NULL. In many cases these bugs could result in leaks when a driver was detached. Reviewed by: yongari MFC after: 2 weeks
Diffstat (limited to 'sys/dev/alc')
-rw-r--r--sys/dev/alc/if_alc.c37
1 files changed, 16 insertions, 21 deletions
diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c
index 9886e9b..dcc9230 100644
--- a/sys/dev/alc/if_alc.c
+++ b/sys/dev/alc/if_alc.c
@@ -1735,76 +1735,71 @@ alc_dma_free(struct alc_softc *sc)
}
/* Tx descriptor ring. */
if (sc->alc_cdata.alc_tx_ring_tag != NULL) {
- if (sc->alc_cdata.alc_tx_ring_map != NULL)
+ if (sc->alc_rdata.alc_tx_ring_paddr != 0)
bus_dmamap_unload(sc->alc_cdata.alc_tx_ring_tag,
sc->alc_cdata.alc_tx_ring_map);
- if (sc->alc_cdata.alc_tx_ring_map != NULL &&
- sc->alc_rdata.alc_tx_ring != NULL)
+ if (sc->alc_rdata.alc_tx_ring != NULL)
bus_dmamem_free(sc->alc_cdata.alc_tx_ring_tag,
sc->alc_rdata.alc_tx_ring,
sc->alc_cdata.alc_tx_ring_map);
+ sc->alc_rdata.alc_tx_ring_paddr = 0;
sc->alc_rdata.alc_tx_ring = NULL;
- sc->alc_cdata.alc_tx_ring_map = NULL;
bus_dma_tag_destroy(sc->alc_cdata.alc_tx_ring_tag);
sc->alc_cdata.alc_tx_ring_tag = NULL;
}
/* Rx ring. */
if (sc->alc_cdata.alc_rx_ring_tag != NULL) {
- if (sc->alc_cdata.alc_rx_ring_map != NULL)
+ if (sc->alc_rdata.alc_rx_ring_paddr != 0)
bus_dmamap_unload(sc->alc_cdata.alc_rx_ring_tag,
sc->alc_cdata.alc_rx_ring_map);
- if (sc->alc_cdata.alc_rx_ring_map != NULL &&
- sc->alc_rdata.alc_rx_ring != NULL)
+ if (sc->alc_rdata.alc_rx_ring != NULL)
bus_dmamem_free(sc->alc_cdata.alc_rx_ring_tag,
sc->alc_rdata.alc_rx_ring,
sc->alc_cdata.alc_rx_ring_map);
+ sc->alc_rdata.alc_rx_ring_paddr = 0;
sc->alc_rdata.alc_rx_ring = NULL;
- sc->alc_cdata.alc_rx_ring_map = NULL;
bus_dma_tag_destroy(sc->alc_cdata.alc_rx_ring_tag);
sc->alc_cdata.alc_rx_ring_tag = NULL;
}
/* Rx return ring. */
if (sc->alc_cdata.alc_rr_ring_tag != NULL) {
- if (sc->alc_cdata.alc_rr_ring_map != NULL)
+ if (sc->alc_rdata.alc_rr_ring_paddr != 0)
bus_dmamap_unload(sc->alc_cdata.alc_rr_ring_tag,
sc->alc_cdata.alc_rr_ring_map);
- if (sc->alc_cdata.alc_rr_ring_map != NULL &&
- sc->alc_rdata.alc_rr_ring != NULL)
+ if (sc->alc_rdata.alc_rr_ring != NULL)
bus_dmamem_free(sc->alc_cdata.alc_rr_ring_tag,
sc->alc_rdata.alc_rr_ring,
sc->alc_cdata.alc_rr_ring_map);
+ sc->alc_rdata.alc_rr_ring_paddr = 0;
sc->alc_rdata.alc_rr_ring = NULL;
- sc->alc_cdata.alc_rr_ring_map = NULL;
bus_dma_tag_destroy(sc->alc_cdata.alc_rr_ring_tag);
sc->alc_cdata.alc_rr_ring_tag = NULL;
}
/* CMB block */
if (sc->alc_cdata.alc_cmb_tag != NULL) {
- if (sc->alc_cdata.alc_cmb_map != NULL)
+ if (sc->alc_rdata.alc_cmb_paddr != 0)
bus_dmamap_unload(sc->alc_cdata.alc_cmb_tag,
sc->alc_cdata.alc_cmb_map);
- if (sc->alc_cdata.alc_cmb_map != NULL &&
- sc->alc_rdata.alc_cmb != NULL)
+ if (sc->alc_rdata.alc_cmb != NULL)
bus_dmamem_free(sc->alc_cdata.alc_cmb_tag,
sc->alc_rdata.alc_cmb,
- sc->alc_cdata.alc_cmb_map);
+ sc->alc_cdata.alc_cmb_map);
+ sc->alc_rdata.alc_cmb_paddr = 0;
sc->alc_rdata.alc_cmb = NULL;
- sc->alc_cdata.alc_cmb_map = NULL;
bus_dma_tag_destroy(sc->alc_cdata.alc_cmb_tag);
sc->alc_cdata.alc_cmb_tag = NULL;
}
/* SMB block */
if (sc->alc_cdata.alc_smb_tag != NULL) {
- if (sc->alc_cdata.alc_smb_map != NULL)
+ if (sc->alc_rdata.alc_smb_paddr != 0)
bus_dmamap_unload(sc->alc_cdata.alc_smb_tag,
sc->alc_cdata.alc_smb_map);
- if (sc->alc_cdata.alc_smb_map != NULL &&
- sc->alc_rdata.alc_smb != NULL)
+ if (sc->alc_rdata.alc_smb != NULL)
bus_dmamem_free(sc->alc_cdata.alc_smb_tag,
sc->alc_rdata.alc_smb,
sc->alc_cdata.alc_smb_map);
+ sc->alc_rdata.alc_smb_paddr = 0;
sc->alc_rdata.alc_smb = NULL;
- sc->alc_cdata.alc_smb_map = NULL;
bus_dma_tag_destroy(sc->alc_cdata.alc_smb_tag);
sc->alc_cdata.alc_smb_tag = NULL;
}
OpenPOWER on IntegriCloud