summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/ivtv/ivtv-irq.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2007-07-18 18:22:06 +0200
committerHans Verkuil <hverkuil@xs4all.nl>2007-07-18 18:22:06 +0200
commitf9411f6ddc7998112b5d287e9ab1de134358cb33 (patch)
treeda28e5c98a155c2b772c9b0b92ea903a33ef1293 /linux/drivers/media/video/ivtv/ivtv-irq.c
parent3a53c3856fb09898dd3711f36b0fd62a945005b4 (diff)
downloadmediapointer-dvb-s2-f9411f6ddc7998112b5d287e9ab1de134358cb33.tar.gz
mediapointer-dvb-s2-f9411f6ddc7998112b5d287e9ab1de134358cb33.tar.bz2
ivtv: fix DMA timeout when capturing VBI + another stream
From: Hans Verkuil <hverkuil@xs4all.nl> The VBI DMA is handled in a special way and is marked with a bit. However, that bit was set at the wrong time and could be cleared by mistake if a PCM (or other) DMA request would arrive before the VBI DMA was completed. So on completion of the VBI DMA the driver no longer knew that that DMA transfer was for VBI data. And this in turn caused havoc with the card's DMA engine. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Diffstat (limited to 'linux/drivers/media/video/ivtv/ivtv-irq.c')
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-irq.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/linux/drivers/media/video/ivtv/ivtv-irq.c b/linux/drivers/media/video/ivtv/ivtv-irq.c
index 7996371ec..a7fe4c51e 100644
--- a/linux/drivers/media/video/ivtv/ivtv-irq.c
+++ b/linux/drivers/media/video/ivtv/ivtv-irq.c
@@ -409,6 +409,11 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
/* Mark last buffer size for Interrupt flag */
s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
+ if (s->type == IVTV_ENC_STREAM_TYPE_VBI)
+ set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
+ else
+ clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
+
if (ivtv_use_pio(s)) {
for (i = 0; i < s->SG_length; i++) {
s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src);
@@ -603,7 +608,6 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv)
data[0], data[1], data[2]);
return;
}
- clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
s = &itv->streams[ivtv_stream_map[data[0]]];
if (!stream_enc_dma_append(s, data)) {
set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
@@ -640,7 +644,6 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
then start a DMA request for just the VBI data. */
if (!stream_enc_dma_append(s, data) &&
!test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) {
- set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
}
}