PERFORCE change 110644 for review

Warner Losh imp at FreeBSD.org
Tue Nov 28 16:14:00 PST 2006


http://perforce.freebsd.org/chv.cgi?CH=110644

Change 110644 by imp at imp_lighthouse on 2006/11/29 00:13:26

	Don't lockup on eeprom lockup.

Affected files ...

.. //depot/projects/arm/src/sys/arm/at91/at91_twi.c#32 edit
.. //depot/projects/arm/src/sys/boot/arm/at91/bootspi/ee.c#6 edit
.. //depot/projects/arm/src/sys/boot/arm/at91/bootspi/ee.h#3 edit
.. //depot/projects/arm/src/sys/boot/arm/at91/libat91/eeprom.c#8 edit
.. //depot/projects/arm/src/sys/boot/arm/at91/libat91/lib.h#21 edit

Differences ...

==== //depot/projects/arm/src/sys/arm/at91/at91_twi.c#32 (text+ko) ====

@@ -224,11 +224,16 @@
 {
 	int err = 0;
 	int counter = 100000;
+	uint32_t sr;
 
-	while (!(RD4(sc, TWI_SR) & bit) && counter-- > 0)
+	while (!((sr = RD4(sc, TWI_SR)) & bit) && counter-- > 0)
 		continue;
 	if (counter <= 0)
 		err = EBUSY;
+	else if (sr & TWI_SR_NACK)
+		err = EADDRNOTAVAIL;
+	if (sr & ~bit)
+		printf("status is %x\n", sr);
 	return (err);
 }
 
@@ -241,10 +246,7 @@
 	sc = device_get_softc(dev);
 	if (oldaddr)
 		*oldaddr = sc->twi_addr;
-	if (addr != 0)
-		sc->twi_addr = 0;
-	else
-		sc->twi_addr = addr;
+	sc->twi_addr = addr;
 
 	/*
 	 * speeds are for 1.5kb/s, 45kb/s and 90kb/s.
@@ -310,7 +312,9 @@
 		 * address feature of twi.  A separate i2c message needs to
 		 * be written to use this.
 		 * See http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html
-		 * for details.
+		 * for details.  Upon reflection, we could use this as an
+		 * optimization, but it is unclear the code bloat will
+		 * result in faster/better operations.
 		 */
 		rdwr = (msgs[i].flags & IIC_M_RD) ? TWI_MMR_MREAD : 0;
 		WR4(sc, TWI_MMR, TWI_MMR_DADR(msgs[i].slave) | rdwr);
@@ -332,14 +336,20 @@
 				WR4(sc, TWI_THR, *buf++);
 				if (len == 0)
 					WR4(sc, TWI_CR, TWI_CR_STOP);
-				if ((err = at91_twi_wait(sc, TWI_SR_TXRDY)))
+				if ((err = at91_twi_wait(sc, TWI_SR_TXRDY))) {
+					printf("Len %d\n", len);
 					goto out;
+				}
 			}
 		}
 		if ((err = at91_twi_wait(sc, TWI_SR_TXCOMP)))
 			break;
 	}
 out:;
+	if (err) {
+		WR4(sc, TWI_CR, TWI_CR_STOP);
+		printf("Err is %d\n", err);
+	}
 	AT91_TWI_UNLOCK(sc);
 	return (err);
 }

==== //depot/projects/arm/src/sys/boot/arm/at91/bootspi/ee.c#6 (text+ko) ====

@@ -89,15 +89,15 @@
  * This function does not utilize the page read mode to simplify the code.
  * .KB_C_FN_DEFINITION_END
  */
-void
+int
 EERead(unsigned ee_off, char *data_addr, unsigned size)
 {
 	const AT91PS_TWI 	twiPtr = AT91C_BASE_TWI;
-	unsigned int status;
+	unsigned int status, count;
 
 	if ((ee_off & ~0xff) != ((ee_off + size) & ~0xff)) {
 		printf("Crosses page boundary: 0x%x 0x%x\n", ee_off, size);
-		return;
+		return -1;
 	}
 
 	status = twiPtr->TWI_SR;
@@ -107,15 +107,22 @@
 	twiPtr->TWI_IADR = ee_off & 0xff;
 	twiPtr->TWI_CR = AT91C_TWI_START;
 	while (size-- > 1) {
-		while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY))
+		count = 1000000;
+		while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY) && --count > 0)
 			continue;
+		if (count <= 0)
+			return -1;
 		*(data_addr++) = twiPtr->TWI_RHR;
 	}
 	twiPtr->TWI_CR = AT91C_TWI_STOP;
 	status = twiPtr->TWI_SR;
-	while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP))
+	count = 1000000;
+	while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP) && --count > 0)
 		continue;
 	*data_addr = twiPtr->TWI_RHR;
+	if (count <= 0)
+		return -1;
+	return 0;
 }
 
 

==== //depot/projects/arm/src/sys/boot/arm/at91/bootspi/ee.h#3 (text+ko) ====

@@ -1,4 +1,4 @@
 void EEInit(void);
-void EERead(unsigned ee_off, char *data_addr, unsigned size);
+int EERead(unsigned ee_off, char *data_addr, unsigned size);
 void EEWrite(unsigned ee_off, const char *data_addr, unsigned size);
 

==== //depot/projects/arm/src/sys/boot/arm/at91/libat91/eeprom.c#8 (text+ko) ====

@@ -82,11 +82,12 @@
  * This function does not utilize the page read mode to simplify the code.
  * .KB_C_FN_DEFINITION_END
  */
-void
+int
 ReadEEPROM(unsigned ee_off, char *data_addr, unsigned size)
 {
 	const AT91PS_TWI 	twiPtr = AT91C_BASE_TWI;
 	unsigned int status;
+	unsigned int count;
 
 	status = twiPtr->TWI_SR;
 	status = twiPtr->TWI_RHR;
@@ -104,10 +105,12 @@
 	status = twiPtr->TWI_SR;
 
 	while (size-- > 1){
-
 		// Wait RHR Holding register is full
-		while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY))
+		count = 1000000;
+		while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY) && --count > 0)
 			continue;
+		if (count <= 0)
+			return -1;
 
 		// Read byte
 		*(data_addr++) = twiPtr->TWI_RHR;
@@ -123,6 +126,7 @@
 
 	// Read last byte
 	*data_addr = twiPtr->TWI_RHR;
+	return 0;
 }
 
 

==== //depot/projects/arm/src/sys/boot/arm/at91/libat91/lib.h#21 (text) ====

@@ -34,7 +34,7 @@
 
 /* The following function write eeprom at ee_addr using data 	*/
 /*  from data_add for size bytes.				*/
-void ReadEEPROM(unsigned eeoff, char *data_addr, unsigned size);
+int ReadEEPROM(unsigned eeoff, char *data_addr, unsigned size);
 void WriteEEPROM(unsigned eeoff, char *data_addr, unsigned size);
 void InitEEPROM(void);
 


More information about the p4-projects mailing list