summaryrefslogtreecommitdiff
path: root/drivers/media/video/cx18/cx18-mailbox.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-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)
* it's filled in).
*
* cx18_queue_get buf() will detect the lost buffers
- * and put them back in rotation eventually.
+ * and send them back to q_free for fw rotation eventually.
*/
if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) &&
!(id >= s->mdl_offset &&
@@ -174,24 +174,27 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order)
break;
}
buf = cx18_queue_get_buf(s, id, mdl_ack->data_used);
+
CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id);
if (buf == NULL) {
CX18_WARN("Could not find buf %d for stream %s\n",
id, s->name);
+ /* Put as many buffers as possible back into fw use */
+ cx18_stream_load_fw_queue(s);
continue;
}
- cx18_buf_sync_for_cpu(s, buf);
if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) {
CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n",
buf->bytesused);
-
dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
buf->bytesused);
-
+ }
+ /* Put as many buffers as possible back into fw use */
+ cx18_stream_load_fw_queue(s);
+ /* Put back TS buffer, since it was removed from all queues */
+ if (s->type == CX18_ENC_STREAM_TYPE_TS)
cx18_stream_put_buf_fw(s, buf);
- } else
- set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
}
wake_up(&cx->dma_waitq);
if (s->id != -1)