[Sound-open-firmware] [PATCH] Remove "void*" pointer of parse_page_descriptors().
From: Yan Wang yan.wang@linux.intel.com
Compiler cannot check the real type of "void*" pointer. It is easy to cause pointer conversion error. So use the pointer of element list of struct dma_sg_elem instead of void* pointer.
Signed-off-by: Yan Wang yan.wang@linux.intel.com --- src/ipc/intel-ipc.c | 106 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 77 insertions(+), 29 deletions(-)
diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index 04e8c1b..373cc26 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -158,24 +158,13 @@ out: * page table entry and adding each elem to a list in struct dma_sg_config. */ static int parse_page_descriptors(struct intel_ipc_data *iipc, - struct sof_ipc_host_buffer *ring, void *data, uint32_t is_trace) + struct sof_ipc_host_buffer *ring, struct list_item *elem_list, + uint32_t is_src) { - struct comp_dev* cd = NULL; - struct sof_ipc_comp_host *host = NULL; - struct dma_trace_data *d = NULL; - struct dma_sg_elem elem; int i; - int err; uint32_t idx; uint32_t phy_addr; - - elem.size = HOST_PAGE_SIZE; - if (is_trace) - d = (struct dma_trace_data *)data; - else { - cd = (struct comp_dev *)data; - host = (struct sof_ipc_comp_host *)&cd->comp; - } + struct dma_sg_elem *e;
/* the ring size may be not multiple of the page size, the last * page may be not full used. The used size should be in range @@ -189,7 +178,6 @@ static int parse_page_descriptors(struct intel_ipc_data *iipc, }
for (i = 0; i < ring->pages; i++) { - idx = (((i << 2) + i)) >> 1; phy_addr = iipc->page_table[idx] | (iipc->page_table[idx + 1] << 8) | (iipc->page_table[idx + 2] << 16); @@ -200,23 +188,23 @@ static int parse_page_descriptors(struct intel_ipc_data *iipc, phy_addr <<= 12; phy_addr &= 0xfffff000;
- if (!is_trace && host->direction == SOF_IPC_STREAM_PLAYBACK) - elem.src = phy_addr; + /* allocate new host DMA elem and add it to our list */ + e = rzalloc(RZONE_RUNTIME, RFLAGS_NONE, sizeof(*e)); + if (!e) + return -ENOMEM; + + if (is_src) + e->src = phy_addr; else - elem.dest = phy_addr; + e->dest = phy_addr;
/* the last page may be not full used */ if (i == (ring->pages - 1)) - elem.size = ring->size - HOST_PAGE_SIZE * i; - - if (is_trace) - err = dma_trace_host_buffer(d, &elem, ring->size); + e->size = ring->size - HOST_PAGE_SIZE * i; else - err = comp_host_buffer(cd, &elem, ring->size); - if (err < 0) { - trace_ipc_error("ePb"); - return err; - } + e->size = HOST_PAGE_SIZE; + + list_item_append(&e->list, elem_list); }
return 0; @@ -232,6 +220,12 @@ static int ipc_stream_pcm_params(uint32_t stream) { #ifdef CONFIG_HOST_PTABLE struct intel_ipc_data *iipc = ipc_get_drvdata(_ipc); + struct sof_ipc_comp_host *host = NULL; + uint32_t is_src; + struct list_item elem_list; + struct dma_sg_elem *elem; + struct list_item *plist; + uint32_t ring_size; #endif struct sof_ipc_pcm_params *pcm_params = _ipc->comp_data; struct sof_ipc_pcm_params_reply reply; @@ -269,12 +263,30 @@ static int ipc_stream_pcm_params(uint32_t stream) }
/* Parse host tables */ + host = (struct sof_ipc_comp_host *)&cd->comp; + is_src = (host->direction == SOF_IPC_STREAM_PLAYBACK); + ring_size = pcm_params->params.buffer.size; + list_init(&elem_list); + err = parse_page_descriptors(iipc, &pcm_params->params.buffer, - pcm_dev->cd, 0); + &elem_list, is_src); if (err < 0) { trace_ipc_error("eAP"); goto error; } + + list_for_item(plist, &elem_list) { + elem = container_of(plist, struct dma_sg_elem, list); + + err = comp_host_buffer(cd, elem, ring_size); + if (err < 0) { + trace_ipc_error("ePb"); + goto error; + } + + list_item_del(&elem->list); + rfree(elem); + } #endif
/* configure pipeline audio params */ @@ -302,6 +314,14 @@ static int ipc_stream_pcm_params(uint32_t stream) return 1;
error: +#ifdef CONFIG_HOST_PTABLE + list_for_item(plist, &elem_list) { + elem = container_of(plist, struct dma_sg_elem, list); + list_item_del(&elem->list); + rfree(elem); + } +#endif + err = pipeline_reset(pcm_dev->cd->pipeline, pcm_dev->cd); if (err < 0) trace_ipc_error("eA!"); @@ -602,6 +622,10 @@ static int ipc_dma_trace_config(uint32_t header) #ifdef CONFIG_HOST_PTABLE struct intel_ipc_data *iipc = ipc_get_drvdata(_ipc); struct sof_ipc_dma_trace_params *params = _ipc->comp_data; + struct list_item elem_list; + struct dma_sg_elem *elem; + struct list_item *plist; + uint32_t ring_size; #endif struct sof_ipc_reply reply; int err; @@ -618,12 +642,28 @@ static int ipc_dma_trace_config(uint32_t header) trace_ipc("DAg");
/* Parse host tables */ + ring_size = params->buffer.size; + list_init(&elem_list); + err = parse_page_descriptors(iipc, ¶ms->buffer, - _ipc->dmat, 1); + &elem_list, 0); if (err < 0) { trace_ipc_error("ePP"); goto error; } + + list_for_item(plist, &elem_list) { + elem = container_of(plist, struct dma_sg_elem, list); + + err = dma_trace_host_buffer(_ipc->dmat, elem, ring_size); + if (err < 0) { + trace_ipc_error("ePb"); + goto error; + } + + list_item_del(&elem->list); + rfree(elem); + } #endif trace_ipc("DAp");
@@ -639,6 +679,14 @@ static int ipc_dma_trace_config(uint32_t header) return 0;
error: +#ifdef CONFIG_HOST_PTABLE + list_for_item(plist, &elem_list) { + elem = container_of(plist, struct dma_sg_elem, list); + list_item_del(&elem->list); + rfree(elem); + } +#endif + if (err < 0) trace_ipc_error("eA!"); return -EINVAL;
On Fri, 2018-03-02 at 16:00 +0800, yan.wang@linux.intel.com wrote:
From: Yan Wang yan.wang@linux.intel.com
Compiler cannot check the real type of "void*" pointer. It is easy to cause pointer conversion error. So use the pointer of element list of struct dma_sg_elem instead of void* pointer.
Signed-off-by: Yan Wang yan.wang@linux.intel.com
src/ipc/intel-ipc.c | 106 ++++++++++++++++++++++++++++++++++++++--------------
Applied with some minor modifications to pass stream direction directly.
Thanks
Liam
On Fri, 2018-03-02 at 16:00 +0800, yan.wang@linux.intel.com wrote:
From: Yan Wang yan.wang@linux.intel.com
Compiler cannot check the real type of "void*" pointer. It is easy to cause pointer conversion error. So use the pointer of element list of struct dma_sg_elem instead of void* pointer.
Signed-off-by: Yan Wang yan.wang@linux.intel.com
src/ipc/intel-ipc.c | 106 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 77 insertions(+), 29 deletions(-)
Applied.
Thanks
Liam
participants (2)
-
Liam Girdwood
-
yan.wang@linux.intel.com