summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18/cx18-queue.c
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2008-12-12 15:50:27 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 09:38:32 -0200
commitabb096de82f6f920a06ca935f76925261e66b556 (patch)
tree51f71ecb1d420083e54162b32733cf237b5b2393 /drivers/media/video/cx18/cx18-queue.c
parent765f6f612ef69ada79f7ec2627dcbc49276bf7b5 (diff)
V4L/DVB (9804): cx18: Avoid making firmware API calls with the queue lock held
cx18: Avoid making firmware API calls with the queue lock held. The source of MPEG strem corruption when not holding the queue lock was found to be that the MPEG buffer could be retrieved by the user app before it was sync'ed for the host cpu. Incoming buffers are now sync'ed before being put on q_full and releasing the queue lock. We can thus avoid the sometimes lengthy call to the firmware for CPU_DE_SET_MDL while holding the queue lock, so we can get better performance. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18/cx18-queue.c')
-rw-r--r--drivers/media/video/cx18/cx18-queue.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 40379d807ce..a6b0666f0ba 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -117,16 +117,18 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
}
buf->bytesused = bytesused;
+ /* Sync the buffer before we release the qlock */
+ cx18_buf_sync_for_cpu(s, buf);
if (s->type == CX18_ENC_STREAM_TYPE_TS) {
/*
- * TS doesn't use q_full, but for sweeping up lost
- * buffers, we want the TS to requeue the buffer just
- * before sending the MDL back to the firmware, so we
- * pull it off the list here.
+ * TS doesn't use q_full. As we pull the buffer off of
+ * the queue here, the caller will have to put it back.
*/
list_del_init(&buf->list);
} else {
+ /* Move buffer from q_busy to q_full */
list_move_tail(&buf->list, &s->q_full.list);
+ set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
s->q_full.bytesused += buf->bytesused;
atomic_inc(&s->q_full.buffers);
}
@@ -135,9 +137,6 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
ret = buf;
break;
}
-
- /* Put more buffers into the transfer rotation from q_free, if we can */
- cx18_stream_load_fw_queue_nolock(s);
mutex_unlock(&s->qlock);
return ret;
}