diff options
author | Andy Walls <awalls@radix.net> | 2008-12-12 21:50:27 +0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-30 14:38:32 +0300 |
commit | abb096de82f6f920a06ca935f76925261e66b556 (patch) | |
tree | 51f71ecb1d420083e54162b32733cf237b5b2393 /drivers/media/video/cx18/cx18-queue.c | |
parent | 765f6f612ef69ada79f7ec2627dcbc49276bf7b5 (diff) | |
download | linux-abb096de82f6f920a06ca935f76925261e66b556.tar.xz |
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.c | 13 |
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 40379d807cef..a6b0666f0ba3 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; } |