[Sound-open-firmware] [PATCH 1/2] comp: buffer: reject buffer size 0 requests.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/include/reef/audio/buffer.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/src/include/reef/audio/buffer.h b/src/include/reef/audio/buffer.h index e708ee2..ea9bd9c 100644 --- a/src/include/reef/audio/buffer.h +++ b/src/include/reef/audio/buffer.h @@ -183,6 +183,8 @@ static inline int buffer_set_size(struct comp_buffer *buffer, uint32_t size) { if (size > buffer->alloc_size) return -ENOMEM; + if (size == 0) + return -EINVAL;
buffer->end_addr = buffer->addr + size; buffer->size = size;
Make SRC, EQ and DAI use the new buffer size and reset position API calls rather than manually resetting and sizing the buffer.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/audio/dai.c | 24 +++++++++++------------- src/audio/eq_fir.c | 16 ++++++++++++++-- src/audio/eq_iir.c | 16 ++++++++++++++-- src/audio/src.c | 21 +++++++++++++++++---- 4 files changed, 56 insertions(+), 21 deletions(-)
diff --git a/src/audio/dai.c b/src/audio/dai.c index 30d3ae9..358ad2d 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -206,7 +206,7 @@ static int dai_playback_params(struct comp_dev *dev) struct dma_sg_elem *elem; struct comp_buffer *dma_buffer; struct list_item *elist, *tlist; - int i; + int i, err; uint32_t buffer_size;
/* set up DMA configuration */ @@ -223,15 +223,14 @@ static int dai_playback_params(struct comp_dev *dev) buffer_size = source_config->periods_sink * dd->period_bytes;
/* resize the buffer if space is available to align with period size */ - if (buffer_size == 0 || buffer_size > dma_buffer->alloc_size) { + err = buffer_set_size(dma_buffer, buffer_size); + if (err < 0) { trace_dai_error("ep1"); trace_value(source_config->periods_sink); trace_value(dd->period_bytes); trace_value(buffer_size); trace_value(dma_buffer->alloc_size); - return -EINVAL; - } else { - dma_buffer->size = buffer_size; + return err; }
if (list_is_empty(&config->elem_list)) { @@ -253,7 +252,7 @@ static int dai_playback_params(struct comp_dev *dev) }
/* set write pointer to start of buffer */ - dma_buffer->w_ptr = dma_buffer->addr; + buffer_reset_pos(dma_buffer);
return 0;
@@ -275,7 +274,7 @@ static int dai_capture_params(struct comp_dev *dev) struct dma_sg_elem *elem; struct comp_buffer *dma_buffer; struct list_item *elist, *tlist; - int i; + int i, err; uint32_t buffer_size;
/* set up DMA configuration */ @@ -292,15 +291,14 @@ static int dai_capture_params(struct comp_dev *dev) buffer_size = sink_config->periods_source * dd->period_bytes;
/* resize the buffer if space is available to align with period size */ - if (buffer_size == 0 || buffer_size > dma_buffer->alloc_size) { + err = buffer_set_size(dma_buffer, buffer_size); + if (err < 0) { trace_dai_error("ec1"); trace_value(sink_config->periods_sink); trace_value(dd->period_bytes); trace_value(buffer_size); trace_value(dma_buffer->alloc_size); - return -EINVAL; - } else { - dma_buffer->size = buffer_size; + return err; }
if (list_is_empty(&config->elem_list)) { @@ -319,8 +317,8 @@ static int dai_capture_params(struct comp_dev *dev) } }
- /* set write pointer to start of buffer */ - dma_buffer->r_ptr = dma_buffer->addr; + /* set read pointer to start of buffer */ + buffer_reset_pos(dma_buffer);
return 0;
diff --git a/src/audio/eq_fir.c b/src/audio/eq_fir.c index 98cd43e..ef3b7d2 100644 --- a/src/audio/eq_fir.c +++ b/src/audio/eq_fir.c @@ -110,10 +110,10 @@ static void eq_fir_s32_default(struct comp_dev *dev, /* Check both source and destination for wrap */ if (x > (int32_t *) source->end_addr) x = (int32_t *) - ((size_t) x - source->alloc_size); + ((size_t) x - source->size); if (snk > (int32_t *) sink->end_addr) y = (int32_t *) - ((size_t) y - sink->alloc_size); + ((size_t) y - sink->size); } }
@@ -286,12 +286,24 @@ static int eq_fir_params(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev); + struct comp_buffer *sink; + int err;
trace_src("par");
/* calculate period size based on config */ cd->period_bytes = dev->frames * dev->frame_bytes;
+ /* configure downstream buffer */ + sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + err = buffer_set_size(sink, cd->period_bytes * config->periods_sink); + if (err < 0) { + trace_src_error("eSz"); + return err; + } + + buffer_reset_pos(sink); + /* EQ supports only S32_LE PCM format */ if (config->frame_fmt != SOF_IPC_FRAME_S32_LE) return -EINVAL; diff --git a/src/audio/eq_iir.c b/src/audio/eq_iir.c index f75be71..66a613c 100644 --- a/src/audio/eq_iir.c +++ b/src/audio/eq_iir.c @@ -110,10 +110,10 @@ static void eq_iir_s32_default(struct comp_dev *dev, /* Check both source and destination for wrap */ if (x > (int32_t *) source->end_addr) x = (int32_t *) - ((size_t) x - source->alloc_size); + ((size_t) x - source->size); if (snk > (int32_t *) sink->end_addr) y = (int32_t *) - ((size_t) y - sink->alloc_size); + ((size_t) y - sink->size); } }
@@ -290,12 +290,24 @@ static int eq_iir_params(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev); + struct comp_buffer *sink; + int err;
trace_eq_iir("par");
/* calculate period size based on config */ cd->period_bytes = dev->frames * dev->frame_bytes;
+ /* configure downstream buffer */ + sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + err = buffer_set_size(sink, cd->period_bytes * config->periods_sink); + if (err < 0) { + trace_eq_iir_error("eSz"); + return err; + } + + buffer_reset_pos(sink); + /* EQ supports only S32_LE PCM format */ if (config->frame_fmt != SOF_IPC_FRAME_S32_LE) return -EINVAL; diff --git a/src/audio/src.c b/src/audio/src.c index ac2fbb5..54c798e 100644 --- a/src/audio/src.c +++ b/src/audio/src.c @@ -60,6 +60,7 @@ struct comp_data { int scratch_length; uint32_t sink_rate; uint32_t source_rate; + uint32_t period_bytes; /* sink period */ void (*src_func)(struct comp_dev *dev, struct comp_buffer *source, struct comp_buffer *sink, @@ -150,7 +151,7 @@ static void src_2s_s32_default(struct comp_dev *dev,
s1.times = n_times1; s1.x_end_addr = source->end_addr; - s1.x_size = source->alloc_size; + s1.x_size = source->size; s1.x_inc = nch; s1.y_end_addr = &cd->delay_lines[cd->scratch_length]; s1.y_size = STAGE_BUF_SIZE * sizeof(int32_t); @@ -161,7 +162,7 @@ static void src_2s_s32_default(struct comp_dev *dev, s2.x_size = STAGE_BUF_SIZE * sizeof(int32_t); s2.x_inc = 1; s2.y_end_addr = sink->end_addr; - s2.y_size = sink->alloc_size; + s2.y_size = sink->size; s2.y_inc = nch;
s1.x_rptr = src + nch - 1; @@ -219,10 +220,10 @@ static void src_1s_s32_default(struct comp_dev *dev,
s1.times = n_times; s1.x_end_addr = source->end_addr; - s1.x_size = source->alloc_size; + s1.x_size = source->size; s1.x_inc = nch; s1.y_end_addr = sink->end_addr; - s1.y_size = sink->alloc_size; + s1.y_size = sink->size; s1.y_inc = nch; s1.x_rptr = src + nch - 1; s1.y_wptr = dest + nch - 1; @@ -307,6 +308,7 @@ static int src_params(struct comp_dev *dev) struct sof_ipc_comp_src *src = COMP_GET_IPC(dev, sof_ipc_comp_src); struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev); struct comp_data *cd = comp_get_drvdata(dev); + struct comp_buffer *sink; struct src_alloc need; size_t delay_lines_size; uint32_t source_rate, sink_rate; @@ -401,6 +403,17 @@ static int src_params(struct comp_dev *dev) /* Need to compute this */ dev->frame_bytes = dev->params.sample_container_bytes * dev->params.channels; + cd->period_bytes = dev->frames * dev->frame_bytes; + + /* configure downstream buffer */ + sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + err = buffer_set_size(sink, cd->period_bytes * config->periods_sink); + if (err < 0) { + trace_src_error("eSz"); + return err; + } + + buffer_reset_pos(sink);
return 0; }
participants (1)
-
Liam Girdwood