aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18/cx18-mailbox.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-mailbox.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-mailbox.c')
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 9d8220539be8..ca8d5f4b731a 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -163,7 +163,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order)
163 * it's filled in). 163 * it's filled in).
164 * 164 *
165 * cx18_queue_get buf() will detect the lost buffers 165 * cx18_queue_get buf() will detect the lost buffers
166 * and put them back in rotation eventually. 166 * and send them back to q_free for fw rotation eventually.
167 */ 167 */
168 if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) && 168 if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) &&
169 !(id >= s->mdl_offset && 169 !(id >= s->mdl_offset &&
@@ -174,24 +174,27 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order)
174 break; 174 break;
175 } 175 }
176 buf = cx18_queue_get_buf(s, id, mdl_ack->data_used); 176 buf = cx18_queue_get_buf(s, id, mdl_ack->data_used);
177
177 CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); 178 CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id);
178 if (buf == NULL) { 179 if (buf == NULL) {
179 CX18_WARN("Could not find buf %d for stream %s\n", 180 CX18_WARN("Could not find buf %d for stream %s\n",
180 id, s->name); 181 id, s->name);
182 /* Put as many buffers as possible back into fw use */
183 cx18_stream_load_fw_queue(s);
181 continue; 184 continue;
182 } 185 }
183 186
184 cx18_buf_sync_for_cpu(s, buf);
185 if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) { 187 if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) {
186 CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n", 188 CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n",
187 buf->bytesused); 189 buf->bytesused);
188
189 dvb_dmx_swfilter(&s->dvb.demux, buf->buf, 190 dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
190 buf->bytesused); 191 buf->bytesused);
191 192 }
193 /* Put as many buffers as possible back into fw use */
194 cx18_stream_load_fw_queue(s);
195 /* Put back TS buffer, since it was removed from all queues */
196 if (s->type == CX18_ENC_STREAM_TYPE_TS)
192 cx18_stream_put_buf_fw(s, buf); 197 cx18_stream_put_buf_fw(s, buf);
193 } else
194 set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
195 } 198 }
196 wake_up(&cx->dma_waitq); 199 wake_up(&cx->dma_waitq);
197 if (s->id != -1) 200 if (s->id != -1)