summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2005-11-30 11:46:58 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2005-11-30 11:46:58 +0000
commit161500aa06a4c0fc4fe25cebbacbefa630ffac96 (patch)
treec3f0dd69e0f51343547049222b2e74044e198308
parent3f0619c045bbeaaae8748c526b8f7f336704830c (diff)
determine the status of fan, volt, and temp sensors by reading the
thresholds off at attach and then comparing the value at update to these cutoffs.
-rw-r--r--sys/arch/i386/i386/esm.c82
-rw-r--r--sys/arch/i386/i386/esmreg.h25
2 files changed, 98 insertions, 9 deletions
diff --git a/sys/arch/i386/i386/esm.c b/sys/arch/i386/i386/esm.c
index 21fe021f4dd..dea5799d643 100644
--- a/sys/arch/i386/i386/esm.c
+++ b/sys/arch/i386/i386/esm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: esm.c,v 1.21 2005/11/28 23:56:04 deraadt Exp $ */
+/* $OpenBSD: esm.c,v 1.22 2005/11/30 11:46:57 dlg Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -34,12 +34,10 @@
#include <arch/i386/i386/esmreg.h>
#include <arch/i386/isa/isa_machdep.h>
-/* #define ESM_DEBUG */
-
#ifdef ESM_DEBUG
#define DPRINTF(x...) do { if (esmdebug) printf(x); } while (0)
#define DPRINTFN(n,x...) do { if (esmdebug > (n)) printf(x); } while (0)
-int esmdebug = 2;
+int esmdebug = 3;
#else
#define DPRINTF(x...) /* x */
#define DPRINTFN(n,x...) /* n: x */
@@ -82,6 +80,13 @@ struct esm_sensor {
enum esm_sensor_type es_type;
+ struct {
+ u_int16_t th_lo_crit;
+ u_int16_t th_lo_warn;
+ u_int16_t th_hi_warn;
+ u_int16_t th_hi_crit;
+ } es_thresholds;
+
struct sensor *es_sensor;
TAILQ_ENTRY(esm_sensor) es_entry;
};
@@ -124,6 +129,8 @@ int esm_get_devmap(struct esm_softc *, int, struct esm_devmap *);
void esm_devmap(struct esm_softc *, struct esm_devmap *);
void esm_make_sensors(struct esm_softc *, struct esm_devmap *,
struct esm_sensor_map *, int);
+int esm_thresholds(struct esm_softc *, struct esm_devmap *,
+ struct esm_sensor *);
int esm_bmc_ready(struct esm_softc *, int, u_int8_t, u_int8_t, int);
int esm_cmd(struct esm_softc *, void *, size_t, void *, size_t,
@@ -348,6 +355,30 @@ esm_refresh(void *arg)
es->es_sensor->flags &= ~SENSOR_FINVALID;
break;
}
+
+ switch (es->es_type) {
+ case ESM_S_TEMP:
+ case ESM_S_FANRPM:
+ case ESM_S_VOLTS:
+ if (val->v_reading >= es->es_thresholds.th_hi_crit ||
+ val->v_reading <= es->es_thresholds.th_lo_crit) {
+ es->es_sensor->status = SENSOR_S_CRIT;
+ break;
+ }
+
+ if (val->v_reading >= es->es_thresholds.th_hi_warn ||
+ val->v_reading <= es->es_thresholds.th_lo_warn) {
+ es->es_sensor->status = SENSOR_S_WARN;
+ break;
+ }
+
+ es->es_sensor->status = SENSOR_S_OK;
+ break;
+
+ default:
+ break;
+ }
+
}
sc->sc_nextsensor = TAILQ_NEXT(es, es_entry);
@@ -788,6 +819,15 @@ esm_make_sensors(struct esm_softc *sc, struct esm_devmap *devmap,
}
break;
+ case ESM_S_TEMP:
+ case ESM_S_FANRPM:
+ case ESM_S_VOLTS:
+ if (esm_thresholds(sc, devmap, es) != 0) {
+ free(es, M_DEVBUF);
+ continue;
+ }
+ /* FALLTHROUGH */
+
default:
nsensors = 1;
s = malloc(sizeof(struct sensor), M_DEVBUF, M_NOWAIT);
@@ -813,6 +853,40 @@ esm_make_sensors(struct esm_softc *sc, struct esm_devmap *devmap,
}
int
+esm_thresholds(struct esm_softc *sc, struct esm_devmap *devmap,
+ struct esm_sensor *es)
+{
+ struct esm_smb_req req;
+ struct esm_smb_resp resp;
+ struct esm_smb_resp_thr *thr = &resp.resp_thr;
+
+ memset(&req, 0, sizeof(req));
+ req.h_cmd = ESM2_CMD_SMB_XMIT_RECV;
+ req.h_dev = devmap->index;
+ req.h_txlen = sizeof(req.req_thr);
+ req.h_rxlen = sizeof(resp.resp_thr);
+
+ req.req_thr.t_cmd = ESM2_SMB_SENSOR_THRESHOLDS;
+ req.req_thr.t_sensor = es->es_id;
+
+ if (esm_smb_cmd(sc, &req, &resp, 1) != 0)
+ return (1);
+
+ DPRINTFN(2, "%s: dev: %d sensor: %d lo fail: %d hi fail: %d "
+ "lo warn: %d hi warn: %d hysterisis: %d checksum: 0x%02x\n",
+ DEVNAME(sc), devmap->index, es->es_id, thr->t_lo_fail,
+ thr->t_hi_fail, thr->t_lo_warn, thr->t_hi_warn, thr->t_hysterisis,
+ thr->t_checksum);
+
+ es->es_thresholds.th_lo_crit = thr->t_lo_fail;
+ es->es_thresholds.th_lo_warn = thr->t_lo_warn;
+ es->es_thresholds.th_hi_warn = thr->t_hi_warn;
+ es->es_thresholds.th_hi_crit = thr->t_hi_fail;
+
+ return (0);
+}
+
+int
esm_bmc_ready(struct esm_softc *sc, int port, u_int8_t mask, u_int8_t val,
int wait)
{
diff --git a/sys/arch/i386/i386/esmreg.h b/sys/arch/i386/i386/esmreg.h
index 873e35dd162..3aee53b9fbf 100644
--- a/sys/arch/i386/i386/esmreg.h
+++ b/sys/arch/i386/i386/esmreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: esmreg.h,v 1.8 2005/11/28 22:13:49 deraadt Exp $ */
+/* $OpenBSD: esmreg.h,v 1.9 2005/11/30 11:46:57 dlg Exp $ */
/*
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -138,18 +138,19 @@ struct esm_devmap_resp {
struct esm_devmap devmap[1]; /* request one map at a time */
} __packed;
-
/* ESM SMB requests */
-struct esm_smb_req_hdr {
-} __packed;
-
struct esm_smb_req_val {
u_int8_t v_cmd;
u_int8_t v_initiator;
u_int8_t v_sensor;
} __packed;
+struct esm_smb_req_thr {
+ u_int8_t t_cmd;
+ u_int8_t t_sensor;
+} __packed;
+
struct esm_smb_req {
struct {
u_int8_t _cmd;
@@ -164,8 +165,10 @@ struct esm_smb_req {
union {
struct esm_smb_req_val _val;
+ struct esm_smb_req_thr _thr;
} __packed _;
#define req_val _._val
+#define req_thr _._thr
} __packed;
@@ -177,6 +180,16 @@ struct esm_smb_resp_val {
u_int8_t v_checksum;
} __packed;
+struct esm_smb_resp_thr {
+ u_int8_t t_sensor;
+ u_int16_t t_lo_fail;
+ u_int16_t t_hi_fail;
+ u_int16_t t_lo_warn;
+ u_int16_t t_hi_warn;
+ u_int16_t t_hysterisis;
+ u_int8_t t_checksum;
+} __packed;
+
struct esm_smb_resp {
struct {
u_int8_t _status;
@@ -193,8 +206,10 @@ struct esm_smb_resp {
union {
struct esm_smb_resp_val _val;
+ struct esm_smb_resp_thr _thr;
} __packed _;
#define resp_val _._val
+#define resp_thr _._thr
} __packed;
#define ESM2_VS_VALID 0x07