Mailing List archive

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

[linux-dvb] Re: Busy waiting in i2c_busy_rise_and_fall (was: Re: Re: full featured card without signal and required video memory investigation)



On Sunday 13 July 2003 18:25, Oliver Endriss wrote:
> [patch #1]

Tomi Ollila pointed out that the jiffies counter might wrap.
There is a small chance that this happens during an i2c transfer.
So, if your DVB box is running for a multiple of 497 days ;-) 
you might consider this patch:

--------------------------------  snip  -------------------------------
--- saa7146.c.org	Mon Nov 18 22:18:46 2002
+++ saa7146.c	Mon Jul 14 00:48:15 2003
@@ -1271,6 +1271,7 @@ int i2c_busy_rise_and_fall(struct saa714
 {
 	int i = 0;
 	u32 status = 0;
+	u32 start;
 		
 	hprintk("saa7146: ==> i2c_busy_rise_and_fall\n");
 
@@ -1284,11 +1285,9 @@ int i2c_busy_rise_and_fall(struct saa714
 		/* check busy flag */
 		if ( 0 != (status & SAA7146_I2C_BUSY))
 			break;
-
-		/* see if anything can be done while we're waiting */
-		cond_resched ();
-		mdelay(1);
 	}
+	if (i == 0)
+		hprintk("saa7146: i2c_busy_rise_and_fall: missed busy flag\n");
 
 	/* we don't check the i-value, since it does not matter
 	   if we missed the rise of the busy flag or the fall or
@@ -1296,9 +1295,12 @@ int i2c_busy_rise_and_fall(struct saa714
 	   after an i2c-command has been written out */	
 	
 	/* wait until busy-flag is inactive or error is reported */
-	for (i = timeout; i > 0; i--) {
-	
-		hprintk("saa7146: i2c_busy_rise_and_fall; fall wait %d\n",i);
+	for (start = jiffies; jiffies-start <= timeout/10; ) {
+
+		hprintk("saa7146: i2c_busy_rise_and_fall; fall wait\n");
+
+		/* see if anything can be done while we're waiting */
+		cond_resched ();
 
 		status = i2c_status_check(saa);
 
@@ -1309,15 +1311,10 @@ int i2c_busy_rise_and_fall(struct saa714
 		/* check error flag */
 		if ( 0 != (status & SAA7146_I2C_ERR))
 			break;
-
-		/* see if anything can be done while we're waiting */
-		cond_resched ();
-
-		mdelay(1);
 	}
 	
 	/* did a timeout occur ? */
-	if ( 0 == i ) {
+	if (jiffies-start > timeout/10) {
 		hprintk("saa7146: i2c_busy_rise_and_fall: timeout #2\n");
 		return -1;
 	}
--- saa7146_core.c.org	Sat Jun 28 01:42:53 2003
+++ saa7146_core.c	Sun Jul 13 21:54:26 2003
@@ -82,7 +82,7 @@ static struct saa7146_extension* saa7146
 #define SAA7146_I2C_TIMEOUT  100   /* in ms */
 #define SAA7146_I2C_RETRIES  6
 
-static u32 SAA7146_I2C_BBR = SAA7146_I2C_BUS_BIT_RATE_3200;
+static u32 SAA7146_I2C_BBR = SAA7146_I2C_BUS_BIT_RATE_120; /* 275 kHz */
 
 #define	__COMPILE_SAA7146_I2C__
 #define	__COMPILE_SAA7146_DEBI__
--------------------------------  snip  -------------------------------

I also added the cond_resched() call again. 
Might be useful on fast machines.

Oliver


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



Home | Main Index | Thread Index