From owner-p4-projects@FreeBSD.ORG Tue Dec 19 07:57:19 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0451716A415; Tue, 19 Dec 2006 07:57:19 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id D334416A407 for ; Tue, 19 Dec 2006 07:57:18 +0000 (UTC) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.FreeBSD.org (Postfix) with ESMTP id 865EF43C9F for ; Tue, 19 Dec 2006 07:57:18 +0000 (GMT) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id kBJ7vCBa058573 for ; Tue, 19 Dec 2006 07:57:13 GMT (envelope-from imp@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id kBJ7vCq3058570 for perforce@freebsd.org; Tue, 19 Dec 2006 07:57:12 GMT (envelope-from imp@freebsd.org) Date: Tue, 19 Dec 2006 07:57:12 GMT Message-Id: <200612190757.kBJ7vCq3058570@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to imp@freebsd.org using -f From: Warner Losh To: Perforce Change Reviews Cc: Subject: PERFORCE change 111931 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Dec 2006 07:57:19 -0000 http://perforce.freebsd.org/chv.cgi?CH=111931 Change 111931 by imp@imp_lighthouse on 2006/12/19 07:57:09 Fix two major bugs, and a bunch of nits: o Eliminate an extra, redundant reading off the sr. o If we don't read enough bytes, don't pretend that we did. Instead, return an error. Maybe we should give an indication of how many bytes were read in this case, but for now we just return the error. o When we encounter an error, use the big hammer of software reset to fix. This may not be entirely necessary but seems to help solve problems we see when reading after there's been an error. o Return ENXIO for NACK. Lame error message, but follows existing practice. o Use #defines for clock speeds rather than hard coding numbers. # this makes it possible to read from existent and then non-existent # devices in a tight loop w/o occasional data corruption of many # flavors. Affected files ... .. //depot/projects/arm/src/sys/arm/at91/at91_twi.c#40 edit Differences ... ==== //depot/projects/arm/src/sys/arm/at91/at91_twi.c#40 (text+ko) ==== @@ -45,6 +45,10 @@ #include #include "iicbus_if.h" +#define TWI_SLOW_CLOCK 1500 +#define TWI_FAST_CLOCK 45000 +#define TWI_FASTEST_CLOCK 90000 + struct at91_twi_softc { device_t dev; /* Myself */ @@ -123,7 +127,7 @@ AT91_TWI_LOCK_DESTROY(sc); goto out; } - sc->cwgr = TWI_CWGR_CKDIV(8 * AT91C_MASTER_CLOCK / 90000) | + sc->cwgr = TWI_CWGR_CKDIV(8 * AT91C_MASTER_CLOCK / TWI_FASTEST_CLOCK) | TWI_CWGR_CHDIV(TWI_CWGR_DIV(TWI_DEF_CLK)) | TWI_CWGR_CLDIV(TWI_CWGR_DIV(TWI_DEF_CLK)); WR4(sc, TWI_CR, TWI_CR_SWRST); @@ -232,7 +236,7 @@ if (counter <= 0) err = EBUSY; else if (sr & TWI_SR_NACK) - err = EADDRNOTAVAIL; + err = ENXIO; // iic nack convention return (err); } @@ -252,17 +256,17 @@ */ switch (speed) { case IIC_SLOW: - clk = 1500; + clk = TWI_SLOW_CLOCK; break; case IIC_FAST: - clk = 45000; + clk = TWI_FAST_CLOCK; break; case IIC_UNKNOWN: case IIC_FASTEST: default: - clk = 90000; + clk = TWI_FASTEST_CLOCK; break; } sc->cwgr = TWI_CWGR_CKDIV(1) | TWI_CWGR_CHDIV(TWI_CWGR_DIV(clk)) | @@ -332,7 +336,6 @@ if (msgs[i].flags & IIC_M_RD) { sr = RD4(sc, TWI_SR); while (!(sr & TWI_SR_TXCOMP)) { - sr = RD4(sc, TWI_SR); if ((sr = RD4(sc, TWI_SR)) & TWI_SR_RXRDY) { len--; *buf++ = RD4(sc, TWI_RHR) & 0xff; @@ -340,8 +343,8 @@ WR4(sc, TWI_CR, TWI_CR_STOP); } } - if (sr & TWI_SR_NACK) { - err = EADDRNOTAVAIL; + if (len > 0 || (sr & TWI_SR_NACK)) { + err = ENXIO; // iic nack convention goto out; } } else { @@ -357,8 +360,11 @@ break; } out:; - if (err) - WR4(sc, TWI_CR, TWI_CR_STOP); + if (err) { + WR4(sc, TWI_CR, TWI_CR_SWRST); + WR4(sc, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS); + WR4(sc, TWI_CWGR, sc->cwgr); + } AT91_TWI_UNLOCK(sc); return (err); }