summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2005-11-15 18:25:25 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2005-11-15 18:25:25 +0000
commit33a4e83db5b746345cf3d350489012c8604b411d (patch)
treef684e382c2b992f3ae242a9d1e69c012fdde7697
parent8bf87d0150feb03ff6c0587cf6152afd86d92759 (diff)
avoid integer overflow in fan speed calculations, from kettenis
also, if things appear majorly wonky, mark sensors invalid
-rw-r--r--sys/dev/i2c/lm87.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/sys/dev/i2c/lm87.c b/sys/dev/i2c/lm87.c
index e67bca2b019..a36af99644d 100644
--- a/sys/dev/i2c/lm87.c
+++ b/sys/dev/i2c/lm87.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lm87.c,v 1.2 2005/11/15 16:23:31 deraadt Exp $ */
+/* $OpenBSD: lm87.c,v 1.3 2005/11/15 18:25:24 deraadt Exp $ */
/*
* Copyright (c) 2005 Mark Kettenis
@@ -106,8 +106,8 @@ lmenv_attach(struct device *parent, struct device *self, void *aux)
printf(": cannot read Fan Divisor register\n");
return;
}
- sc->sc_fan1_div = (data >> 4) & 0x03;
- sc->sc_fan2_div = (data >> 6) & 0x03;
+ sc->sc_fan1_div = 1 << ((data >> 4) & 0x03);
+ sc->sc_fan2_div = 1 << ((data >> 6) & 0x03);
cmd = LM87_REVISION;
if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
@@ -182,6 +182,7 @@ lmenv_refresh(void *arg)
{
struct lmenv_softc *sc = arg;
u_int8_t cmd, data;
+ u_int tmp;
int sensor;
iic_acquire_bus(sc->sc_tag, 0);
@@ -194,6 +195,7 @@ lmenv_refresh(void *arg)
continue;
}
+ sc->sc_sensor[sensor].flags &= ~SENSOR_FINVALID;
switch (sensor) {
case LMENV_2_5V:
sc->sc_sensor[sensor].value = 2500000 * data / 192;
@@ -217,18 +219,23 @@ lmenv_refresh(void *arg)
(int8_t)data * 1000000 + 273150000;
break;
case LMENV_FAN1:
- sc->sc_sensor[sensor].value =
- (1350000 * data) / sc->sc_fan1_div;
+ tmp = data * sc->sc_fan1_div;
+ if (tmp == 0)
+ sc->sc_sensor[sensor].flags |= SENSOR_FINVALID;
+ else
+ sc->sc_sensor[sensor].value = 1350000 / tmp;
break;
case LMENV_FAN2:
- sc->sc_sensor[sensor].value =
- (1350000 * data) / sc->sc_fan2_div;
+ tmp = data * sc->sc_fan2_div;
+ if (tmp == 0)
+ sc->sc_sensor[sensor].flags |= SENSOR_FINVALID;
+ else
+ sc->sc_sensor[sensor].value = 1350000 / tmp;
break;
default:
sc->sc_sensor[sensor].flags |= SENSOR_FINVALID;
- continue;
+ break;
}
- sc->sc_sensor[sensor].flags &= ~SENSOR_FINVALID;
}
iic_release_bus(sc->sc_tag, 0);