summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2005-11-22 11:54:54 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2005-11-22 11:54:54 +0000
commitd512dcc09f9c237dc309d0f3809bb03918b24c35 (patch)
tree13ec6625a90a1fff848e52f928da3e136993a318 /sys/arch
parent5ebfeb516ed416f744a705daa0e24286685ce7f2 (diff)
for every sensor esm looks after it has to talk to the hardware, which
means it could busy wait while the hardware gets ready. all the sensors are updated out of a single timeout. doing this for the 30ish esm sensors on my machine is probably not a good thing... this changes the way updates are handled. instead of a single big update for all the sensors, we now update only one sensor in a timeout. after that sensor has been updated it sets up a very short timeout for the next sensor to run out of. we also use the short timeouts to retry the same sensor if the hardware isnt ready which means we avoid the (worst) busy wait.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/i386/i386/esm.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/sys/arch/i386/i386/esm.c b/sys/arch/i386/i386/esm.c
index 9969db4dee8..a4cd31eb1fb 100644
--- a/sys/arch/i386/i386/esm.c
+++ b/sys/arch/i386/i386/esm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: esm.c,v 1.6 2005/11/22 08:33:24 dlg Exp $ */
+/* $OpenBSD: esm.c,v 1.7 2005/11/22 11:54:53 dlg Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -73,6 +73,8 @@ struct esm_softc {
bus_space_handle_t sc_ioh;
TAILQ_HEAD(, esm_sensor) sc_sensors;
+ struct esm_sensor *sc_nextsensor;
+ int sc_retries;
struct timeout sc_timeout;
};
@@ -168,6 +170,8 @@ esm_attach(struct device *parent, struct device *self, void *aux)
if (!TAILQ_EMPTY(&sc->sc_sensors)) {
DPRINTF("%s: starting refresh\n", DEVNAME(sc));
+ sc->sc_nextsensor = TAILQ_FIRST(&sc->sc_sensors);
+ sc->sc_retries = 0;
timeout_set(&sc->sc_timeout, esm_refresh, sc);
timeout_add(&sc->sc_timeout, hz * 10);
}
@@ -177,26 +181,24 @@ void
esm_refresh(void *arg)
{
struct esm_softc *sc = arg;
- struct esm_sensor *sensor;
+ struct esm_sensor *sensor = sc->sc_nextsensor;
struct esm_smb_req req;
struct esm_smb_resp resp;
struct esm_smb_resp_val *val = &resp.resp_val;
memset(&req, 0, sizeof(req));
req.h_cmd = ESM2_CMD_SMB_XMIT_RECV;
+ req.h_dev = sensor->es_dev;
req.h_txlen = sizeof(req.req_val);
req.h_rxlen = sizeof(resp.resp_val);
req.req_val.v_cmd = ESM2_SMB_SENSOR_VALUE;
+ req.req_val.v_sensor = sensor->es_id;
- TAILQ_FOREACH(sensor, &sc->sc_sensors, es_entry) {
- req.h_dev = sensor->es_dev;
- req.req_val.v_sensor = sensor->es_id;
-
- if (esm_smb_cmd(sc, &req, &resp, 1) != 0) {
- sensor->es_sensor.flags |= SENSOR_FINVALID;
- continue;
- }
-
+ if (esm_smb_cmd(sc, &req, &resp, 0) != 0) {
+ if (++sc->sc_retries < 10)
+ goto tick;
+ sensor->es_sensor.flags |= SENSOR_FINVALID;
+ } else {
switch (sensor->es_sensor.type) {
case SENSOR_TEMP:
sensor->es_sensor.value = esm_val2temp(val->v_reading);
@@ -208,9 +210,20 @@ esm_refresh(void *arg)
sensor->es_sensor.value = val->v_reading;
break;
}
+ sensor->es_sensor.flags &= ~SENSOR_FINVALID;
}
- timeout_add(&sc->sc_timeout, hz * 10);
+ sc->sc_nextsensor = TAILQ_NEXT(sensor, es_entry);
+ sc->sc_retries = 0;
+
+ if (sc->sc_nextsensor == NULL) {
+ sc->sc_nextsensor = TAILQ_FIRST(&sc->sc_sensors);
+ timeout_add(&sc->sc_timeout, hz * 10);
+ return;
+ }
+tick:
+ timeout_add(&sc->sc_timeout, hz / 100);
+
}
int
@@ -545,7 +558,7 @@ esm_cmd(struct esm_softc *sc, void *cmd, size_t cmdlen, void *resp,
int i;
/* Wait for card ready */
- if (esm_bmc_ready(sc, ESM2_TC_REG, ESM2_TC_READY, 0, 1) != 0)
+ if (esm_bmc_ready(sc, ESM2_TC_REG, ESM2_TC_READY, 0, wait) != 0)
return (1); /* busy */
/* Write command data to port */