piix4 fails to reset? (ticket #1078)

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

 



On Thu, 19 Dec 2002, Mark D. Studebaker wrote:

> If you have an idea about fixing it then if you post or check
> in a patch there's lots of folks with piix4's that could test it,
> at lest to see that it didn't break anything...

Attached. At least it compiles...
So it retries host busy condition 5 times with 10 ms delay before
it goes for Start. On a transaction timeout, it tries to release host
using the KILL flag.

-- 
  Ky?sti M?lkki
  kmalkki at cc.hut.fi
-------------- next part --------------
--- i2c-piix4.c.orig	Sat Oct 12 15:43:13 2002
+++ i2c-piix4.c	Fri Dec 20 07:38:29 2002
@@ -353,28 +353,29 @@
 #endif
 
 	/* Make sure the SMBus host is ready to start transmitting */
-	if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
+	while ( ((temp = inb_p(SMBHSTSTS)) != 0x00) && (timeout++ < 5)) {
 #ifdef DEBUG
-		printk(KERN_DEBUG "i2c-piix4.o: SMBus busy (%02x). Resetting... \n",
+		printk(KERN_DEBUG "i2c-piix4.o: SMBus busy (%02x). Waiting... \n",
 		       temp);
 #endif
-		outb_p(temp, SMBHSTSTS);
-		if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
+		piix4_do_pause(HZ/100);
+	}
+	if (timeout >= 5) {
 #ifdef DEBUG
-			printk(KERN_ERR "i2c-piix4.o: Failed! (%02x)\n", temp);
+		printk(KERN_ERR "i2c-piix4.o: SMBus busy timeout! (%02x)\n", temp);
 #endif
-			return -1;
-		} else {
+		return -1;
+	} else if (timeout) {
 #ifdef DEBUG
-			printk(KERN_DEBUG "i2c-piix4.o: Successfull!\n");
+		printk(KERN_DEBUG "i2c-piix4.o: SMBus released after %d attempts\n", timeout);
 #endif
-		}
 	}
 
 	/* start the transaction by setting bit 6 */
 	outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
 
 	/* We will always wait for a fraction of a second! (See PIIX4 docs errata) */
+	timeout=0;
 	do {
 		piix4_do_pause(1);
 		temp = inb_p(SMBHSTSTS);
@@ -413,6 +414,22 @@
 	if (inb_p(SMBHSTSTS) != 0x00)
 		outb_p(inb(SMBHSTSTS), SMBHSTSTS);
 
+	if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
+#ifdef DEBUG
+		printk
+		    (KERN_ERR "i2c-piix4.o: Trying KILL at end of transaction (%02x)\n",
+		     temp);
+#endif
+		/* KILL */
+		outb_p(inb(SMBHSTCNT) | 0x02, SMBHSTCNT);
+		outb_p(temp = inb_p(SMBHSTSTS), SMBHSTSTS);
+#ifdef DEBUG
+		if (temp & ~0x10)
+		    printk(KERN_ERR "i2c-piix4.o: KILL failed (%02x)\n", temp);
+#endif
+		/* UNKILL */
+		outb_p(inb(SMBHSTCNT) &~ 0x02, SMBHSTCNT);
+	}
 #ifdef DEBUG
 	if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
 		printk


[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux