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;
 }

Reply via email to