Skip to content

Commit 3681e09

Browse files
LaurentiuM1234dbaluta
authored andcommitted
audio: host-zephyr: Allocate DMA block configuration on heap
Currently, the DMA block configuration (struct dma_block_config) is placed on the stack during host_common_params(). Later on, host_copy_one_shot() tries to re-configure the DMAC driver using the same block configuration that's located in a stack frame that's no longer valid. As such, allocate a DMA block configuration on the heap during host_common_params() which can be used later on (e.g: during host_copy_one_shot()) to reconfigure the DMAC. Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
1 parent 1233a22 commit 3681e09

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

src/audio/host-zephyr.c

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev,
736736
struct dma_sg_config *config = &hd->config;
737737
struct dma_sg_elem *sg_elem;
738738
struct dma_config *dma_cfg = &hd->z_config;
739-
struct dma_block_config dma_block_cfg;
739+
struct dma_block_config *dma_block_cfg;
740740
uint32_t period_count;
741741
uint32_t period_bytes;
742742
uint32_t buffer_size;
@@ -890,12 +890,21 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev,
890890
hd->chan->period = config->period;
891891

892892
memset(dma_cfg, 0, sizeof(*dma_cfg));
893-
memset(&dma_block_cfg, 0, sizeof(dma_block_cfg));
893+
894+
dma_block_cfg = rzalloc(SOF_MEM_ZONE_RUNTIME, 0,
895+
SOF_MEM_CAPS_RAM,
896+
sizeof(*dma_block_cfg));
897+
898+
if (!dma_block_cfg) {
899+
comp_err(dev, "host_common_params: dma_block_config allocation failed");
900+
err = -ENOMEM;
901+
goto err_release_channel;
902+
}
894903

895904
dma_cfg->block_count = 1;
896905
dma_cfg->source_data_size = config->src_width;
897906
dma_cfg->dest_data_size = config->dest_width;
898-
dma_cfg->head_block = &dma_block_cfg;
907+
dma_cfg->head_block = dma_block_cfg;
899908

900909
for (i = 0; i < config->elem_array.count; i++) {
901910
sg_elem = config->elem_array.elems + i;
@@ -912,33 +921,31 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev,
912921
buffer_addr = addr;
913922
}
914923

915-
dma_block_cfg.block_size = buffer_bytes;
924+
dma_block_cfg->block_size = buffer_bytes;
916925

917926
switch (config->direction) {
918927
case DMA_DIR_LMEM_TO_HMEM:
919928
dma_cfg->channel_direction = MEMORY_TO_HOST;
920-
dma_block_cfg.source_address = buffer_addr;
929+
dma_block_cfg->source_address = buffer_addr;
921930
break;
922931
case DMA_DIR_HMEM_TO_LMEM:
923932
dma_cfg->channel_direction = HOST_TO_MEMORY;
924-
dma_block_cfg.dest_address = buffer_addr;
933+
dma_block_cfg->dest_address = buffer_addr;
925934
break;
926935
}
927936

928937
err = dma_config(hd->chan->dma->z_dev, hd->chan->index, dma_cfg);
929938
if (err < 0) {
930939
comp_err(dev, "host_params(): dma_config() failed");
931-
dma_release_channel(hd->dma->z_dev, hd->chan->index);
932-
hd->chan = NULL;
933-
return err;
940+
goto err_free_block_cfg;
934941
}
935942

936943
err = dma_get_attribute(hd->dma->z_dev, DMA_ATTR_COPY_ALIGNMENT,
937944
&hd->dma_copy_align);
938945

939946
if (err < 0) {
940947
comp_err(dev, "host_params(): dma_get_attribute()");
941-
return err;
948+
goto err_free_block_cfg;
942949
}
943950

944951
/* minimal copied data shouldn't be less than alignment */
@@ -952,6 +959,15 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev,
952959
host_copy_normal;
953960

954961
return 0;
962+
963+
err_free_block_cfg:
964+
dma_cfg->head_block = NULL;
965+
rfree(dma_block_cfg);
966+
err_release_channel:
967+
dma_release_channel(hd->dma->z_dev, hd->chan->index);
968+
hd->chan = NULL;
969+
970+
return err;
955971
}
956972

957973
static int host_params(struct comp_dev *dev,
@@ -1024,6 +1040,10 @@ void host_common_reset(struct host_data *hd, uint16_t state)
10241040
hd->dma_buffer = NULL;
10251041
}
10261042

1043+
/* free DMA block configuration */
1044+
if (hd->z_config.head_block)
1045+
rfree(hd->z_config.head_block);
1046+
10271047
/* reset buffer pointers */
10281048
hd->local_pos = 0;
10291049
hd->report_pos = 0;

0 commit comments

Comments
 (0)