v4l2: Add mutex to streamon() and dqbuf()in v4l2 framework.

When v4l2 streamon() is called the framework moves to streamon state,
after queueing the buffer. A state check is performed during dqbuf().
Sometimes when dqbuf() is called streamon() function has not completed
setting the state transisiton flag. This results in failure to dqbuf() as
the framework has not moved to streamon. This patch adds a mutex
around state transitions and dqbuf() calls.

Change-Id: I0eadc4aaffbed62facd7dd250893e50448d7e52b
Signed-off-by: Ashray Kulkarni <ashrayk@codeaurora.org>
This commit is contained in:
Ashray Kulkarni
2012-08-16 22:44:34 -07:00
committed by Stephen Boyd
parent 064dfc9c9e
commit 90752ebfb4
2 changed files with 8 additions and 2 deletions

View File

@@ -1330,12 +1330,14 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
return -EINVAL;
}
mutex_lock(&q->q_lock);
ret = __vb2_get_done_vb(q, &vb, nonblocking);
if (ret < 0) {
dprintk(1, "dqbuf: error getting next done buffer\n");
mutex_unlock(&q->q_lock);
return ret;
}
mutex_unlock(&q->q_lock);
ret = call_qop(q, buf_finish, vb);
if (ret) {
dprintk(1, "dqbuf: buffer finish failed\n");
@@ -1447,15 +1449,17 @@ int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
/*
* Let driver notice that streaming state has been enabled.
*/
mutex_lock(&q->q_lock);
ret = call_qop(q, start_streaming, q, atomic_read(&q->queued_count));
if (ret) {
dprintk(1, "streamon: driver refused to start streaming\n");
__vb2_queue_cancel(q);
mutex_unlock(&q->q_lock);
return ret;
}
q->streaming = 1;
mutex_unlock(&q->q_lock);
dprintk(3, "Streamon successful\n");
return 0;
}
@@ -1729,6 +1733,7 @@ int vb2_queue_init(struct vb2_queue *q)
INIT_LIST_HEAD(&q->queued_list);
INIT_LIST_HEAD(&q->done_list);
spin_lock_init(&q->done_lock);
mutex_init(&q->q_lock);
init_waitqueue_head(&q->done_wq);
if (q->buf_struct_size == 0)

View File

@@ -289,6 +289,7 @@ struct vb2_queue {
atomic_t queued_count;
struct list_head done_list;
spinlock_t done_lock;
struct mutex q_lock;
wait_queue_head_t done_wq;
void *alloc_ctx[VIDEO_MAX_PLANES];