[Sound-open-firmware] [PATCH v3 01/27] host: handle more possibility for playback spitting
Keyon Jie
yang.jie at linux.intel.com
Sat Feb 11 03:17:41 CET 2017
We may meet src buffer bound, sink buffer bound, and
splitting may not finish at one time DMA copy, that
is, next_size < split_remaining, ...
This patch added to handle all of those cases, and
prepare for the buffer read/write pointer checking
in future.
Signed-off-by: Keyon Jie <yang.jie at linux.intel.com>
---
src/audio/host.c | 63 ++++++++++++++++++++++++++------------------------------
1 file changed, 29 insertions(+), 34 deletions(-)
diff --git a/src/audio/host.c b/src/audio/host.c
index 217ad4f..5fc99fa 100644
--- a/src/audio/host.c
+++ b/src/audio/host.c
@@ -111,6 +111,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;
local_elem = list_first_item(&hd->config.elem_list,
struct dma_sg_elem, list);
@@ -148,48 +149,42 @@ static void host_dma_cb_playback(struct comp_dev *dev,
ipc_stream_send_notification(dev, &hd->cp);
}
- /* are we dealing with a split transfer */
- if (hd->split_remaining) {
-
- /* update local elem */
- local_elem->dest += local_elem->size;
+ local_elem->src += local_elem->size;
+ local_elem->dest += local_elem->size;
+ if (local_elem->src == hd->source->current_end) {
+ /* end of elem, so use next */
source_elem = next_buffer(hd->source);
hd->source->current_end = source_elem->src + source_elem->size;
local_elem->src = source_elem->src;
-
- /* set up next elem */
- local_elem->size = hd->split_remaining;
- hd->next_inc = hd->split_remaining;
- hd->split_remaining = 0;
-
- } else {
- /* destination is always DSP period size */
+ }
+ if (local_elem->dest == hd->sink->current_end) {
+ /* end of elem, so use next */
sink_elem = next_buffer(hd->sink);
-
+ hd->sink->current_end = sink_elem->dest + sink_elem->size;
local_elem->dest = sink_elem->dest;
- local_elem->size = hd->period->size;
- local_elem->src += hd->next_inc;
- hd->next_inc = hd->period->size;
-
- /* are we at end of elem */
- if (local_elem->src == hd->source->current_end) {
-
- /* end of elem, so use next */
- source_elem = next_buffer(hd->source);
- hd->source->current_end = source_elem->src + source_elem->size;
- local_elem->src = source_elem->src;
+ }
- } else if (local_elem->src + hd->period->size > hd->source->current_end) {
+ next_size = hd->period->size;
+ if (local_elem->src + hd->period->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;
- /* split copy - split transaction into 2 copies */
- local_elem->size = hd->source->current_end - local_elem->src;
- hd->split_remaining = hd->period->size - local_elem->size;
+ if (!hd->split_remaining) {
+ if (next_size != hd->period->size)
+ hd->split_remaining = hd->period->size - next_size;
+ } else {
+ next_size = next_size < hd->split_remaining ?
+ next_size : hd->split_remaining;
+ hd->split_remaining -= next_size;
+ }
+ local_elem->size = next_size;
- next->src = local_elem->src;
- next->dest = local_elem->dest;
- next->size = local_elem->size;
- return;
- }
+ if (hd->split_remaining) {
+ next->src = local_elem->src;
+ next->dest = local_elem->dest;
+ next->size = local_elem->size;
+ return;
}
/* let any waiters know we have completed */
--
2.7.4
More information about the Sound-open-firmware
mailing list