[Sound-open-firmware] [PATCH 11/25] host: add R/W pointers check for playback
Keyon Jie
yang.jie at linux.intel.com
Tue Feb 7 15:02:58 CET 2017
Here add R/W pointers check for playback, make sure the next
copy size is not bigger than the host avail bytes.
Signed-off-by: Keyon Jie <yang.jie at linux.intel.com>
---
src/audio/host.c | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/src/audio/host.c b/src/audio/host.c
index 2eaea6a..806a505 100644
--- a/src/audio/host.c
+++ b/src/audio/host.c
@@ -138,7 +138,7 @@ static void host_dma_cb_playback(struct comp_dev *dev,
struct host_data *hd = comp_get_drvdata(dev);
struct dma_sg_elem *local_elem, *source_elem, *sink_elem;
struct comp_buffer *dma_buffer;
- uint32_t next_size;
+ uint32_t next_size, need_copy = 0;
local_elem = list_first_item(&hd->config.elem_list,
struct dma_sg_elem, list);
@@ -158,7 +158,7 @@ static void host_dma_cb_playback(struct comp_dev *dev,
#endif
/* recalc available buffer space */
- comp_update_buffer_consume(hd->dma_buffer);
+ comp_update_buffer_produce(hd->dma_buffer);
/* new local period, update host buffer position blks */
hd->host_pos_read += local_elem->size;
@@ -166,8 +166,6 @@ static void host_dma_cb_playback(struct comp_dev *dev,
/* buffer overlap ? */
if (hd->host_pos_read >= hd->host_size)
hd->host_pos_read = 0;
- if (hd->host_pos)
- *hd->host_pos = hd->host_pos_read;
host_update_buffer_consume(hd);
/* send IPC message to driver if needed */
@@ -200,7 +198,7 @@ static void host_dma_cb_playback(struct comp_dev *dev,
}
next_size = hd->period->size;
- if (local_elem->src + hd->period->size > hd->source->current_end)
+ if (local_elem->src + next_size > hd->source->current_end)
next_size = hd->source->current_end - local_elem->src;
if (local_elem->dest + next_size > hd->sink->current_end)
next_size = hd->sink->current_end - local_elem->dest;
@@ -209,13 +207,33 @@ static void host_dma_cb_playback(struct comp_dev *dev,
if (next_size != hd->period->size)
hd->split_remaining = hd->period->size - next_size;
} else {
+ need_copy = 1;
next_size = next_size < hd->split_remaining ?
next_size : hd->split_remaining;
hd->split_remaining -= next_size;
}
local_elem->size = next_size;
- if (hd->split_remaining) {
+ /* check if avail is enough, otherwise, drain the last bytes and stop */
+ if (hd->host_avail < local_elem->size) {
+ if (hd->host_avail == 0) {
+ /* end of stream, stop */
+ next->size = 0;
+ need_copy = 0;
+ goto next_copy;
+ }
+
+ /* end of stream, drain the last bytes */
+ local_elem->size = hd->host_avail;
+
+ /* the split_remaining may not be copied anymore, but, let's make it
+ correct. we have only hd->host_avail data, so the split_remaining
+ should be (next_size - hd->host_avail) bigger */
+ hd->split_remaining += next_size - hd->host_avail;
+ }
+
+next_copy:
+ if (need_copy) {
next->src = local_elem->src;
next->dest = local_elem->dest;
next->size = local_elem->size;
@@ -266,7 +284,7 @@ static void host_dma_cb_capture(struct comp_dev *dev,
*hd->host_pos = hd->host_pos_read;
/* recalc available buffer space */
- comp_update_buffer_produce(hd->dma_buffer);
+ comp_update_buffer_consume(hd->dma_buffer);
/* send IPC message to driver if needed */
hd->host_period_pos += local_elem->size;
--
2.7.4
More information about the Sound-open-firmware
mailing list