summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-12-13 17:13:45 +0100
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-07 10:14:25 +0100
commit88e268702bfba78448abd20a31129458707383aa (patch)
treea008036986dd5827c1883754e33ce6a744db8a44
parent[media] vb2: return ENOBUFS in start_streaming in case of too few buffers (diff)
downloadlinux-88e268702bfba78448abd20a31129458707383aa.tar.xz
linux-88e268702bfba78448abd20a31129458707383aa.zip
[media] vb2: Improve file I/O emulation to handle buffers in any order
videobuf2 file I/O emulation assumed that buffers dequeued from the driver would return in the order they were enqueued in the driver. Improve the file I/O emulator's book-keeping to remove this assumption. Also set the buf->size properly if a write() dequeues a buffer and the VB2_FILEIO_WRITE_IMMEDIATELY flag is set. Based on an initial patch by Andy Walls. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Reviewed-by: Andy Walls <awalls@md.metrocast.net> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 2552c4626826..098df28b021a 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -2355,6 +2355,7 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read)
goto err_reqbufs;
fileio->bufs[i].queued = 1;
}
+ fileio->index = q->num_buffers;
}
/*
@@ -2430,15 +2431,11 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
}
fileio = q->fileio;
- index = fileio->index;
- buf = &fileio->bufs[index];
-
/*
* Check if we need to dequeue the buffer.
*/
- if (buf->queued) {
- struct vb2_buffer *vb;
-
+ index = fileio->index;
+ if (index >= q->num_buffers) {
/*
* Call vb2_dqbuf to get buffer back.
*/
@@ -2451,12 +2448,18 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
return ret;
fileio->dq_count += 1;
+ index = fileio->b.index;
+ buf = &fileio->bufs[index];
+
/*
* Get number of bytes filled by the driver
*/
- vb = q->bufs[index];
- buf->size = vb2_get_plane_payload(vb, 0);
+ buf->pos = 0;
buf->queued = 0;
+ buf->size = read ? vb2_get_plane_payload(q->bufs[index], 0)
+ : vb2_plane_size(q->bufs[index], 0);
+ } else {
+ buf = &fileio->bufs[index];
}
/*
@@ -2519,13 +2522,10 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_
*/
buf->pos = 0;
buf->queued = 1;
- buf->size = q->bufs[0]->v4l2_planes[0].length;
+ buf->size = vb2_plane_size(q->bufs[index], 0);
fileio->q_count += 1;
-
- /*
- * Switch to the next buffer
- */
- fileio->index = (index + 1) % q->num_buffers;
+ if (fileio->index < q->num_buffers)
+ fileio->index++;
}
/*