1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-17 10:26:15 +00:00

Fix teardown of static DMA allocations in various NIC drivers:

- Add missing calls to bus_dmamap_unload() in et(4).
- Check the bus address against 0 to decide when to call
  bus_dmamap_unload() instead of comparing the bus_dma map against NULL.
- Check the virtual address against NULL to decide when to call
  bus_dmamem_free() instead of comparing the bus_dma map against NULL.
- Don't clear bus_dma map pointers to NULL for static allocations.
  Instead, treat the value as completely opaque.
- Pass the correct virtual address to bus_dmamem_free() in wpi(4) instead
  of trying to free a pointer to the virtual address.

Reviewed by:	yongari
This commit is contained in:
John Baldwin 2014-06-17 14:47:49 +00:00
parent 31bcfda84e
commit c34f1a08c6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=267580
6 changed files with 87 additions and 60 deletions

View File

@ -1314,10 +1314,14 @@ cgem_detach(device_t dev)
}
/* Release DMA resources. */
if (sc->rxring_dma_map != NULL) {
if (sc->rxring != NULL) {
if (sc->rxring_physaddr != 0) {
bus_dmamap_unload(sc->desc_dma_tag, sc->rxring_dma_map);
sc->rxring_physaddr = 0;
}
bus_dmamem_free(sc->desc_dma_tag, sc->rxring,
sc->rxring_dma_map);
sc->rxring_dma_map = NULL;
sc->rxring = NULL;
for (i = 0; i < CGEM_NUM_RX_DESCS; i++)
if (sc->rxring_m_dmamap[i] != NULL) {
bus_dmamap_destroy(sc->mbuf_dma_tag,
@ -1325,10 +1329,14 @@ cgem_detach(device_t dev)
sc->rxring_m_dmamap[i] = NULL;
}
}
if (sc->txring_dma_map != NULL) {
if (sc->txring != NULL) {
if (sc->txring_physaddr != 0) {
bus_dmamap_unload(sc->desc_dma_tag, sc->txring_dma_map);
sc->txring_physaddr = 0;
}
bus_dmamem_free(sc->desc_dma_tag, sc->txring,
sc->txring_dma_map);
sc->txring_dma_map = NULL;
sc->txring = NULL;
for (i = 0; i < CGEM_NUM_TX_DESCS; i++)
if (sc->txring_m_dmamap[i] != NULL) {
bus_dmamap_destroy(sc->mbuf_dma_tag,

View File

@ -120,7 +120,7 @@ static int et_dma_ring_alloc(struct et_softc *, bus_size_t, bus_size_t,
bus_dma_tag_t *, uint8_t **, bus_dmamap_t *, bus_addr_t *,
const char *);
static void et_dma_ring_free(struct et_softc *, bus_dma_tag_t *, uint8_t **,
bus_dmamap_t *);
bus_dmamap_t, bus_addr_t *);
static void et_init_tx_ring(struct et_softc *);
static int et_init_rx_ring(struct et_softc *);
static void et_free_tx_ring(struct et_softc *);
@ -841,15 +841,16 @@ et_dma_ring_alloc(struct et_softc *sc, bus_size_t alignment, bus_size_t maxsize,
static void
et_dma_ring_free(struct et_softc *sc, bus_dma_tag_t *tag, uint8_t **ring,
bus_dmamap_t *map)
bus_dmamap_t map, bus_addr_t *paddr)
{
if (*map != NULL)
bus_dmamap_unload(*tag, *map);
if (*map != NULL && *ring != NULL) {
bus_dmamem_free(*tag, *ring, *map);
if (*paddr != 0) {
bus_dmamap_unload(*tag, map);
*paddr = 0;
}
if (*ring != NULL) {
bus_dmamem_free(*tag, *ring, map);
*ring = NULL;
*map = NULL;
}
if (*tag) {
bus_dma_tag_destroy(*tag);
@ -1101,27 +1102,27 @@ et_dma_free(struct et_softc *sc)
/* Destroy mini RX ring, ring 0. */
rx_ring = &sc->sc_rx_ring[0];
et_dma_ring_free(sc, &rx_ring->rr_dtag, (void *)&rx_ring->rr_desc,
&rx_ring->rr_dmap);
rx_ring->rr_dmap, &rx_ring->rr_paddr);
/* Destroy standard RX ring, ring 1. */
rx_ring = &sc->sc_rx_ring[1];
et_dma_ring_free(sc, &rx_ring->rr_dtag, (void *)&rx_ring->rr_desc,
&rx_ring->rr_dmap);
rx_ring->rr_dmap, &rx_ring->rr_paddr);
/* Destroy RX stat ring. */
rxst_ring = &sc->sc_rxstat_ring;
et_dma_ring_free(sc, &rxst_ring->rsr_dtag, (void *)&rxst_ring->rsr_stat,
&rxst_ring->rsr_dmap);
rxst_ring->rsr_dmap, &rxst_ring->rsr_paddr);
/* Destroy RX status block. */
rxsd = &sc->sc_rx_status;
et_dma_ring_free(sc, &rxst_ring->rsr_dtag, (void *)&rxst_ring->rsr_stat,
&rxst_ring->rsr_dmap);
rxst_ring->rsr_dmap, &rxst_ring->rsr_paddr);
/* Destroy TX ring. */
tx_ring = &sc->sc_tx_ring;
et_dma_ring_free(sc, &tx_ring->tr_dtag, (void *)&tx_ring->tr_desc,
&tx_ring->tr_dmap);
tx_ring->tr_dmap, &tx_ring->tr_paddr);
/* Destroy TX status block. */
txsd = &sc->sc_tx_status;
et_dma_ring_free(sc, &txsd->txsd_dtag, (void *)&txsd->txsd_status,
&txsd->txsd_dmap);
txsd->txsd_dmap, &txsd->txsd_paddr);
/* Destroy the parent tag. */
if (sc->sc_dtag) {

View File

@ -105,15 +105,15 @@ oce_dma_free(POCE_SOFTC sc, POCE_DMA_MEM dma)
if (dma->tag == NULL)
return;
if (dma->map != NULL) {
if (dma->paddr != 0) {
bus_dmamap_sync(dma->tag, dma->map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(dma->tag, dma->map);
dma->paddr = 0;
}
if (dma->ptr != NULL) {
bus_dmamem_free(dma->tag, dma->ptr, dma->map);
dma->map = NULL;
dma->ptr = NULL;
}

View File

@ -227,7 +227,7 @@ static void ti_dma_free(struct ti_softc *);
static int ti_dma_ring_alloc(struct ti_softc *, bus_size_t, bus_size_t,
bus_dma_tag_t *, uint8_t **, bus_dmamap_t *, bus_addr_t *, const char *);
static void ti_dma_ring_free(struct ti_softc *, bus_dma_tag_t *, uint8_t **,
bus_dmamap_t *);
bus_dmamap_t, bus_addr_t *);
static int ti_newbuf_std(struct ti_softc *, int);
static int ti_newbuf_mini(struct ti_softc *, int);
static int ti_newbuf_jumbo(struct ti_softc *, int, struct mbuf *);
@ -1035,15 +1035,16 @@ ti_dma_ring_alloc(struct ti_softc *sc, bus_size_t alignment, bus_size_t maxsize,
static void
ti_dma_ring_free(struct ti_softc *sc, bus_dma_tag_t *tag, uint8_t **ring,
bus_dmamap_t *map)
bus_dmamap_t map, bus_addr_t *paddr)
{
if (*map != NULL)
bus_dmamap_unload(*tag, *map);
if (*map != NULL && *ring != NULL) {
bus_dmamem_free(*tag, *ring, *map);
if (*paddr != 0) {
bus_dmamap_unload(*tag, map);
*paddr = 0;
}
if (*ring != NULL) {
bus_dmamem_free(*tag, *ring, map);
*ring = NULL;
*map = NULL;
}
if (*tag) {
bus_dma_tag_destroy(*tag);
@ -1336,32 +1337,39 @@ ti_dma_free(struct ti_softc *sc)
/* Destroy standard RX ring. */
ti_dma_ring_free(sc, &sc->ti_cdata.ti_rx_std_ring_tag,
(void *)&sc->ti_rdata.ti_rx_std_ring,
&sc->ti_cdata.ti_rx_std_ring_map);
sc->ti_cdata.ti_rx_std_ring_map,
&sc->ti_rdata.ti_rx_std_ring_paddr);
/* Destroy jumbo RX ring. */
ti_dma_ring_free(sc, &sc->ti_cdata.ti_rx_jumbo_ring_tag,
(void *)&sc->ti_rdata.ti_rx_jumbo_ring,
&sc->ti_cdata.ti_rx_jumbo_ring_map);
sc->ti_cdata.ti_rx_jumbo_ring_map,
&sc->ti_rdata.ti_rx_jumbo_ring_paddr);
/* Destroy mini RX ring. */
ti_dma_ring_free(sc, &sc->ti_cdata.ti_rx_mini_ring_tag,
(void *)&sc->ti_rdata.ti_rx_mini_ring,
&sc->ti_cdata.ti_rx_mini_ring_map);
sc->ti_cdata.ti_rx_mini_ring_map,
&sc->ti_rdata.ti_rx_mini_ring_paddr);
/* Destroy RX return ring. */
ti_dma_ring_free(sc, &sc->ti_cdata.ti_rx_return_ring_tag,
(void *)&sc->ti_rdata.ti_rx_return_ring,
&sc->ti_cdata.ti_rx_return_ring_map);
sc->ti_cdata.ti_rx_return_ring_map,
&sc->ti_rdata.ti_rx_return_ring_paddr);
/* Destroy TX ring. */
ti_dma_ring_free(sc, &sc->ti_cdata.ti_tx_ring_tag,
(void *)&sc->ti_rdata.ti_tx_ring, &sc->ti_cdata.ti_tx_ring_map);
(void *)&sc->ti_rdata.ti_tx_ring, sc->ti_cdata.ti_tx_ring_map,
&sc->ti_rdata.ti_tx_ring_paddr);
/* Destroy status block. */
ti_dma_ring_free(sc, &sc->ti_cdata.ti_status_tag,
(void *)&sc->ti_rdata.ti_status, &sc->ti_cdata.ti_status_map);
(void *)&sc->ti_rdata.ti_status, sc->ti_cdata.ti_status_map,
&sc->ti_rdata.ti_status_paddr);
/* Destroy event ring. */
ti_dma_ring_free(sc, &sc->ti_cdata.ti_event_ring_tag,
(void *)&sc->ti_rdata.ti_event_ring,
&sc->ti_cdata.ti_event_ring_map);
sc->ti_cdata.ti_event_ring_map, &sc->ti_rdata.ti_event_ring_paddr);
/* Destroy GIB */
ti_dma_ring_free(sc, &sc->ti_cdata.ti_gib_tag,
(void *)&sc->ti_rdata.ti_info, &sc->ti_cdata.ti_gib_map);
(void *)&sc->ti_rdata.ti_info, sc->ti_cdata.ti_gib_map,
&sc->ti_rdata.ti_info_paddr);
/* Destroy the parent tag. */
if (sc->ti_cdata.ti_parent_tag) {

View File

@ -169,8 +169,8 @@ static int txp_alloc_rings(struct txp_softc *);
static void txp_init_rings(struct txp_softc *);
static int txp_dma_alloc(struct txp_softc *, char *, bus_dma_tag_t *,
bus_size_t, bus_size_t, bus_dmamap_t *, void **, bus_size_t, bus_addr_t *);
static void txp_dma_free(struct txp_softc *, bus_dma_tag_t *, bus_dmamap_t *,
void **);
static void txp_dma_free(struct txp_softc *, bus_dma_tag_t *, bus_dmamap_t,
void **, bus_addr_t *);
static void txp_free_rings(struct txp_softc *);
static int txp_rxring_fill(struct txp_softc *);
static void txp_rxring_empty(struct txp_softc *);
@ -787,7 +787,7 @@ txp_download_fw_section(struct txp_softc *sc,
bus_dmamap_sync(sec_tag, sec_map, BUS_DMASYNC_POSTWRITE);
bail:
txp_dma_free(sc, &sec_tag, &sec_map, (void **)&sec_buf);
txp_dma_free(sc, &sec_tag, sec_map, (void **)&sec_buf, &sec_paddr);
return (err);
}
@ -1265,17 +1265,17 @@ txp_dma_alloc(struct txp_softc *sc, char *type, bus_dma_tag_t *tag,
}
static void
txp_dma_free(struct txp_softc *sc, bus_dma_tag_t *tag, bus_dmamap_t *map,
void **buf)
txp_dma_free(struct txp_softc *sc, bus_dma_tag_t *tag, bus_dmamap_t map,
void **buf, bus_addr_t *paddr)
{
if (*tag != NULL) {
if (*map != NULL)
bus_dmamap_unload(*tag, *map);
if (*map != NULL && buf != NULL)
bus_dmamem_free(*tag, *(uint8_t **)buf, *map);
if (*paddr != 0)
bus_dmamap_unload(*tag, map);
if (buf != NULL)
bus_dmamem_free(*tag, *(uint8_t **)buf, map);
*(uint8_t **)buf = NULL;
*map = NULL;
*paddr = 0;
bus_dma_tag_destroy(*tag);
*tag = NULL;
}
@ -1649,38 +1649,48 @@ txp_free_rings(struct txp_softc *sc)
/* Hi priority Tx ring. */
txp_dma_free(sc, &sc->sc_cdata.txp_txhiring_tag,
&sc->sc_cdata.txp_txhiring_map,
(void **)&sc->sc_ldata.txp_txhiring);
sc->sc_cdata.txp_txhiring_map,
(void **)&sc->sc_ldata.txp_txhiring,
&sc->sc_ldata.txp_txhiring_paddr);
/* Low priority Tx ring. */
txp_dma_free(sc, &sc->sc_cdata.txp_txloring_tag,
&sc->sc_cdata.txp_txloring_map,
(void **)&sc->sc_ldata.txp_txloring);
sc->sc_cdata.txp_txloring_map,
(void **)&sc->sc_ldata.txp_txloring,
&sc->sc_ldata.txp_txloring_paddr);
/* Hi priority Rx ring. */
txp_dma_free(sc, &sc->sc_cdata.txp_rxhiring_tag,
&sc->sc_cdata.txp_rxhiring_map,
(void **)&sc->sc_ldata.txp_rxhiring);
sc->sc_cdata.txp_rxhiring_map,
(void **)&sc->sc_ldata.txp_rxhiring,
&sc->sc_ldata.txp_rxhiring_paddr);
/* Low priority Rx ring. */
txp_dma_free(sc, &sc->sc_cdata.txp_rxloring_tag,
&sc->sc_cdata.txp_rxloring_map,
(void **)&sc->sc_ldata.txp_rxloring);
sc->sc_cdata.txp_rxloring_map,
(void **)&sc->sc_ldata.txp_rxloring,
&sc->sc_ldata.txp_rxloring_paddr);
/* Receive buffer ring. */
txp_dma_free(sc, &sc->sc_cdata.txp_rxbufs_tag,
&sc->sc_cdata.txp_rxbufs_map, (void **)&sc->sc_ldata.txp_rxbufs);
sc->sc_cdata.txp_rxbufs_map, (void **)&sc->sc_ldata.txp_rxbufs,
&sc->sc_ldata.txp_rxbufs_paddr);
/* Command ring. */
txp_dma_free(sc, &sc->sc_cdata.txp_cmdring_tag,
&sc->sc_cdata.txp_cmdring_map, (void **)&sc->sc_ldata.txp_cmdring);
sc->sc_cdata.txp_cmdring_map, (void **)&sc->sc_ldata.txp_cmdring,
&sc->sc_ldata.txp_cmdring_paddr);
/* Response ring. */
txp_dma_free(sc, &sc->sc_cdata.txp_rspring_tag,
&sc->sc_cdata.txp_rspring_map, (void **)&sc->sc_ldata.txp_rspring);
sc->sc_cdata.txp_rspring_map, (void **)&sc->sc_ldata.txp_rspring,
&sc->sc_ldata.txp_rspring_paddr);
/* Zero ring. */
txp_dma_free(sc, &sc->sc_cdata.txp_zero_tag,
&sc->sc_cdata.txp_zero_map, (void **)&sc->sc_ldata.txp_zero);
sc->sc_cdata.txp_zero_map, (void **)&sc->sc_ldata.txp_zero,
&sc->sc_ldata.txp_zero_paddr);
/* Host variables. */
txp_dma_free(sc, &sc->sc_cdata.txp_hostvar_tag,
&sc->sc_cdata.txp_hostvar_map, (void **)&sc->sc_ldata.txp_hostvar);
sc->sc_cdata.txp_hostvar_map, (void **)&sc->sc_ldata.txp_hostvar,
&sc->sc_ldata.txp_hostvar_paddr);
/* Boot record. */
txp_dma_free(sc, &sc->sc_cdata.txp_boot_tag,
&sc->sc_cdata.txp_boot_map, (void **)&sc->sc_ldata.txp_boot);
sc->sc_cdata.txp_boot_map, (void **)&sc->sc_ldata.txp_boot,
&sc->sc_ldata.txp_boot_paddr);
if (sc->sc_cdata.txp_parent_tag != NULL) {
bus_dma_tag_destroy(sc->sc_cdata.txp_parent_tag);

View File

@ -901,13 +901,13 @@ static void
wpi_dma_contig_free(struct wpi_dma_info *dma)
{
if (dma->tag) {
if (dma->map != NULL) {
if (dma->vaddr_start != NULL) {
if (dma->paddr_start != 0) {
bus_dmamap_sync(dma->tag, dma->map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(dma->tag, dma->map);
}
bus_dmamem_free(dma->tag, &dma->vaddr_start, dma->map);
bus_dmamem_free(dma->tag, dma->vaddr_start, dma->map);
}
bus_dma_tag_destroy(dma->tag);
}