Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 234054
b: refs/heads/master
c: d213ad0
h: refs/heads/master
v: v3
  • Loading branch information
Michael authored and Mauro Carvalho Chehab committed Mar 2, 2011
1 parent 12de9a0 commit a469e7c
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1e6406b8f0dc1ae7d7c39c9e1ac6ca78e016ebfb
refs/heads/master: d213ad08362909ab50fbd6568fcc9fd568268d29
58 changes: 51 additions & 7 deletions trunk/drivers/media/video/ivtv/ivtv-irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,22 +628,66 @@ static void ivtv_irq_enc_pio_complete(struct ivtv *itv)
static void ivtv_irq_dma_err(struct ivtv *itv)
{
u32 data[CX2341X_MBOX_MAX_DATA];
u32 status;

del_timer(&itv->dma_timer);

ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
status = read_reg(IVTV_REG_DMASTATUS);
IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1],
read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream);
write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
status, itv->cur_dma_stream);
/*
* We do *not* write back to the IVTV_REG_DMASTATUS register to
* clear the error status, if either the encoder write (0x02) or
* decoder read (0x01) bus master DMA operation do not indicate
* completed. We can race with the DMA engine, which may have
* transitioned to completed status *after* we read the register.
* Setting a IVTV_REG_DMASTATUS flag back to "busy" status, after the
* DMA engine has completed, will cause the DMA engine to stop working.
*/
status &= 0x3;
if (status == 0x3)
write_reg(status, IVTV_REG_DMASTATUS);

if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) &&
itv->cur_dma_stream >= 0 && itv->cur_dma_stream < IVTV_MAX_STREAMS) {
struct ivtv_stream *s = &itv->streams[itv->cur_dma_stream];

/* retry */
if (s->type >= IVTV_DEC_STREAM_TYPE_MPG)
if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
/* retry */
/*
* FIXME - handle cases of DMA error similar to
* encoder below, except conditioned on status & 0x1
*/
ivtv_dma_dec_start(s);
else
ivtv_dma_enc_start(s);
return;
return;
} else {
if ((status & 0x2) == 0) {
/*
* CX2341x Bus Master DMA write is ongoing.
* Reset the timer and let it complete.
*/
itv->dma_timer.expires =
jiffies + msecs_to_jiffies(600);
add_timer(&itv->dma_timer);
return;
}

if (itv->dma_retries < 3) {
/*
* CX2341x Bus Master DMA write has ended.
* Retry the write, starting with the first
* xfer segment. Just retrying the current
* segment is not sufficient.
*/
s->sg_processed = 0;
itv->dma_retries++;
ivtv_dma_enc_start_xfer(s);
return;
}
/* Too many retries, give up on this one */
}

}
if (test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
ivtv_udma_start(itv);
Expand Down

0 comments on commit a469e7c

Please sign in to comment.