aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18/cx18-queue.c
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2008-12-12 13:50:27 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:38:32 -0500
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 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,
117 } 117 }
118 118
119 buf->bytesused = bytesused; 119 buf->bytesused = bytesused;
120 /* Sync the buffer before we release the qlock */
121 cx18_buf_sync_for_cpu(s, buf);
120 if (s->type == CX18_ENC_STREAM_TYPE_TS) { 122 if (s->type == CX18_ENC_STREAM_TYPE_TS) {
121 /* 123 /*
122 * TS doesn't use q_full, but for sweeping up lost 124 * TS doesn't use q_full. As we pull the buffer off of
123 * buffers, we want the TS to requeue the buffer just 125 * the queue here, the caller will have to put it back.
124 * before sending the MDL back to the firmware, so we
125 * pull it off the list here.
126 */ 126 */
127 list_del_init(&buf->list); 127 list_del_init(&buf->list);
128 } else { 128 } else {
129 /* Move buffer from q_busy to q_full */
129 list_move_tail(&buf->list, &s->q_full.list); 130 list_move_tail(&buf->list, &s->q_full.list);
131 set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
130 s->q_full.bytesused += buf->bytesused; 132 s->q_full.bytesused += buf->bytesused;
131 atomic_inc(&s->q_full.buffers); 133 atomic_inc(&s->q_full.buffers);
132 } 134 }
@@ -135,9 +137,6 @@ struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id,
135 ret = buf; 137 ret = buf;
136 break; 138 break;
137 } 139 }
138
139 /* Put more buffers into the transfer rotation from q_free, if we can */
140 cx18_stream_load_fw_queue_nolock(s);
141 mutex_unlock(&s->qlock); 140 mutex_unlock(&s->qlock);
142 return ret; 141 return ret;
143} 142}