aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2007-07-18 12:22:06 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-07-20 16:35:52 -0400
commitdd1e729d63f74a0b6290ca417bafd3fd8665db50 (patch)
treedd2fe5f70269c9ea9b407dfac2ecd8a20fde209e
parent201700d3544c653d453716a60976efe1987110af (diff)
V4L/DVB (5866): 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. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-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 14f35df05fa2..fcd6e7f5f121 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)
403 /* Mark last buffer size for Interrupt flag */ 403 /* Mark last buffer size for Interrupt flag */
404 s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000); 404 s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
405 405
406 if (s->type == IVTV_ENC_STREAM_TYPE_VBI)
407 set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
408 else
409 clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
410
406 if (ivtv_use_pio(s)) { 411 if (ivtv_use_pio(s)) {
407 for (i = 0; i < s->SG_length; i++) { 412 for (i = 0; i < s->SG_length; i++) {
408 s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src); 413 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)
597 data[0], data[1], data[2]); 602 data[0], data[1], data[2]);
598 return; 603 return;
599 } 604 }
600 clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
601 s = &itv->streams[ivtv_stream_map[data[0]]]; 605 s = &itv->streams[ivtv_stream_map[data[0]]];
602 if (!stream_enc_dma_append(s, data)) { 606 if (!stream_enc_dma_append(s, data)) {
603 set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags); 607 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)
634 then start a DMA request for just the VBI data. */ 638 then start a DMA request for just the VBI data. */
635 if (!stream_enc_dma_append(s, data) && 639 if (!stream_enc_dma_append(s, data) &&
636 !test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) { 640 !test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) {
637 set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
638 set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags); 641 set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
639 } 642 }
640} 643}