Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: [PATCH] fix for stream corruption on budget /Nova-T cards



Robert Schlabbach wrote:

The odd/even trick makes the SAA7146A automatically switch between two
buffers. The ugly side of this is that you have to busy-wait for it to
really switch buffers and then _copy_ the data out of the DMA buffer.
Yep, I tried doing a busy wait before I came up with the solution to infer the pointer position from the olddma pointer. I did a patch which catches the suspect pointer and just busy waits until it has moved to a different location. It often takes several microseconds for the DMA pointer to make up its mind.

I have attached the patch against the dvb-kernel code for reference in case anyone wants to try it out. I don't recommend it since it doesn't appear to work any better than the solution I posted earlier and it consumes a few more CPU cycles doing the busy waits.

Jon

diff -urw cvs/dvb-kernel/linux/drivers/media/dvb/ttpci/budget-core.c dvb-kernel/linux/drivers/media/dvb/ttpci/budget-core.c
--- cvs/dvb-kernel/linux/drivers/media/dvb/ttpci/budget-core.c	2003-06-26 18:42:36.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget-core.c	2003-08-30 01:25:11.000000000 +0100
@@ -68,6 +68,18 @@
         u32 olddma = budget->ttbp;
         u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
 
+#define MAX_COUNT 100
+	int count = MAX_COUNT;
+	while ((( newdma == 0) || (newdma == TS_BUFLEN / 2)) && (count != 0)){
+	  /* DMA pointer looks suspect */
+	  udelay(1);
+	  newdma = saa7146_read(budget->dev, PCI_VDP3);
+	  count--;
+	}
+	if (count < (MAX_COUNT/2)) {
+	  ERR(("DMA stuck for %dus\n", MAX_COUNT - count));
+	}
+
         /* nearest lower position divisible by 188 */
         newdma -= newdma % 188;
 

Home | Main Index | Thread Index