diff --git a/src/drivers/amd/common/acp_dma.c b/src/drivers/amd/common/acp_dma.c index bd1e6cba16a2..df68b8bebfb6 100644 --- a/src/drivers/amd/common/acp_dma.c +++ b/src/drivers/amd/common/acp_dma.c @@ -314,6 +314,7 @@ static int acp_dma_probe(struct dma *dma) sizeof(struct acp_dma_chan_data)); if (!acp_dma_chan) { rfree(dma->chan); + dma->chan = NULL; tr_err(&acpdma_tr, "acp-dma: %d channel %d private data alloc failed", dma->plat_data.id, channel); return -ENOMEM; diff --git a/src/drivers/dw/dma.c b/src/drivers/dw/dma.c index 102cbbe0d7ba..005980454798 100644 --- a/src/drivers/dw/dma.c +++ b/src/drivers/dw/dma.c @@ -532,8 +532,6 @@ static int dw_dma_set_config(struct dma_chan_data *channel, /* do we need to realloc descriptors */ if (config->elem_array.count != channel->desc_count) { - channel->desc_count = config->elem_array.count; - /* * Allocate descriptors for channel. They must be cache-line * size aligned to avoid corrupting adjacent memory when @@ -542,18 +540,25 @@ static int dw_dma_set_config(struct dma_chan_data *channel, * allocations on Zephyr to always force cache-line size * alignment. */ - if (dw_chan->lli) - rfree(dw_chan->lli); + rfree(dw_chan->lli); dw_chan->lli = rmalloc(SOF_MEM_FLAG_KERNEL | SOF_MEM_FLAG_COHERENT | SOF_MEM_FLAG_DMA, - sizeof(struct dw_lli) * channel->desc_count); + sizeof(struct dw_lli) * config->elem_array.count); if (!dw_chan->lli) { tr_err(&dwdma_tr, "dma %d channel %d lli alloc failed", channel->dma->plat_data.id, channel->index); + /* allocation failed, so dw_chan->lli is now NULL; reset + * the count to match it so a later config does not + * bzero() a NULL pointer using a stale count + */ + channel->desc_count = 0; ret = -ENOMEM; goto out; } + + /* only commit the new count once the buffer is allocated */ + channel->desc_count = config->elem_array.count; } /* initialise descriptors */ diff --git a/src/drivers/imx/sdma.c b/src/drivers/imx/sdma.c index a613f98b40c5..e14db9e6796e 100644 --- a/src/drivers/imx/sdma.c +++ b/src/drivers/imx/sdma.c @@ -443,7 +443,7 @@ static void sdma_enable_event(struct dma_chan_data *channel, int eventnum) tr_dbg(&sdma_tr, "channel %d, event %d", channel->index, eventnum); - if (eventnum < 0 || eventnum > SDMA_HWEVENTS_COUNT) + if (eventnum < 0 || eventnum >= SDMA_HWEVENTS_COUNT) return; /* No change if request is invalid */ dma_reg_update_bits(channel->dma, SDMA_CHNENBL(eventnum), @@ -461,7 +461,7 @@ static void sdma_disable_event(struct dma_chan_data *channel, int eventnum) { tr_dbg(&sdma_tr, "channel %d, event %d", channel->index, eventnum); - if (eventnum < 0 || eventnum > SDMA_HWEVENTS_COUNT) + if (eventnum < 0 || eventnum >= SDMA_HWEVENTS_COUNT) return; /* No change if request is invalid */ dma_reg_update_bits(channel->dma, SDMA_CHNENBL(eventnum),