[linux-dvb] IRQ-Lockup

Hamish Moffatt hamish at cloud.net.au
Mon Feb 21 23:05:48 CET 2005


On Mon, Feb 21, 2005 at 08:31:02PM +0100, Florian-Wolfgang Stock wrote:
> I am using an Avermedia 771 DVB-T card (with mt352 frontend).

> So far so good, but when I start application, it instantly stops working
> Feb 17 17:23:38 multivac kernel: bt878(0): irq FDSR risc_pc=0ed5a208
> Feb 17 17:24:05 multivac kernel: bt878(0): irq FDSR risc_pc=0ed5a1d0
> Feb 17 17:24:06 multivac kernel: bt878(0): irq FDSR risc_pc=0ed5a208
> Feb 17 17:24:06 multivac kernel: bt878(0): irq FDSR risc_pc=0ed5a190
> Feb 17 17:24:32 multivac kernel: bt878(0): irq FDSR risc_pc=0ed5a068
> Feb 17 17:24:32 multivac kernel: bt878(0): irq FBUS risc_pc=0ed5a138
[..]
> Feb 17 17:24:32 multivac last message repeated 28 times
> Feb 17 17:24:32 multivac kernel: bt878(0): IRQ lockup, cleared int mask
> 
> No receiving possible, remote works perfect, but no more TV.
> 
> I also tried 2.6.10 - same behaviour. Instantly stop.

I have spent some time on this problem with my Avermedia 761 (same
chipset, the bt878). I never noticed any difference between 2.6.8
and 2.6.10, so you might have found something valuable there.

You may be able to help this problem by adjusting the PCI latency timers
for your cards. You can see the current values with 'lspci -vv', and set
them with setpci. Also you can use powertweak which allows you to set
these graphically. You probably need to _decrease_ the latency timer on
your _other_ cards so that they can be interrupted sooner by the bt878.

I've attached a patch for the bt878 drivers that I was experimenting
with. (This is not intended to go into CVS but might help you debug.) It
adds a few module parameters.

On the bt878 module, you have two new parameters:

lockup_count: sets the number of errors before lockup declared. Default
is 20; try 100 or more. It might be that you have a brief burst and if
the limit is increased you will be fine.

pktp (range 0-2); sets the fifo threshold for the bt878 before it starts
transmitting data on the PCI bus. The default is 2, which means it waits
until the fifo is half full before doing anything. I think it should be
0 (start as soon as possible), but changing it never made any difference
to me.

There is a new parameter on the dvb-bt8xx module also, but I don't think
you need it for the 771 card. It changes the behaviour of the 761 to
match the 771. I am surprised that you get FDSR errors as those are
supposed to be masked out in the RISC program.


A word of warning though: I never made my 761 card work satisfactorily
with any other I/O on the PCI bus, so I bought a card with a different
chipset to replace it.


Hamish
-- 
Hamish Moffatt VK3SB <hamish at debian.org> <hamish at cloud.net.au>
-------------- next part --------------
diff -urN linux-2.6.10/drivers/media/dvb/bt8xx/bt878.c linux-2.6.10-patched/drivers/media/dvb/bt8xx/bt878.c
--- linux-2.6.10/drivers/media/dvb/bt8xx/bt878.c	2004-12-27 17:13:55.000000000 +1100
+++ linux-2.6.10-patched/drivers/media/dvb/bt8xx/bt878.c	2004-12-27 17:25:41.000000000 +1100
@@ -53,6 +53,8 @@
 
 static unsigned int bt878_verbose = 1;
 static unsigned int bt878_debug;
+static unsigned int bt878_lockup_count = 20;
+static unsigned int bt878_pktp = 2;
 
 module_param_named(verbose, bt878_verbose, int, 0444);
 MODULE_PARM_DESC(bt878_verbose,
@@ -60,11 +62,21 @@
 module_param_named(debug, bt878_debug, int, 0644);
 MODULE_PARM_DESC(bt878_debug, "Turn on/off debugging (default:off).");
 
+module_param_named(lockup_count, bt878_lockup_count, int, 0644);
+MODULE_PARM_DESC(bt878_lockup_count,
+		 "interrupt lockup count, default is 20");
+
+module_param_named(pktp, bt878_pktp, int, 0644);
+MODULE_PARM_DESC(bt878_pktp,
+		 "BT878 fifo threshold (0-2), default is 2");
+
 int bt878_num;
 struct bt878 bt878[BT878_MAX];
 
 EXPORT_SYMBOL(bt878_debug);
 EXPORT_SYMBOL(bt878_verbose);
+EXPORT_SYMBOL(bt878_lockup_count);
+EXPORT_SYMBOL(bt878_pktp);
 EXPORT_SYMBOL(bt878_num);
 EXPORT_SYMBOL(bt878);
 
@@ -217,7 +229,8 @@
 	 */
 	bt878_risc_program(bt, op_sync_orin);
 	controlreg &= ~0x1f;
-	controlreg |= 0x1b;
+	/*controlreg |= 0x1b;*/
+	controlreg |= 0x13 | ((bt878_pktp & 0x3) << 2);
 
 	btwrite(cpu_to_le32(bt->risc_dma), BT878_ARISC_START);
 
@@ -280,8 +293,11 @@
 	while (1) {
 		stat = btread(BT878_AINT_STAT);
 		mask = btread(BT878_AINT_MASK);
-		if (!(astat = (stat & mask)))
-			return IRQ_NONE;	/* this interrupt is not for me */
+		if (!(astat = (stat & mask))) {
+			if (count == 0)
+				return IRQ_NONE;	/* this interrupt is not for me */
+			break;
+		}
 /*		dprintk("bt878(%d) debug: irq count %d, stat 0x%8.8x, mask 0x%8.8x\n",bt->nr,count,stat,mask); */
 		btwrite(astat, BT878_AINT_STAT);	/* try to clear interupt condition */
 
@@ -327,14 +343,20 @@
 			break;
 		}
 		count++;
-		if (count > 20) {
+		if (count > bt878_lockup_count) {
 			btwrite(0, BT878_AINT_MASK);
 			printk(KERN_ERR
-			       "bt878(%d): IRQ lockup, cleared int mask\n",
-			       bt->nr);
+			       "bt878(%d): IRQ lockup (count > %d), cleared int mask\n",
+			       bt->nr, bt878_lockup_count);
 			break;
 		}
 	}
+
+	if (count > 20) {
+		printk(KERN_ERR
+				"bt878(%d): handled %d loops at once\n",
+				bt->nr, count);
+	}
 	return IRQ_HANDLED;
 }
 
diff -urN linux-2.6.10/drivers/media/dvb/bt8xx/dvb-bt8xx.c linux-2.6.10-patched/drivers/media/dvb/bt8xx/dvb-bt8xx.c
--- linux-2.6.10/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2004-12-27 17:13:55.000000000 +1100
+++ linux-2.6.10-patched/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2005-01-30 13:00:43.000000000 +1100
@@ -38,9 +38,12 @@
 #include "bt878.h"
 
 static int debug;
+static int aver761_resync;
 
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+module_param(aver761_resync, int, 0644);
+MODULE_PARM_DESC(aver761_resync, "Turn on/off Aver761 resync (default:off).");
 
 #define dprintk( args... ) \
 	do { \
@@ -529,7 +532,7 @@
 #endif
 	case BTTV_AVDVBT_761:
 		card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
-		card->op_sync_orin = 0;
+		card->op_sync_orin = (aver761_resync) ? BT878_RISC_SYNC_MASK : 0;
 		card->irq_err_ignore = 0;
 				/* A_PWRDN DA_SBR DA_APP (high speed serial) */
 				break;


More information about the linux-dvb mailing list