summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandreast <andreast@FreeBSD.org>2011-06-03 18:58:32 +0000
committerandreast <andreast@FreeBSD.org>2011-06-03 18:58:32 +0000
commitc87aaacb37e486140abfa953a47faede328892bc (patch)
tree852b0d68cb580595406716d21a4a3aa9f28377e8
parent72c50e51a578d789a06bec5ad77c3ee4fc24db00 (diff)
downloadFreeBSD-src-c87aaacb37e486140abfa953a47faede328892bc.zip
FreeBSD-src-c87aaacb37e486140abfa953a47faede328892bc.tar.gz
- Improve error handling.
- Add a retry loop for the i2c sensor reading. - Update the sensor handling for sensors which do not have a location entry. [1] Submitted by: [1] Justin Hibbits. Approved by: nwhitehorn (mentor)
-rw-r--r--sys/dev/iicbus/ds1775.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/sys/dev/iicbus/ds1775.c b/sys/dev/iicbus/ds1775.c
index faa4a1a..364f4d1 100644
--- a/sys/dev/iicbus/ds1775.c
+++ b/sys/dev/iicbus/ds1775.c
@@ -95,20 +95,28 @@ static int
ds1775_read_2(device_t dev, uint32_t addr, uint8_t reg, uint16_t *data)
{
uint8_t buf[4];
+ int err, try = 0;
struct iic_msg msg[2] = {
{ addr, IIC_M_WR | IIC_M_NOSTOP, 1, &reg },
{ addr, IIC_M_RD, 2, buf },
};
- if (iicbus_transfer(dev, msg, 2) != 0) {
- device_printf(dev, "iicbus read failed\n");
- return (EIO);
+ for (;;)
+ {
+ err = iicbus_transfer(dev, msg, 2);
+ if (err != 0)
+ goto retry;
+
+ *data = *((uint16_t*)buf);
+ return (0);
+ retry:
+ if (++try > 5) {
+ device_printf(dev, "iicbus read failed\n");
+ return (-1);
+ }
+ pause("ds1775_read_2", hz);
}
-
- *data = *((uint16_t*)buf);
-
- return (0);
}
static int
@@ -182,7 +190,10 @@ ds1775_start(void *xdev)
ctx = device_get_sysctl_ctx(dev);
sensroot_oid = device_get_sysctl_tree(dev);
- OF_getprop(child, "hwsensor-zone", &sc->sc_sensor.zone, sizeof(int));
+ if (OF_getprop(child, "hwsensor-zone", &sc->sc_sensor.zone,
+ sizeof(int)) < 0)
+ sc->sc_sensor.zone = 0;
+
plen = OF_getprop(child, "hwsensor-location", sc->sc_sensor.name,
sizeof(sc->sc_sensor.name));
units = "C";
@@ -199,8 +210,14 @@ ds1775_start(void *xdev)
}
/* Make up target temperatures. These are low, for the drive bay. */
- sc->sc_sensor.target_temp = 300 + FCU_ZERO_C_TO_K;
- sc->sc_sensor.max_temp = 600 + FCU_ZERO_C_TO_K;
+ if (sc->sc_sensor.zone == 0) {
+ sc->sc_sensor.target_temp = 500 + FCU_ZERO_C_TO_K;
+ sc->sc_sensor.max_temp = 600 + FCU_ZERO_C_TO_K;
+ }
+ else {
+ sc->sc_sensor.target_temp = 300 + FCU_ZERO_C_TO_K;
+ sc->sc_sensor.max_temp = 600 + FCU_ZERO_C_TO_K;
+ }
sc->sc_sensor.read =
(int (*)(struct pmac_therm *sc))(ds1775_sensor_read);
@@ -220,8 +237,11 @@ ds1775_sensor_read(struct ds1775_softc *sc)
{
uint16_t buf[2];
uint16_t read;
+ int err;
- ds1775_read_2(sc->sc_dev, sc->sc_addr, DS1775_TEMP, buf);
+ err = ds1775_read_2(sc->sc_dev, sc->sc_addr, DS1775_TEMP, buf);
+ if (err < 0)
+ return (-1);
read = *((int16_t *)buf);
@@ -243,6 +263,8 @@ ds1775_sensor_sysctl(SYSCTL_HANDLER_ARGS)
sc = device_get_softc(dev);
temp = ds1775_sensor_read(sc);
+ if (temp < 0)
+ return (EIO);
error = sysctl_handle_int(oidp, &temp, 0, req);
OpenPOWER on IntegriCloud