Mailing List archive

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

[linux-dvb] Re: Hardware lockup




  Two instances of dvbtune run in close succession makes my dvb-c machine
lock up after a couple of tries.  Some sleep in between helps.  My script
for finding the services for example works like this:

./dvbtune -f 283000000 -s 5900 -qam 128 -i > htv1.xml
sleep 2
./dvbtune -f 290000000 -s 5900 -qam 128 -i > htv2.xml
sleep 2
./dvbtune -f 162000000 -s 6900 -qam 64 -i > htv3.xml
sleep 2
./dvbtune -f 170000000 -s 6900 -qam 128 -i > htv4.xml
sleep 2
./dvbtune -f 297000000 -s 5900 -qam 128 -i > htv5.xml
sleep 2
./dvbtune -f 146000000 -s 6900 -qam 128 -i > htv6.xml
sleep 2
./dvbtune -f 154000000 -s 6900 -qam 128 -i > htv7.xml
sleep 2
./dvbtune -f 138000000 -s 6900 -qam 128 -i > htv8.xml
sleep 2
./dvbtune -f 276000000 -s 5900 -qam 128 -i > htv9.xml

  Also in vdr, sleep(1) between the openings of adapter devices helps.
I tried to send this message earlier but it seems to have been lost
somewhere:

-----------

[ subject: Leftover kdvb-fe processes ]

On Sun, 1 Dec 2002, Klaus Schmidinger wrote:
> VDR doesn't open it twice in parallel. It opens it, closes it and then
> re-opens it.
> I believe that should be allowed.

  I resolved this by inserting sleep(1) before and after close(f) in
Probe() in vdr.  Not very neat, but timings seem to work now and nothing
is left over.

  I have to maintain some patches to DVB HEAD driver to get it to tune
reliably with DVB-C here.  QAM128 and freq offsets and auto-inversion
affected. Also if the card is not tuned by the application in start
kdvb-fe -threads consume cpu in the loop reading status, so I made the
loop to notice this. Added also some debugging while trying to get it to
tune, it might be helpful to others who wonder about the CPU usage.  I
have not followed the linux-dvb list very closely so I might be off here
with my fixes, but the patch is below in case anyone needs it.  I suggest
not to commit any of these changes to CVS, this is just the hack I use.

Index: driver/dvb_frontend.c
===================================================================
RCS file: /cvs/linuxtv/DVB/driver/dvb_frontend.c,v
retrieving revision 1.35
diff -u -r1.35 dvb_frontend.c
--- driver/dvb_frontend.c	5 Dec 2002 17:19:44 -0000	1.35
+++ driver/dvb_frontend.c	6 Dec 2002 07:56:05 -0000
@@ -172,7 +172,7 @@
 		frequency += this_fe->lnb_drift;
 		frequency += this_fe->bending;

-		if (this_fe != fe &&
+		if (-1 != fe->lost_sync_count && this_fe != fe &&
                     frequency > f - stepsize && frequency < f + stepsize)
 		{
 			if (recursive % 2)
@@ -318,6 +318,10 @@
 		 __FUNCTION__, param->frequency, fe->lnb_drift);

 	param->frequency += fe->lnb_drift + fe->bending;
+	printk ("%i:%i: drift: %c%u.%06u, bending: %c%u.%06u\n",
+		fe->frontend.i2c->adapter->num, fe->frontend.i2c->id,
+		fe->lnb_drift < 0 ? '-' : '+', abs(fe->lnb_drift) / 1000000, abs(fe->lnb_drift) % 1000000,
+		fe->bending < 0 ? '-' : '+', abs(fe->bending) / 1000000, abs(fe->bending) % 1000000);
 	err = dvb_frontend_internal_ioctl (frontend, FE_SET_FRONTEND, param);
 	param->frequency -= fe->lnb_drift + fe->bending;

@@ -359,7 +363,7 @@


 #define LNB_DRIFT 1024  /*  max. tolerated LNB drift, XXX FIXME: adjust! */
-#define TIMEOUT 2*HZ
+#define TIMEOUT 4*HZ

 /**
  *  here we only come when we have lost the lock bit,
@@ -439,16 +443,20 @@
 	daemonize ();
 	reparent_to_init ();
 	sigfillset (&current->blocked);
-	strncpy (current->comm, "kdvb-fe", sizeof (current->comm));
+	snprintf (current->comm, sizeof (current->comm), "kdvb-fe %i:%i", fe->frontend.i2c->adapter->num, fe->frontend.i2c->id);
 	fe->thread = current;
 	unlock_kernel ();

 	dvb_call_frontend_notifiers (fe, 0);
 	dvb_frontend_init (fe);

+	fe->lost_sync_count = -1; /* Not tuned yet, at least not by me. */
+
 	while (!dvb_frontend_is_exiting (fe)) {
 		up (&fe->sem);      /* is locked when we enter the thread... */

+		if (fe->lost_sync_count > 0)
+			printk ("%i:%i: delay: %d.%06ds\n", fe->frontend.i2c->adapter->num, fe->frontend.i2c->id, delay / HZ, (delay % HZ) * 1000000/HZ);
 		interruptible_sleep_on_timeout (&fe->wait_queue, delay);

 		if (down_interruptible (&fe->sem)) {
@@ -458,6 +466,8 @@

 		if (dvb_frontend_is_exiting (fe))
 			break;
+		if (-1 == fe->lost_sync_count)
+			continue;

 		dvb_frontend_internal_ioctl (&fe->frontend, FE_READ_STATUS, &s);

@@ -473,8 +483,11 @@
 			if (!(fe->info->caps & FE_CAN_CLEAN_SETUP))
 				if (fe->lost_sync_count < 10)
 					continue;
-			dvb_frontend_recover (fe);
-			delay = HZ/5;
+			if (fe->lost_sync_count > 1) {
+				printk ("%i:%i: call recover\n", fe->frontend.i2c->adapter->num, fe->frontend.i2c->id);
+				dvb_frontend_recover (fe);
+			}
+			delay = HZ/2;
 			if (jiffies - fe->lost_sync_jiffies > TIMEOUT) {
 				s |= FE_TIMEDOUT;
 				if ((fe->status & FE_TIMEDOUT) == 0)
@@ -944,3 +957,6 @@
 MODULE_PARM_DESC(dvb_frontend_debug, "enable verbose debug messages");
 MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware");

+// Local variables:
+// c-basic-offset: 8
+// End:
Index: driver/frontends/ves1820.c
===================================================================
RCS file: /cvs/linuxtv/DVB/driver/frontends/ves1820.c,v
retrieving revision 1.15
diff -u -r1.15 ves1820.c
--- driver/frontends/ves1820.c	27 Nov 2002 11:24:20 -0000	1.15
+++ driver/frontends/ves1820.c	6 Dec 2002 07:56:06 -0000
@@ -27,7 +27,7 @@
 #include "dvb_frontend.h"


-#if 0
+#if 1
 #define dprintk(x...) printk(x)
 #else
 #define dprintk(x...)
@@ -168,6 +168,23 @@
  *   set up the downconverter frequency divisor for a
  *   reference clock comparision frequency of 62.5 kHz.
  */
+
+/*
+ *   Tuner Mitel SP5659 (tuner_type==1)
+ *   buf[2]: 1  2^16  2^15  PE  R3  R2  R1  R0
+ *           1     0     0   0   0   1   0   1
+ *   PE = prescaler, enables 2.7GHz operation.  Not needed, set to 0
+ *   2^16, 2^15 = high bits of divider
+ *   R3..0 = division ratio, 0101 = 64, corresponds to comp. freq 62.5kHz
+ *           with 4MHz external reference.
+ *   buf[3]: C1   C0   RE  RTS   P3   P2/TS2 P1/TS1 P0/TS0
+ *            1    0    0    0    0       1     0     0
+ *   C1,0 = charge pump current, 10 = +-555µA
+ *   RE = REF/COMP output enable
+ *   RTS = 0=REF output, 1=COMP output.  (RE,RTS)=(0,0) = normal operation.
+ *   TS2..0 = test mode control bits
+ *   P3..0 = port P3..0 output, 1000 (<174MHz), 0100 (<470MHz), 0001 (>470MHz)
+ */
 static
 int tuner_set_tv_freq (struct dvb_frontend *fe, u32 freq)
 {
@@ -180,7 +197,7 @@
 	if (tuner_type == 0xff)     /*  PLL not reachable over i2c ...  */
 		return 0;

-	div = (freq + 36250000 + 31250) / 62500;
+	div = (freq + 36000000 + 31250) / 62500;
 	buf[0] = (div >> 8) & 0x7f;
 	buf[1] = div & 0xff;
 	buf[2] = byte3[tuner_type];
@@ -194,6 +211,11 @@
 			  freq < 454000000 ? 0x92 : 0x34);
 	}

+	dprintk ("%s: tuning to %u.%06u MHz\n",
+		 __FILE__,
+		 (div * 62500 - 36000000) / 1000000,
+		 (div * 62500 - 36000000) % 1000000);
+
         return tuner_write (fe->i2c, addr[tuner_type], buf);
 }

@@ -202,10 +224,13 @@
 int ves1820_setup_reg0 (struct dvb_frontend *fe, u8 reg0)
 {
 	reg0 |= GET_REG0(fe->data) & 0x62;
+
+	reg0 |= 0x20;

 	ves1820_writereg (fe, 0x00, reg0 & 0xfe);
         ves1820_writereg (fe, 0x00, reg0 | 0x01);

+#if 0
 	/**
 	 *  check lock and toggle inversion bit if required...
 	 */
@@ -217,6 +242,7 @@
         		ves1820_writereg (fe, 0x00, reg0 | 0x01);
 		}
 	}
+#endif

 	SET_REG0(fe->data, reg0);

@@ -306,7 +332,7 @@
 			    struct dvb_frontend_parameters *p)
 {
 	static const u8 reg0x00 [] = { 0x00, 0x04, 0x08, 0x0c, 0x10 };
-	static const u8 reg0x01 [] = {  140,  140,  106,  120,   92 };
+	static const u8 reg0x01 [] = {  140,  140,  106,  100,   92 };
 	static const u8 reg0x05 [] = {  135,  100,   70,   54,   38 };
 	static const u8 reg0x08 [] = {  162,  116,   67,   52,   35 };
 	static const u8 reg0x09 [] = {  145,  150,  106,  126,  107 };
@@ -315,7 +341,7 @@
 	if (real_qam < 0 || real_qam > 4)
 		return -EINVAL;

-	tuner_set_tv_freq (fe, p->frequency);
+	tuner_set_tv_freq (fe, QAM_128 == p->u.qam.modulation ? p->frequency - 125000 : p->frequency);
 	ves1820_set_symbolrate (fe, p->u.qam.symbol_rate);
 	ves1820_writereg (fe, 0x34, GET_PWM(fe->data));

@@ -544,3 +570,7 @@
 MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
 MODULE_LICENSE("GPL");

+
+// Local variables:
+// c-basic-offset: 8
+// End:

-- 
Foreca Ltd                                           Jaakko.Hyvatti@foreca.com
Pursimiehenkatu 29-31 B, FIN-00150 Helsinki, Finland     http://www.foreca.com





--
Info:
To unsubscribe send a mail to listar@linuxtv.org with "unsubscribe linux-dvb" as subject.



Home | Main Index | Thread Index