Hi! On a machine the system temperature sensor shows e.g. 33 which is ok. But on sysctl hw.sensors the status is CRITICAL. I've read the IPMI specs and i think this is because ipmi_test_threshold ignores the fact, that some sensors have a signed value and threshold. In my case the lower thresholds are all negative. The following diff for sys/dev/ipmi.c should fix this problem. It checks the SDR if the sensor returns signed values and passes the result to ipmi_test_threshold() which then does the threshold check regarding the sign.
-- Matthias
--- ipmi.c 10 Apr 2013 01:35:55 -0000 1.68 +++ ipmi.c 19 Jun 2013 09:27:51 -0000 @@ -186,7 +186,7 @@ void ipmi_unmap_regs(struct ipmi_softc * void *scan_sig(long, long, int, int, const void *); -int ipmi_test_threshold(u_int8_t, u_int8_t, u_int8_t, u_int8_t); +int ipmi_test_threshold(u_int8_t, u_int8_t, u_int8_t, u_int8_t, int); int ipmi_sensor_status(struct ipmi_softc *, struct ipmi_sensor *, u_int8_t *); @@ -1287,9 +1287,14 @@ ipmi_convert(u_int8_t v, struct sdrtype1 } int -ipmi_test_threshold(u_int8_t v, u_int8_t valid, u_int8_t hi, u_int8_t lo) +ipmi_test_threshold(u_int8_t v, u_int8_t valid, u_int8_t hi, u_int8_t lo, + int sign) { - dbg_printf(10, "thresh: %.2x %.2x %.2x %d\n", v, lo, hi,valid); + dbg_printf(10, "thresh: %.2x %.2x %.2x %d %d\n", v, lo, hi,valid, sign); + if (sign) + return ((valid & 1 && lo != 0x00 && (int8_t)v <= (int8_t)lo) || + (valid & 8 && hi != 0xFF && (int8_t)v >= (int8_t)hi)); + return ((valid & 1 && lo != 0x00 && v <= lo) || (valid & 8 && hi != 0xFF && v >= hi)); } @@ -1301,6 +1306,7 @@ ipmi_sensor_status(struct ipmi_softc *sc u_int8_t data[32]; struct sdrtype1 *s1 = (struct sdrtype1 *)psensor->i_sdr; int rxlen, etype; + int sign = s1->units1 >> 7 & 1; /* Get reading of sensor */ switch (psensor->i_sensor.type) { @@ -1339,15 +1345,15 @@ ipmi_sensor_status(struct ipmi_softc *sc data[6]); if (ipmi_test_threshold(*reading, data[0] >> 2 , - data[6], data[3])) + data[6], data[3], sign)) return (SENSOR_S_CRIT); if (ipmi_test_threshold(*reading, data[0] >> 1, - data[5], data[2])) + data[5], data[2], sign)) return (SENSOR_S_CRIT); if (ipmi_test_threshold(*reading, data[0] , - data[4], data[1])) + data[4], data[1], sign)) return (SENSOR_S_WARN); break;