[Sound-open-firmware] [PATCH] comp: host: make sure we have enough data to copy to/from host
Perform a check in the copy() function to make sure there is enough data to copy to/from host buffers.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/audio/host.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/src/audio/host.c b/src/audio/host.c index b467036..e71e95f 100644 --- a/src/audio/host.c +++ b/src/audio/host.c @@ -636,12 +636,30 @@ static int host_reset(struct comp_dev *dev) static int host_copy(struct comp_dev *dev) { struct host_data *hd = comp_get_drvdata(dev); + struct comp_buffer *dma_buffer; + struct dma_sg_elem *local_elem;
tracev_host("cpy");
if (dev->state != COMP_STATE_RUNNING) return 0;
+ local_elem = list_first_item(&hd->config.elem_list, + struct dma_sg_elem, list); + + /* enough free or avail to copy ? */ + if (dev->params.direction == SOF_IPC_STREAM_PLAYBACK) { + dma_buffer = list_first_item(&dev->bsink_list, + struct comp_buffer, source_list); + if (dma_buffer->free < local_elem->size) + return 0; + } else { + dma_buffer = list_first_item(&dev->bsource_list, + struct comp_buffer, sink_list); + if (dma_buffer->avail < local_elem->size) + return 0; + } + /* do DMA transfer */ dma_set_config(hd->dma, hd->chan, &hd->config); dma_start(hd->dma, hd->chan);
State this to be obvious. TODO: merge into 1 structure to enforce this.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/include/uapi/ipc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/include/uapi/ipc.h b/src/include/uapi/ipc.h index ae212be..003b96e 100644 --- a/src/include/uapi/ipc.h +++ b/src/include/uapi/ipc.h @@ -494,7 +494,7 @@ struct sof_ipc_buffer { } __attribute__((packed));
-/* generic component config data */ +/* generic component config data - must always be after struct sof_ipc_comp */ struct sof_ipc_comp_config { uint32_t periods_sink; /* 0 means variable */ uint32_t periods_source; /* 0 means variable */
Condense the buffer status data into fewer trace lines.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/include/reef/audio/buffer.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/include/reef/audio/buffer.h b/src/include/reef/audio/buffer.h index 0a4edd1..55e9de1 100644 --- a/src/include/reef/audio/buffer.h +++ b/src/include/reef/audio/buffer.h @@ -99,8 +99,8 @@ static inline void comp_update_buffer_produce(struct comp_buffer *buffer, buffer->free = buffer->size - buffer->avail;
tracev_buffer("pro"); - tracev_value(buffer->avail); - tracev_value(buffer->free); + tracev_value((buffer->avail << 12) | buffer->free); + tracev_value((buffer->ipc_buffer.comp.id << 16) | buffer->size); }
/* called by a component after consuming data from this buffer */ @@ -125,8 +125,8 @@ static inline void comp_update_buffer_consume(struct comp_buffer *buffer, buffer->free = buffer->size - buffer->avail;
tracev_buffer("con"); - tracev_value(buffer->avail); - tracev_value(buffer->free); + tracev_value((buffer->avail << 12) | buffer->free); + tracev_value((buffer->ipc_buffer.comp.id << 16) | buffer->size); }
/* get the max number of bytes that can be copied between sink and source */
Complain loudly in trace if we have components overruning or underruning buffers. Components should check buffer free/avail before use.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/include/reef/audio/buffer.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/src/include/reef/audio/buffer.h b/src/include/reef/audio/buffer.h index 55e9de1..9394d29 100644 --- a/src/include/reef/audio/buffer.h +++ b/src/include/reef/audio/buffer.h @@ -81,6 +81,14 @@ void buffer_free(struct comp_buffer *buffer); static inline void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes) { + /* complain loudly if component tries to overrun buffer + * components MUST check for free space first !! */ + if (bytes > buffer->free) { + trace_buffer_error("Xxo"); + trace_value(buffer->ipc_buffer.comp.id); + return; + } + buffer->w_ptr += bytes;
/* check for pointer wrap */ @@ -107,6 +115,14 @@ static inline void comp_update_buffer_produce(struct comp_buffer *buffer, static inline void comp_update_buffer_consume(struct comp_buffer *buffer, uint32_t bytes) { + /* complain loudly if component tries to underrun buffer + * components MUST check for avail space first !! */ + if (buffer->avail < bytes) { + trace_buffer_error("Xxu"); + trace_value(buffer->ipc_buffer.comp.id); + return; + } + buffer->r_ptr += bytes;
/* check for pointer wrap */
participants (1)
-
Liam Girdwood