Date: Wed, 29 Nov 2006 00:13:59 GMT From: Warner Losh <imp@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 110644 for review Message-ID: <200611290013.kAT0Dxdx027659@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=110644 Change 110644 by imp@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200611290013.kAT0Dxdx027659>