提交 dd1e729d 编写于 作者: H Hans Verkuil 提交者: Mauro Carvalho Chehab

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: NHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: NMauro Carvalho Chehab <mchehab@infradead.org>
上级 201700d3
...@@ -403,6 +403,11 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) ...@@ -403,6 +403,11 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
/* Mark last buffer size for Interrupt flag */ /* Mark last buffer size for Interrupt flag */
s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000); 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)) { if (ivtv_use_pio(s)) {
for (i = 0; i < s->SG_length; i++) { for (i = 0; i < s->SG_length; i++) {
s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src); 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,7 +602,6 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv)
data[0], data[1], data[2]); data[0], data[1], data[2]);
return; return;
} }
clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
s = &itv->streams[ivtv_stream_map[data[0]]]; s = &itv->streams[ivtv_stream_map[data[0]]];
if (!stream_enc_dma_append(s, data)) { 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); 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,7 +638,6 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
then start a DMA request for just the VBI data. */ then start a DMA request for just the VBI data. */
if (!stream_enc_dma_append(s, data) && if (!stream_enc_dma_append(s, data) &&
!test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) { !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); set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册