diff options
author | andreast <andreast@FreeBSD.org> | 2011-06-03 18:58:32 +0000 |
---|---|---|
committer | andreast <andreast@FreeBSD.org> | 2011-06-03 18:58:32 +0000 |
commit | c87aaacb37e486140abfa953a47faede328892bc (patch) | |
tree | 852b0d68cb580595406716d21a4a3aa9f28377e8 | |
parent | 72c50e51a578d789a06bec5ad77c3ee4fc24db00 (diff) | |
download | FreeBSD-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.c | 44 |
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, ® }, { 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); |