pipeline completion should check for valid pipeline status and return any errors for invalid status (like already completed pipelines).
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/audio/pipeline.c | 13 +++++++++++-- src/include/reef/audio/pipeline.h | 3 ++- src/include/reef/ipc.h | 2 +- src/ipc/intel-ipc.c | 4 +--- src/ipc/ipc.c | 6 +++--- 5 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/src/audio/pipeline.c b/src/audio/pipeline.c index 4e830c6..69dcce7 100644 --- a/src/audio/pipeline.c +++ b/src/audio/pipeline.c @@ -228,6 +228,7 @@ struct pipeline *pipeline_new(struct sof_ipc_pipe_new *pipe_desc,
/* init pipeline */ p->sched_comp = cd; + p->status = COMP_STATE_INIT; schedule_task_init(&p->pipe_task, pipeline_task, p); schedule_task_config(&p->pipe_task, pipe_desc->priority, pipe_desc->core); @@ -263,16 +264,24 @@ int pipeline_free(struct pipeline *p) return 0; }
-void pipeline_complete(struct pipeline *p) +int pipeline_complete(struct pipeline *p) { /* now walk downstream and upstream form "start" component and complete component task and pipeline init */
trace_pipe("com"); - tracev_value(p->ipc_pipe.pipeline_id); + trace_value(p->ipc_pipe.pipeline_id); + + /* cheeck whether pipeline is already complete */ + if (p->status != COMP_STATE_INIT) { + trace_pipe_error("epc"); + return -EINVAL; + }
connect_downstream(p, p->sched_comp, p->sched_comp); connect_upstream(p, p->sched_comp, p->sched_comp); + p->status = COMP_STATE_READY; + return 0; }
/* connect component -> buffer */ diff --git a/src/include/reef/audio/pipeline.h b/src/include/reef/audio/pipeline.h index 909f905..41cfffc 100644 --- a/src/include/reef/audio/pipeline.h +++ b/src/include/reef/audio/pipeline.h @@ -59,6 +59,7 @@ struct pipeline {
/* runtime status */ int32_t xrun_bytes; /* last xrun length */ + uint32_t status; /* pipeline status */
/* lists */ struct list_item comp_list; /* list of components */ @@ -86,7 +87,7 @@ int pipeline_comp_connect(struct pipeline *p, struct comp_dev *source_comp, struct comp_buffer *sink_buffer); int pipeline_buffer_connect(struct pipeline *p, struct comp_buffer *source_buffer, struct comp_dev *sink_comp); -void pipeline_complete(struct pipeline *p); +int pipeline_complete(struct pipeline *p);
/* pipeline parameters */ int pipeline_params(struct pipeline *p, struct comp_dev *cd, diff --git a/src/include/reef/ipc.h b/src/include/reef/ipc.h index 84a1dc1..a552626 100644 --- a/src/include/reef/ipc.h +++ b/src/include/reef/ipc.h @@ -148,7 +148,7 @@ int ipc_buffer_free(struct ipc *ipc, uint32_t buffer_id); */ int ipc_pipeline_new(struct ipc *ipc, struct sof_ipc_pipe_new *pipeline); int ipc_pipeline_free(struct ipc *ipc, uint32_t comp_id); -void ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id); +int ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id);
/* * Pipeline component and buffer connections. diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index 92dfd73..8a4fafd 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -787,9 +787,7 @@ static int ipc_glb_tplg_pipe_complete(uint32_t header)
trace_ipc("Ipc");
- ipc_pipeline_complete(_ipc, ipc_pipeline->comp_id); - - return 0; + return ipc_pipeline_complete(_ipc, ipc_pipeline->comp_id); }
static int ipc_glb_tplg_comp_connect(uint32_t header) diff --git a/src/ipc/ipc.c b/src/ipc/ipc.c index e589d56..966fafd 100644 --- a/src/ipc/ipc.c +++ b/src/ipc/ipc.c @@ -293,17 +293,17 @@ int ipc_pipeline_free(struct ipc *ipc, uint32_t comp_id) return 0; }
-void ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id) +int ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id) { struct ipc_comp_dev *ipc_pipe;
/* check whether pipeline exists */ ipc_pipe = ipc_get_comp(ipc, comp_id); if (ipc_pipe == NULL) - return; + return -EINVAL;
/* free buffer and remove from list */ - pipeline_complete(ipc_pipe->pipeline); + return pipeline_complete(ipc_pipe->pipeline); }
int ipc_comp_dai_config(struct ipc *ipc, struct sof_ipc_dai_config *config)