git: 9front

Download patch

ref: 3eb41aadc141c8276b3d9585f293212113575916
parent: 09f4d78c4666041cef5f198b3850d60211ee318c
author: google <google@daverabbitz.ath.cx>
date: Mon Sep 3 15:23:28 EDT 2012

Add timeout to eeprom and flash init in ether82563 driver.

Prevents hang on misidentified or broken cards.

--- a/sys/src/9/pc/ether82563.c
+++ b/sys/src/9/pc/ether82563.c
@@ -1650,10 +1650,17 @@
 static int
 eeread(Ctlr *ctlr, int adr)
 {
+	int timeout;
+
 	csr32w(ctlr, Eerd, EEstart | adr << 2);
-	while ((csr32r(ctlr, Eerd) & EEdone) == 0)
-		;
-	return csr32r(ctlr, Eerd) >> 16;
+	timeout = 1000;
+	while ((csr32r(ctlr, Eerd) & EEdone) == 0 && timeout--)
+		microdelay(5);
+	if (timeout < 0) {
+		print("%s: eeread timeout.\n", cname(ctlr));
+		return -1;
+	}
+	return (csr32r(ctlr, Eerd) >> 16) & 0xffff;
 }
 
 static int
@@ -1665,6 +1672,7 @@
 	sum = 0;
 	for (adr = 0; adr < 0x40; adr++) {
 		data = eeread(ctlr, adr);
+		if(data == -1) return -1;
 		ctlr->eeprom[adr] = data;
 		sum += data;
 	}
@@ -1694,6 +1702,7 @@
 fread(Ctlr *c, Flash *f, int ladr)
 {
 	u16int s;
+	int timeout;
 
 	delay(1);
 	if(fcycle(c, f) == -1)
@@ -1704,9 +1713,13 @@
 	/* setup flash control register */
 	s = f->reg[Fctl] & ~0x3ff;
 	f->reg[Fctl] = s | 1<<8 | Fgo;	/* 2 byte read */
-
-	while((f->reg[Fsts] & Fdone) == 0)
-		;
+	timeout = 1000;
+	while((f->reg[Fsts] & Fdone) == 0 && timeout--)
+		microdelay(5);
+	if(timeout < 0){
+		print("%s: fread timeout.\n");
+		return -1;
+	}
 	if(f->reg[Fsts] & (Fcerr|Ael))
 		return -1;
 	return f->reg32[Fdata] & 0xffff;
--