I already posted this patch yesterday but it was a hand crafted patch,
so I'm resubmitting it properly with my latest results:

Attached is the patch against 2.6.22.1 sources which I have been testing
against 13 WinTV PVR-150 cards and 1 WinTV PVR-500, over the last 26
hours I have had no DMA TIMEOUTs, when normally I would have had 6 or 7.

In my testing the cards also recover from a DMA TIMEOUT if you provoke
one setting a stupidly low latency.

You may also need Hans's VBI/PCM patch that is attached for convenience.

Please report back on any successes/failures/side effects of this fix to
the list.

Regards,
 Mark Bryars


-- 
Mark Bryars
Product Development Engineer
ETV Interactive Ltd
Logie Court
Stirling University Innovation Park
Stirling
Scotland, UK
FK9 4NF
T: +44 (0) 1786 455150
F: +44 (0) 1786 455179
W: www.etvinteractive.com

diff -urN linux-2.6.22.1/drivers/media/video/ivtv/ivtv-driver.c 
linux-2.6.22.1.dmapatch/drivers/media/video/ivtv/ivtv-driver.c
--- linux-2.6.22.1/drivers/media/video/ivtv/ivtv-driver.c       2007-07-27 
13:47:38.427739664 +0100
+++ linux-2.6.22.1.dmapatch/drivers/media/video/ivtv/ivtv-driver.c      
2007-07-27 13:51:51.949198544 +0100
@@ -1116,7 +1116,7 @@
        }
        itv->params.video_gop_size = itv->is_60hz ? 15 : 12;
 
-       itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_MPG] = 0x08000;
+       itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_MPG] = 0x20000;
        itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_PCM] = 0x01200;
        itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_MPG] = 0x10000;
 
@@ -1322,7 +1322,7 @@
 
 static int module_start(void)
 {
-       printk(KERN_INFO "ivtv:  ==================== START INIT IVTV 
====================\n");
+       printk(KERN_INFO "ivtv:  ==================== START INIT IVTV [128k 
buffer patch] ====================\n");
        printk(KERN_INFO "ivtv:  version %s (" VERMAGIC_STRING ") loading\n", 
IVTV_VERSION);
 
        memset(ivtv_cards, 0, sizeof(ivtv_cards));
diff -urN linux-2.6.22.1/drivers/media/video/ivtv/ivtv-irq.c 
linux-2.6.22.1.dmapatch/drivers/media/video/ivtv/ivtv-irq.c
--- linux-2.6.22.1/drivers/media/video/ivtv/ivtv-irq.c  2007-07-26 
13:44:02.000000000 +0100
+++ linux-2.6.22.1.dmapatch/drivers/media/video/ivtv/ivtv-irq.c 2007-07-26 
13:27:56.000000000 +0100
@@ -124,6 +124,11 @@
                        offset = data[1];
                        size = data[2];
                        s->dma_pts = 0;
+
+                       if (size>0x20000) {
+                               IVTV_WARN("Warning: Large transfer requested 
0x%08x (truncating)\n",size);
+                               size=0x20000;
+                       }
                        break;
 
                case IVTV_ENC_STREAM_TYPE_YUV:
diff -urN linux-2.6.22.1/drivers/media/video/ivtv/ivtv-irq.c.orig 
linux-2.6.22.1.dmapatch/drivers/media/video/ivtv/ivtv-irq.c.orig
--- linux-2.6.22.1/drivers/media/video/ivtv/ivtv-irq.c.orig     2007-07-26 
13:43:35.000000000 +0100
+++ linux-2.6.22.1.dmapatch/drivers/media/video/ivtv/ivtv-irq.c.orig    
2007-07-26 13:16:54.000000000 +0100
@@ -898,7 +898,9 @@
 
        if (!test_bit(IVTV_F_I_DMA, &itv->i_flags))
                return;
-       IVTV_ERR("DMA TIMEOUT %08x %d\n", read_reg(IVTV_REG_DMASTATUS), 
itv->cur_dma_stream);
+       
+    IVTV_ERR("DMA TIMEOUT [deltimer]  %08x %d\n", 
read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream);
+       del_timer(&itv->dma_timer);
 
        write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
        clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
diff -r ce6e2e8c859f linux/drivers/media/video/ivtv/ivtv-irq.c
--- a/linux/drivers/media/video/ivtv/ivtv-irq.c Tue Jul 17 18:50:46 2007 +0200
+++ b/linux/drivers/media/video/ivtv/ivtv-irq.c Wed Jul 18 18:02:56 2007 +0200
@@ -409,6 +409,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);
@@ -603,7 +608,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);
@@ -640,7 +644,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);
        }
 }
_______________________________________________
ivtv-devel mailing list
[email protected]
http://ivtvdriver.org/mailman/listinfo/ivtv-devel

Reply via email to