[Sound-open-firmware] [PATCH] Remove "void*" pointer of parse_page_descriptors().

yan.wang at linux.intel.com yan.wang at linux.intel.com
Fri Mar 2 09:00:40 CET 2018


From: Yan Wang <yan.wang at 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 at 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, &params->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;
-- 
2.14.3



More information about the Sound-open-firmware mailing list