summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2007-07-24 08:07:33 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-08-09 14:27:31 -0700
commit53a8e6e303cd55242bdfc5a1c898d21ce2805ac7 (patch)
treea63df8db9b45719bb15175b34684b0de587e1f97 /drivers/media
parent77157ba22f856f303d243d0093a88bac469c7a9c (diff)
V4L: ivtv: fix DMA timeout when capturing VBI + another stream
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. (cherry picked from commit dd1e729d63f74a0b6290ca417bafd3fd8665db50) Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org> Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index ba98bf054f2e..e83b49668507 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -403,6 +403,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);
@@ -597,7 +602,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);
@@ -634,7 +638,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);
}
}