diff --git a/ipmitool/include/ipmitool/ipmi_sdr.h b/ipmitool/include/ipmitool/ipmi_sdr.h index c24c229..8b49914 100644 --- a/ipmitool/include/ipmitool/ipmi_sdr.h +++ b/ipmitool/include/ipmitool/ipmi_sdr.h @@ -381,6 +381,20 @@ struct sdr_record_full_sensor { } type; } unit; +#define SDR_SENSOR_L_LINEAR 0x00 +#define SDR_SENSOR_L_LN 0x01 +#define SDR_SENSOR_L_LOG10 0x02 +#define SDR_SENSOR_L_LOG2 0x03 +#define SDR_SENSOR_L_E 0x04 +#define SDR_SENSOR_L_EXP10 0x05 +#define SDR_SENSOR_L_EXP2 0x06 +#define SDR_SENSOR_L_1_X 0x07 +#define SDR_SENSOR_L_SQR 0x08 +#define SDR_SENSOR_L_CUBE 0x09 +#define SDR_SENSOR_L_SQRT 0x0a +#define SDR_SENSOR_L_CUBERT 0x0b +#define SDR_SENSOR_L_NONLINEAR 0x70 + uint8_t linearization; /* 70h=non linear, 71h-7Fh=non linear, OEM */ uint16_t mtol; /* M, tolerance */ uint32_t bacc; /* accuracy, B, Bexp, Rexp */ diff --git a/ipmitool/lib/ipmi_sdr.c b/ipmitool/lib/ipmi_sdr.c index 18bfff8..e5c7660 100644 --- a/ipmitool/lib/ipmi_sdr.c +++ b/ipmitool/lib/ipmi_sdr.c @@ -56,7 +56,8 @@ #endif #define READING_UNAVAILABLE 0x20 -#define SCANNING_DISABLED 0x80 +#define SCANNING_DISABLED 0x40 +#define EVENTS_DISABLED 0x80 #define GET_SENSOR_READING 0x2d #define GET_SENSOR_FACTORS 0x23 @@ -100,6 +101,7 @@ sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor, uint8_t val) { int m, b, k1, k2; + float result; m = __TO_M(sensor->mtol); b = __TO_B(sensor->bacc); @@ -109,18 +111,61 @@ sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor, switch (sensor->unit.analog) { case 0: - return (float)(((m * val) + + result = (float)(((m * val) + (b * pow(10, k1))) * pow(10, k2)); + break; case 1: if (val & 0x80) val ++; /* Deliberately fall through to case 2. */ case 2: - return (float)(((m * (int8_t)val) + + result = (float)(((m * (int8_t)val) + (b * pow(10, k1))) * pow(10, k2)); + break; default: /* Oops! This isn't an analog sensor. */ return 0.0; } + + switch (sensor->linearization & 0x7f) { + default: + case SDR_SENSOR_L_LINEAR: + break; + case SDR_SENSOR_L_LN: + result = log(result); + break; + case SDR_SENSOR_L_LOG10: + result = log10(result); + break; + case SDR_SENSOR_L_LOG2: + result = log2(result); + break; + case SDR_SENSOR_L_E: + result = exp(result); + break; + case SDR_SENSOR_L_EXP10: + result = exp10(result); + break; + case SDR_SENSOR_L_EXP2: + result = exp2(result); + break; + case SDR_SENSOR_L_1_X: + result = pow(result, -1.0); /*1/x w/o exception*/ + break; + case SDR_SENSOR_L_SQR: + result = result * result; + break; + case SDR_SENSOR_L_CUBE: + result = pow(result, 3.0); + break; + case SDR_SENSOR_L_SQRT: + result = sqrt(result); + break; + case SDR_SENSOR_L_CUBERT: + result = cbrt(result); + break; + } + + return result; } /* sdr_convert_sensor_value_to_raw - convert sensor reading back to raw @@ -371,16 +416,15 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf * intf, if (sensor == NULL) return -1; - /* only handles linear sensors (for now) */ - if (sensor->linearization) { - lprintf(LOG_ERR, "Sensor #%02x is non-linear", - sensor->keys.sensor_num); - return -1; - } - memset(desc, 0, sizeof(desc)); memcpy(desc, sensor->id_string, 16); + /* only handle linear sensors and linearized sensors (for now) */ + if (sensor->linearization>=SDR_SENSOR_L_NONLINEAR) { + printf("sensor %s non-linear!\n", desc); + return; + } + /* get sensor reading */ rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num); @@ -407,7 +451,7 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf * intf, else if (!(rsp->data[1] & SCANNING_DISABLED)) { /* Sensor Scanning Disabled * not an error condition so return 0 */ - return 0; + validread = 0; } else if (rsp->data[0] != 0) { /* convert RAW reading into units */ @@ -509,9 +553,10 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf * intf, i += snprintf(sval, sizeof(sval), "%.*f %s", (val==(int)val) ? 0 : 2, val, do_unit ? unitstr : ""); + else if (!(rsp->data[1] & SCANNING_DISABLED)) + i += snprintf(sval, sizeof(sval), "disabled "); else - i += snprintf(sval, sizeof(sval), - "no reading "); + i += snprintf(sval, sizeof(sval), "no reading "); printf("%s", sval); @@ -568,7 +613,9 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf * intf, (tol==(int)tol) ? 0 : 3, tol, unitstr); - } else + } else if (!(rsp->data[1] & SCANNING_DISABLED)) + printf("Disabled\n"); + else printf("Not Present\n"); printf(" Status : %s\n", diff --git a/ipmitool/lib/ipmi_sensor.c b/ipmitool/lib/ipmi_sensor.c index b17afb5..1a85475 100644 --- a/ipmitool/lib/ipmi_sensor.c +++ b/ipmitool/lib/ipmi_sensor.c @@ -189,16 +189,15 @@ ipmi_sensor_print_full_analog(struct ipmi_intf * intf, if (sensor == NULL) return -1; - /* only handle linear sensors (for now) */ - if (sensor->linearization) { - lprintf(LOG_ERR, "Sensor #%02x is non-linear", - sensor->keys.sensor_num); - return -1; - } - memset(id, 0, sizeof(id)); memcpy(id, sensor->id_string, 16); + /* only handle linear and linearized sensors (for now) */ + if (sensor->linearization>=SDR_SENSOR_L_NONLINEAR) { + printf("sensor %s non-linear!\n", id); + return; + } + /* * Get current reading */