[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