Module Name:    src
Committed By:   msaitoh
Date:           Tue Jan  5 11:49:32 UTC 2016

Modified Files:
        src/sys/dev/i2c: spdmem_i2c.c
        src/sys/dev/ic: spdmem.c spdmemvar.h

Log Message:
Check whether iic_exec is failed or not.
- This change fixes a bug that a device that the checksum is really 0 fails
  attaching.
- Reduce the number of access to one if a device doesn't exist. Without this
  change and iic(4) does polling, it'll wait long time.


To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/sys/dev/i2c/spdmem_i2c.c
cvs rdiff -u -r1.20 -r1.21 src/sys/dev/ic/spdmem.c
cvs rdiff -u -r1.10 -r1.11 src/sys/dev/ic/spdmemvar.h

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/spdmem_i2c.c
diff -u src/sys/dev/i2c/spdmem_i2c.c:1.11 src/sys/dev/i2c/spdmem_i2c.c:1.12
--- src/sys/dev/i2c/spdmem_i2c.c:1.11	Mon Dec  7 09:41:37 2015
+++ src/sys/dev/i2c/spdmem_i2c.c	Tue Jan  5 11:49:32 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: spdmem_i2c.c,v 1.11 2015/12/07 09:41:37 mlelstv Exp $ */
+/* $NetBSD: spdmem_i2c.c,v 1.12 2016/01/05 11:49:32 msaitoh Exp $ */
 
 /*
  * Copyright (c) 2007 Nicolas Joly
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spdmem_i2c.c,v 1.11 2015/12/07 09:41:37 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spdmem_i2c.c,v 1.12 2016/01/05 11:49:32 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -95,7 +95,7 @@ static int  spdmem_i2c_detach(device_t, 
 CFATTACH_DECL_NEW(spdmem_iic, sizeof(struct spdmem_i2c_softc),
     spdmem_i2c_match, spdmem_i2c_attach, spdmem_i2c_detach, NULL);
 
-static uint8_t spdmem_i2c_read(struct spdmem_softc *, uint16_t);
+static int spdmem_i2c_read(struct spdmem_softc *, uint16_t, uint8_t *);
 
 static int
 spdmem_i2c_match(device_t parent, cfdata_t match, void *aux)
@@ -153,32 +153,33 @@ spdmem_i2c_detach(device_t self, int fla
 	return spdmem_common_detach(&sc->sc_base, self);
 }
 
-static uint8_t
-spdmem_i2c_read(struct spdmem_softc *softc, uint16_t addr)
+static int
+spdmem_i2c_read(struct spdmem_softc *softc, uint16_t addr, uint8_t *val)
 {
-	uint8_t reg, val;
+	uint8_t reg;
 	struct spdmem_i2c_softc *sc = (struct spdmem_i2c_softc *)softc;
 	static uint8_t dummy = 0;
+	int rv;
 
 	reg = addr & 0xff;
 
 	iic_acquire_bus(sc->sc_tag, 0);
 
 	if (addr & 0x100) {
-		iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_page1,
-			&dummy, 1, NULL, 0, I2C_F_POLL);
-		iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
-			&reg, 1, &val, 1, I2C_F_POLL);
-		iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_page0,
-			&dummy, 1, NULL, 0, I2C_F_POLL);
+		rv = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_page1,
+		    &dummy, 1, NULL, 0, I2C_F_POLL);
+		rv |= iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
+		    &reg, 1, val, 1, I2C_F_POLL);
+		rv |= iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
+		    sc->sc_page0, &dummy, 1, NULL, 0, I2C_F_POLL);
 	} else {
-		iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
-			&reg, 1, &val, 1, I2C_F_POLL);
+		rv = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
+		    &reg, 1, val, 1, I2C_F_POLL);
 	}
 
 	iic_release_bus(sc->sc_tag, 0);
 
-	return val;
+	return rv;
 }
 
 MODULE(MODULE_CLASS_DRIVER, spdmem, "i2cexec");

Index: src/sys/dev/ic/spdmem.c
diff -u src/sys/dev/ic/spdmem.c:1.20 src/sys/dev/ic/spdmem.c:1.21
--- src/sys/dev/ic/spdmem.c:1.20	Thu Dec 24 14:16:18 2015
+++ src/sys/dev/ic/spdmem.c	Tue Jan  5 11:49:32 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: spdmem.c,v 1.20 2015/12/24 14:16:18 msaitoh Exp $ */
+/* $NetBSD: spdmem.c,v 1.21 2016/01/05 11:49:32 msaitoh Exp $ */
 
 /*
  * Copyright (c) 2007 Nicolas Joly
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spdmem.c,v 1.20 2015/12/24 14:16:18 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spdmem.c,v 1.21 2016/01/05 11:49:32 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -154,14 +154,15 @@ static const uint16_t spdmem_cycle_frac[
 
 /* CRC functions used for certain memory types */
 
-static uint16_t spdcrc16 (struct spdmem_softc *sc, int count)
+static uint16_t
+spdcrc16(struct spdmem_softc *sc, int count)
 {
 	uint16_t crc;
 	int i, j;
 	uint8_t val;
 	crc = 0;
 	for (j = 0; j <= count; j++) {
-		val = (sc->sc_read)(sc, j);
+		(sc->sc_read)(sc, j, &val);
 		crc = crc ^ val << 8;
 		for (i = 0; i < 8; ++i)
 			if (crc & 0x8000)
@@ -180,16 +181,20 @@ spdmem_common_probe(struct spdmem_softc 
 	int spd_len, spd_crc_cover;
 	uint16_t crc_calc, crc_spd;
 
-	spd_type = (sc->sc_read)(sc, 2);
+	/* Read failed means a device doesn't exist */
+	if ((sc->sc_read)(sc, 2, &spd_type) != 0)
+		return 0;
 
 	/* For older memory types, validate the checksum over 1st 63 bytes */
 	if (spd_type <= SPDMEM_MEMTYPE_DDR2SDRAM) {
-		for (i = 0; i < 63; i++)
-			cksum += (sc->sc_read)(sc, i);
+		for (i = 0; i < 63; i++) {
+			(sc->sc_read)(sc, i, &val);
+			cksum += val;
+		}
 
-		val = (sc->sc_read)(sc, 63);
+		(sc->sc_read)(sc, 63, &val);
 
-		if (cksum == 0 || (cksum & 0xff) != val) {
+		if ((cksum & 0xff) != val) {
 			aprint_debug("spd checksum failed, calc = 0x%02x, "
 				     "spd = 0x%02x\n", cksum, val);
 			return 0;
@@ -199,7 +204,8 @@ spdmem_common_probe(struct spdmem_softc 
 
 	/* For DDR3 and FBDIMM, verify the CRC */
 	else if (spd_type <= SPDMEM_MEMTYPE_DDR3SDRAM) {
-		spd_len = (sc->sc_read)(sc, 0);
+		(sc->sc_read)(sc, 0, &val);
+		spd_len = val;
 		if (spd_len & SPDMEM_SPDCRC_116)
 			spd_crc_cover = 116;
 		else
@@ -220,8 +226,10 @@ spdmem_common_probe(struct spdmem_softc 
 		if (spd_crc_cover > spd_len)
 			return 0;
 		crc_calc = spdcrc16(sc, spd_crc_cover);
-		crc_spd = (sc->sc_read)(sc, 127) << 8;
-		crc_spd |= (sc->sc_read)(sc, 126);
+		(sc->sc_read)(sc, 127, &val);
+		crc_spd = val << 8;
+		(sc->sc_read)(sc, 126, &val);
+		crc_spd |= val;
 		if (crc_calc != crc_spd) {
 			aprint_debug("crc16 failed, covers %d bytes, "
 				     "calc = 0x%04x, spd = 0x%04x\n",
@@ -230,7 +238,8 @@ spdmem_common_probe(struct spdmem_softc 
 		}
 		return 1;
 	} else if (spd_type == SPDMEM_MEMTYPE_DDR4SDRAM) {
-		spd_len = (sc->sc_read)(sc, 0) & 0x0f;
+		(sc->sc_read)(sc, 0, &val);
+		spd_len = val & 0x0f;
 		if ((unsigned int)spd_len > __arraycount(spd_rom_sizes))
 			return 0;
 		spd_len = spd_rom_sizes[spd_len];
@@ -238,8 +247,10 @@ spdmem_common_probe(struct spdmem_softc 
 		if (spd_crc_cover > spd_len)
 			return 0;
 		crc_calc = spdcrc16(sc, spd_crc_cover);
-		crc_spd = (sc->sc_read)(sc, 127) << 8;
-		crc_spd |= (sc->sc_read)(sc, 126);
+		(sc->sc_read)(sc, 127, &val);
+		crc_spd = val << 8;
+		(sc->sc_read)(sc, 126, &val);
+		crc_spd |= val;
 		if (crc_calc != crc_spd) {
 			aprint_debug("crc16 failed, covers %d bytes, "
 				     "calc = 0x%04x, spd = 0x%04x\n",
@@ -269,9 +280,9 @@ spdmem_common_attach(struct spdmem_softc
 	unsigned int i, spd_len, spd_size;
 	const struct sysctlnode *node = NULL;
 
-	s->sm_len = (sc->sc_read)(sc, 0);
-	s->sm_size = (sc->sc_read)(sc, 1);
-	s->sm_type = (sc->sc_read)(sc, 2);
+	(sc->sc_read)(sc, 0, &s->sm_len);
+	(sc->sc_read)(sc, 1, &s->sm_size);
+	(sc->sc_read)(sc, 2, &s->sm_type);
 
 	if (s->sm_type == SPDMEM_MEMTYPE_DDR4SDRAM) {
 		/*
@@ -315,7 +326,7 @@ spdmem_common_attach(struct spdmem_softc
 	if (spd_len > sizeof(struct spdmem))
 		spd_len = sizeof(struct spdmem);
 	for (i = 3; i < spd_len; i++)
-		((uint8_t *)s)[i] = (sc->sc_read)(sc, i);
+		(sc->sc_read)(sc, i, &((uint8_t *)s)[i]);
 
 	/*
 	 * Setup our sysctl subtree, hw.spdmemN

Index: src/sys/dev/ic/spdmemvar.h
diff -u src/sys/dev/ic/spdmemvar.h:1.10 src/sys/dev/ic/spdmemvar.h:1.11
--- src/sys/dev/ic/spdmemvar.h:1.10	Thu Dec 24 14:16:18 2015
+++ src/sys/dev/ic/spdmemvar.h	Tue Jan  5 11:49:32 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: spdmemvar.h,v 1.10 2015/12/24 14:16:18 msaitoh Exp $ */
+/* $NetBSD: spdmemvar.h,v 1.11 2016/01/05 11:49:32 msaitoh Exp $ */
 
 /*
  * Copyright (c) 2007 Paul Goyette
@@ -891,7 +891,7 @@ struct spdmem {
 #define SPDMEM_TYPE_MAXLEN 40
 
 struct spdmem_softc {
-	uint8_t		(*sc_read)(struct spdmem_softc *, uint16_t);
+	int		(*sc_read)(struct spdmem_softc *, uint16_t, uint8_t *);
 	struct spdmem	sc_spd_data;
 	struct sysctllog *sc_sysctl_log;
 	char		sc_type[SPDMEM_TYPE_MAXLEN];

Reply via email to