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:
parent
31bcfda84e
commit
c34f1a08c6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=267580
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user