| 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); |
| } |
| } |