blob: 1a6b4e9a92299ddcce749861c373654fe670904f [file] [log] [blame]
From stable-bounces@linux.kernel.org Tue Jul 24 05:07:52 2007
From: Hans Verkuil <hverkuil@xs4all.nl>
Date: Tue, 24 Jul 2007 08:07:33 -0400
Subject: V4L: ivtv: fix DMA timeout when capturing VBI + another stream
To: stable@kernel.org
Message-ID: <46A5EB85.701@linuxtv.org>
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.
(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>
---
drivers/media/video/ivtv/ivtv-irq.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
--- 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 iv
/* 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(struc
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
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);
}
}