[Sound-open-firmware] [PATCH] ipc: improve error reporting and return values

Liam Girdwood liam.r.girdwood at linux.intel.com
Tue Aug 15 17:39:27 CEST 2017


Improve IPC error reporting and values to host by tracing all failures
and making sure errors are returned when detected.

Signed-off-by: Liam Girdwood <liam.r.girdwood at linux.intel.com>
---
 src/ipc/byt-ipc.c   | 37 ++++++++++++++++++++++++++++---------
 src/ipc/intel-ipc.c | 45 ++++++++++++++++++++++++++++-----------------
 2 files changed, 56 insertions(+), 26 deletions(-)

diff --git a/src/ipc/byt-ipc.c b/src/ipc/byt-ipc.c
index b73ad05..4fd5d62 100644
--- a/src/ipc/byt-ipc.c
+++ b/src/ipc/byt-ipc.c
@@ -78,6 +78,7 @@ static void do_notify(void)
 
 out:
 	spin_unlock_irq(&_ipc->lock, flags);
+
 	/* clear DONE bit - tell Host we have completed */
 	shim_write(SHIM_IPCDH, shim_read(SHIM_IPCDH) & ~SHIM_IPCDH_DONE);
 
@@ -121,30 +122,48 @@ static void irq_handler(void *arg)
 void ipc_platform_do_cmd(struct ipc *ipc)
 {
 	struct intel_ipc_data *iipc = ipc_get_drvdata(ipc);
-	uint32_t ipcxh;//, status;
+	struct sof_ipc_reply reply;
+	uint32_t ipcxh;
+	int32_t err;
 
 	trace_ipc("Cmd");
-	//trace_value(_ipc->host_msg);
 
-	/* TODO: handle error with reply data in mailbox */
-	ipc_cmd();
+	/* clear old mailbox return values */
+	reply.hdr.cmd = SOF_IPC_GLB_REPLY;
+	reply.hdr.size = sizeof(reply);
+	reply.error = 0;
+	mailbox_outbox_write(0, &reply, sizeof(reply));
+
+	/* perform command and return any error */
+	err = ipc_cmd();
+	if (err < 0) {
+		/* read component values from the inbox */
+		reply.error = err;
+
+		/* write error back to outbox */
+		mailbox_outbox_write(0, &reply, sizeof(reply));
+	}
 	ipc->host_pending = 0;
-	trace_ipc("CmD");
+
 	/* clear BUSY bit and set DONE bit - accept new messages */
 	ipcxh = shim_read(SHIM_IPCXH);
 	ipcxh &= ~SHIM_IPCXH_BUSY;
-	ipcxh |= SHIM_IPCXH_DONE;// | status;
+	ipcxh |= SHIM_IPCXH_DONE;
 	shim_write(SHIM_IPCXH, ipcxh);
 
+	/* unmask busy interrupt */
+	shim_write(SHIM_IMRD, shim_read(SHIM_IMRD) & ~SHIM_IMRD_BUSY);
+
 	// TODO: signal audio work to enter D3 in normal context
 	/* are we about to enter D3 ? */
 	if (iipc->pm_prepare_D3) {
-		while (1)
+		while (1) {
+			trace_ipc("pme");
 			wait_for_interrupt(0);
+		}
 	}
 
-	/* unmask busy interrupt */
-	shim_write(SHIM_IMRD, shim_read(SHIM_IMRD) & ~SHIM_IMRD_BUSY);
+	trace_ipc("CmD");
 }
 
 void ipc_platform_send_msg(struct ipc *ipc)
diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c
index dbb0db1..2d73fbb 100644
--- a/src/ipc/intel-ipc.c
+++ b/src/ipc/intel-ipc.c
@@ -255,7 +255,9 @@ static int ipc_stream_pcm_params(uint32_t stream)
 	return 0;
 
 error:
-	pipeline_reset(pcm_dev->cd->pipeline, pcm_dev->cd);
+	err = pipeline_reset(pcm_dev->cd->pipeline, pcm_dev->cd);
+	if (err < 0)
+		trace_ipc_error("eA!");
 	return -EINVAL;
 }
 
@@ -269,11 +271,14 @@ static int ipc_stream_pcm_free(uint32_t header)
 
 	/* get the pcm_dev */
 	pcm_dev = ipc_get_comp(_ipc, free_req->comp_id);
-	if (pcm_dev == NULL)
-		return ENODEV;
+	if (pcm_dev == NULL) {
+		trace_ipc_error("eFr");
+		return -ENODEV;
+	}
 
 	/* reset the pipeline */
-	pipeline_reset(pcm_dev->cd->pipeline, pcm_dev->cd);
+	return pipeline_reset(pcm_dev->cd->pipeline, pcm_dev->cd);
+}
 
 /* get stream position */
 static int ipc_stream_position(uint32_t header)
@@ -326,7 +331,7 @@ static int ipc_stream_trigger(uint32_t header)
 	uint32_t cmd = COMP_CMD_RELEASE;
 	struct sof_ipc_stream *stream  = _ipc->comp_data;
 	uint32_t ipc_cmd = (header & SOF_CMD_TYPE_MASK) >> SOF_CMD_TYPE_SHIFT;
-	int err;
+	int ret;
 
 	trace_ipc("tri");
 
@@ -334,7 +339,7 @@ static int ipc_stream_trigger(uint32_t header)
 	pcm_dev = ipc_get_comp(_ipc, stream->comp_id);
 	if (pcm_dev == NULL) {
 		trace_ipc_error("eRg");
-		goto error;
+		return -ENODEV;
 	}
 
 	switch (ipc_cmd) {
@@ -359,15 +364,13 @@ static int ipc_stream_trigger(uint32_t header)
 	}
 
 	/* trigger the component */
-	err = pipeline_cmd(pcm_dev->cd->pipeline, pcm_dev->cd,
+	ret = pipeline_cmd(pcm_dev->cd->pipeline, pcm_dev->cd,
 			cmd, NULL);
-	if (err < 0) {
+	if (ret < 0) {
 		trace_ipc_error("eRc");
-		goto error;
 	}
 
-error:
-	return 0;
+	return ret;
 }
 
 static int ipc_glb_stream_message(uint32_t header)
@@ -532,7 +535,7 @@ static int ipc_glb_pm_message(uint32_t header)
 	case iCS(SOF_IPC_PM_CLK_GET):
 	case iCS(SOF_IPC_PM_CLK_REQ):
 	default:
-		return -ENOMEM;
+		return -EINVAL;
 	}
 }
 
@@ -545,12 +548,14 @@ static int ipc_comp_set_value(uint32_t header, uint32_t cmd)
 	struct ipc_comp_dev *stream_dev;
 	struct sof_ipc_ctrl_values *values = _ipc->comp_data;
 
-	//trace_ipc("VoS");
+	trace_ipc("VoS");
 
 	/* get the component */
 	stream_dev = ipc_get_comp(_ipc, values->comp_id);
-	if (stream_dev == NULL)
+	if (stream_dev == NULL) {
+		trace_ipc_error("eVs");
 		return -ENODEV;
+	}
 
 	/* set component values */
 	return comp_cmd(stream_dev->cd, cmd, values);
@@ -566,13 +571,17 @@ static int ipc_comp_get_value(uint32_t header, uint32_t cmd)
 
 	/* get the component */
 	stream_dev = ipc_get_comp(_ipc, values->comp_id);
-	if (stream_dev == NULL)
+	if (stream_dev == NULL){
+		trace_ipc_error("eVg");
 		return -ENODEV;
+	}
 	
 	/* get component values */
 	ret = comp_cmd(stream_dev->cd, COMP_CMD_VOLUME, values);
-	if (ret < 0)
+	if (ret < 0) {
+		trace_ipc_error("eVG");
 		return ret;
+	}
 
 	/* write component values to the outbox */
 	mailbox_outbox_write(values, 0, sizeof(*values));
@@ -618,8 +627,10 @@ static int ipc_glb_tplg_comp_new(uint32_t header)
 
 	/* register component */
 	ret = ipc_comp_new(_ipc, comp);
-	if (ret < 0)
+	if (ret < 0) {
+		trace_ipc_error("etc");
 		return ret;
+	}
 
 	/* write component values to the outbox */
 	mailbox_outbox_write(0, &reply, sizeof(reply));
-- 
2.11.0



More information about the Sound-open-firmware mailing list