From 704a9b346c85897e92413af2bb1c599342ed6650 Mon Sep 17 00:00:00 2001 From: pgoyette Date: Mon, 9 Feb 2009 20:27:21 +0000 Subject: [PATCH] Previous check for ADM1027 caused a kernel panic, since the read routine can be called _before_ we've identified the chip. Ensure that sc_chip is initialized to NULL before chip is identified, and if it is NULL or ADM1027, use the less-efficient send_byte/receive_byte. While here, don't attempt to release the i2c bus if we failed to acquire it. This would cause a panic on a LOCKDEBUG kernel. Thanks to Nicholas Joly for pointing out both of these bugs. --- sys/dev/i2c/dbcool.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sys/dev/i2c/dbcool.c b/sys/dev/i2c/dbcool.c index 4a7d3b8614f3..36a1e03a3129 100644 --- a/sys/dev/i2c/dbcool.c +++ b/sys/dev/i2c/dbcool.c @@ -1,4 +1,4 @@ -/* $NetBSD: dbcool.c,v 1.10 2009/02/08 17:48:02 pgoyette Exp $ */ +/* $NetBSD: dbcool.c,v 1.11 2009/02/09 20:27:21 pgoyette Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -49,7 +49,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: dbcool.c,v 1.10 2009/02/08 17:48:02 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dbcool.c,v 1.11 2009/02/09 20:27:21 pgoyette Exp $"); #include #include @@ -591,6 +591,7 @@ dbcool_match(device_t parent, cfdata_t cf, void *aux) struct dbcool_softc sc; sc.sc_tag = ia->ia_tag; sc.sc_addr = ia->ia_addr; + sc.sc_chip = NULL; sc.sc_readreg = dbcool_readreg; sc.sc_writereg = dbcool_writereg; @@ -615,6 +616,7 @@ dbcool_attach(device_t parent, device_t self, void *aux) sc->sc_dev = self; sc->sc_readreg = dbcool_readreg; sc->sc_writereg = dbcool_writereg; + sc->sc_chip = NULL; (void)dbcool_chip_ident(sc); aprint_naive("\n"); @@ -699,9 +701,9 @@ dbcool_readreg(struct dbcool_softc *sc, uint8_t reg) uint8_t data = 0; if (iic_acquire_bus(sc->sc_tag, 0) != 0) - goto bad; + return data; - if (sc->sc_chip->flags & DBCFLAG_ADM1027) { + if ( sc->sc_chip == NULL || sc->sc_chip->flags & DBCFLAG_ADM1027) { /* ADM1027 doesn't support i2c read_byte protocol */ if (iic_smbus_send_byte(sc->sc_tag, sc->sc_addr, reg, 0) != 0) goto bad;