Module Name: src Committed By: thorpej Date: Mon Jan 13 00:09:28 UTC 2020
Modified Files: src/sys/dev/i2c: gttwsi_core.c Log Message: Improve diagnostic messages: - Pass an additional argument to gttwsi_wait() to indicate what's going on, and report that, along with the error code from cv_timedwait(), if a timeout occurs. - In gttwsi_send_stop(), if we don't get the expected NRS status, report which status we *did* get when a timeout occurs. To generate a diff of this commit: cvs rdiff -u -r1.12 -r1.13 src/sys/dev/i2c/gttwsi_core.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/i2c/gttwsi_core.c diff -u src/sys/dev/i2c/gttwsi_core.c:1.12 src/sys/dev/i2c/gttwsi_core.c:1.13 --- src/sys/dev/i2c/gttwsi_core.c:1.12 Sun Jan 12 17:48:42 2020 +++ src/sys/dev/i2c/gttwsi_core.c Mon Jan 13 00:09:28 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: gttwsi_core.c,v 1.12 2020/01/12 17:48:42 thorpej Exp $ */ +/* $NetBSD: gttwsi_core.c,v 1.13 2020/01/13 00:09:28 thorpej Exp $ */ /* * Copyright (c) 2008 Eiji Kawauchi. * All rights reserved. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: gttwsi_core.c,v 1.12 2020/01/12 17:48:42 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gttwsi_core.c,v 1.13 2020/01/13 00:09:28 thorpej Exp $"); #include "locators.h" #include <sys/param.h> @@ -90,7 +90,7 @@ static int gttwsi_read_byte(void *v, uin static int gttwsi_write_byte(void *v, uint8_t val, int flags); static int gttwsi_wait(struct gttwsi_softc *, uint32_t, uint32_t, - uint32_t, int); + uint32_t, int, const char *); uint32_t gttwsi_read_4(struct gttwsi_softc *sc, uint32_t reg) @@ -195,7 +195,7 @@ gttwsi_send_start(void *v, int flags) else expect = STAT_SCT; sc->sc_started = true; - return gttwsi_wait(sc, CONTROL_START, expect, 0, flags); + return gttwsi_wait(sc, CONTROL_START, expect, 0, flags, "send-start"); } static int @@ -203,7 +203,7 @@ gttwsi_send_stop(void *v, int flags) { struct gttwsi_softc *sc = v; int retry = TWSI_RETRY_COUNT; - uint32_t control; + uint32_t control, status; sc->sc_started = false; @@ -213,14 +213,15 @@ gttwsi_send_stop(void *v, int flags) control |= CONTROL_IFLG; gttwsi_write_4(sc, TWSI_CONTROL, control); while (retry > 0) { - if (gttwsi_read_4(sc, TWSI_STATUS) == STAT_NRS) + if ((status = gttwsi_read_4(sc, TWSI_STATUS)) == STAT_NRS) return 0; retry--; DELAY(TWSI_STAT_DELAY); } - aprint_error_dev(sc->sc_dev, "send STOP failed\n"); - return -1; + aprint_error_dev(sc->sc_dev, "send STOP failed, status=0x%02x\n", + status); + return EWOULDBLOCK; } static int @@ -254,7 +255,7 @@ gttwsi_initiate_xfer(void *v, i2c_addr_t */ data |= 0xf0 | ((addr & 0x300) >> 7); gttwsi_write_4(sc, TWSI_DATA, data); - error = gttwsi_wait(sc, 0, expect, alt, flags); + error = gttwsi_wait(sc, 0, expect, alt, flags, "send-addr-10"); if (error) return error; /* @@ -273,7 +274,7 @@ gttwsi_initiate_xfer(void *v, i2c_addr_t data |= (addr << 1); gttwsi_write_4(sc, TWSI_DATA, data); - return gttwsi_wait(sc, 0, expect, alt, flags); + return gttwsi_wait(sc, 0, expect, alt, flags, "send-addr"); } static int @@ -282,10 +283,13 @@ gttwsi_read_byte(void *v, uint8_t *valp, struct gttwsi_softc *sc = v; int error; - if (flags & I2C_F_LAST) - error = gttwsi_wait(sc, 0, STAT_MRRD_ANT, 0, flags); - else - error = gttwsi_wait(sc, CONTROL_ACK, STAT_MRRD_AT, 0, flags); + if (flags & I2C_F_LAST) { + error = gttwsi_wait(sc, 0, STAT_MRRD_ANT, 0, flags, + "read-last-byte"); + } else { + error = gttwsi_wait(sc, CONTROL_ACK, STAT_MRRD_AT, 0, flags, + "read-byte"); + } if (!error) *valp = gttwsi_read_4(sc, TWSI_DATA); if ((flags & (I2C_F_LAST | I2C_F_STOP)) == (I2C_F_LAST | I2C_F_STOP)) @@ -300,7 +304,7 @@ gttwsi_write_byte(void *v, uint8_t val, int error; gttwsi_write_4(sc, TWSI_DATA, val); - error = gttwsi_wait(sc, 0, STAT_MTDB_AR, 0, flags); + error = gttwsi_wait(sc, 0, STAT_MTDB_AR, 0, flags, "write-byte"); if (flags & I2C_F_STOP) gttwsi_send_stop(sc, flags); return error; @@ -308,7 +312,7 @@ gttwsi_write_byte(void *v, uint8_t val, static int gttwsi_wait(struct gttwsi_softc *sc, uint32_t control, uint32_t expect, - uint32_t alt, int flags) + uint32_t alt, int flags, const char *what) { uint32_t status; int timo, error = 0; @@ -328,8 +332,9 @@ gttwsi_wait(struct gttwsi_softc *sc, uin break; if (!(flags & I2C_F_POLL)) { error = cv_timedwait(&sc->sc_cv, &sc->sc_mtx, hz); - if (error) + if (error) { break; + } } else { DELAY(TWSI_RETRY_DELAY); if (timo++ > 1000000) /* 1sec */ @@ -337,9 +342,19 @@ gttwsi_wait(struct gttwsi_softc *sc, uin } } if ((control & CONTROL_IFLG) == 0) { + /* + * error is set by the cv_timedwait() call above in the + * non-polled case. + */ + if (flags & I2C_F_POLL) { + error = EWOULDBLOCK; + } else { + KASSERT(error != 0); + } aprint_error_dev(sc->sc_dev, - "gttwsi_wait(): timeout, control=0x%x\n", control); - error = EWOULDBLOCK; + "gttwsi_wait(): %s timeout%s, control=0x%x, error=%d\n", + what, (flags & I2C_F_POLL) ? " (polled)" : "", + control, error); goto end; } status = gttwsi_read_4(sc, TWSI_STATUS); @@ -356,7 +371,7 @@ gttwsi_wait(struct gttwsi_softc *sc, uin expect); error = EIO; } -end: + end: mutex_exit(&sc->sc_mtx); return error; }