summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/cx18/cx18-mailbox.c
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2008-12-12 13:50:27 -0500
committerAndy Walls <awalls@radix.net>2008-12-12 13:50:27 -0500
commita00ab36aaa26baf7d88c5763300d06dc47327148 (patch)
treef777cd182398b9fea8de36afe01a1658afe0ec70 /linux/drivers/media/video/cx18/cx18-mailbox.c
parente5df23b4a1dac3d29cb3f3713ecebbac3fd550d1 (diff)
downloadmediapointer-dvb-s2-a00ab36aaa26baf7d88c5763300d06dc47327148.tar.gz
mediapointer-dvb-s2-a00ab36aaa26baf7d88c5763300d06dc47327148.tar.bz2
cx18: Avoid making firmware API calls with the queue lock held
From: Andy Walls <awalls@radix.net> 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. Priority: normal Signed-off-by: Andy Walls <awalls@radix.net>
Diffstat (limited to 'linux/drivers/media/video/cx18/cx18-mailbox.c')
-rw-r--r--linux/drivers/media/video/cx18/cx18-mailbox.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/linux/drivers/media/video/cx18/cx18-mailbox.c b/linux/drivers/media/video/cx18/cx18-mailbox.c
index 2f7060cc1..eb5c31af6 100644
--- a/linux/drivers/media/video/cx18/cx18-mailbox.c
+++ b/linux/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)