From 1e1058db4908970bac9f288129e5689fc0dbee4e Mon Sep 17 00:00:00 2001 From: Jon Cassorla Date: Thu, 5 Feb 2004 01:10:25 +0000 Subject: [PATCH] add sensor list, get/set threshold commands --- ipmitool/include/ipmitool/ipmi_sdr.h | 3 + ipmitool/include/ipmitool/ipmi_sensor.h | 43 +- ipmitool/lib/ipmi_sdr.c | 52 +- ipmitool/lib/ipmi_sensor.c | 687 +++++++++++++++++++++--- 4 files changed, 710 insertions(+), 75 deletions(-) diff --git a/ipmitool/include/ipmitool/ipmi_sdr.h b/ipmitool/include/ipmitool/ipmi_sdr.h index 00fb49a..dd9e4db 100644 --- a/ipmitool/include/ipmitool/ipmi_sdr.h +++ b/ipmitool/include/ipmitool/ipmi_sdr.h @@ -627,7 +627,10 @@ void ipmi_sdr_end(struct ipmi_intf * intf, struct ipmi_sdr_iterator * i); void ipmi_sdr_print_sdr(struct ipmi_intf * intf, unsigned char type); const char * ipmi_sdr_get_status(unsigned char stat); float sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor, unsigned char val); +unsigned char sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor * sensor, float val); struct ipmi_rs * ipmi_sdr_get_sensor_reading(struct ipmi_intf * intf, unsigned char sensor); +const char * ipmi_sdr_get_sensor_type_desc(const unsigned char type); +struct sdr_record_full_sensor * ipmi_sdr_find_sdr(struct ipmi_intf * intf, char * id); #endif /* IPMI_SDR_H */ diff --git a/ipmitool/include/ipmitool/ipmi_sensor.h b/ipmitool/include/ipmitool/ipmi_sensor.h index fc43357..e9a1027 100644 --- a/ipmitool/include/ipmitool/ipmi_sensor.h +++ b/ipmitool/include/ipmitool/ipmi_sensor.h @@ -41,11 +41,52 @@ #include #include +/* ipmi sensor commands */ #define GET_SENSOR_READING 0x2d #define GET_SENSOR_FACTORS 0x23 -#define GET_SENSOR_THRES 0x27 +#define SET_SENSOR_THRESHOLDS 0x26 +#define GET_SENSOR_THRESHOLDS 0x27 #define GET_SENSOR_TYPE 0x2f +/* threshold specification bits for analog sensors for get sensor threshold command + * and set sensor threshold command + */ +#define UPPER_NON_RECOV_SPECIFIED 0x20 +#define UPPER_CRIT_SPECIFIED 0x10 +#define UPPER_NON_CRIT_SPECIFIED 0x08 +#define LOWER_NON_RECOV_SPECIFIED 0x04 +#define LOWER_CRIT_SPECIFIED 0x02 +#define LOWER_NON_CRIT_SPECIFIED 0x01 + +/* state assertion bits for discrete sensors for get sensor reading command */ +#define STATE_0_ASSERTED 0x01 +#define STATE_1_ASSERTED 0x02 +#define STATE_2_ASSERTED 0x04 +#define STATE_3_ASSERTED 0x08 +#define STATE_4_ASSERTED 0x10 +#define STATE_5_ASSERTED 0x20 +#define STATE_6_ASSERTED 0x40 +#define STATE_7_ASSERTED 0x80 +#define STATE_8_ASSERTED 0x01 +#define STATE_9_ASSERTED 0x02 +#define STATE_10_ASSERTED 0x04 +#define STATE_11_ASSERTED 0x08 +#define STATE_12_ASSERTED 0x10 +#define STATE_13_ASSERTED 0x20 +#define STATE_14_ASSERTED 0x40 + +struct sensor_set_thresh_rq { + unsigned char sensor_num; /* sensor # */ + unsigned char set_mask; /* threshold setting mask */ + unsigned char lower_non_crit; /* new lower non critical threshold*/ + unsigned char lower_crit; /* new lower critical threshold*/ + unsigned char lower_non_recov; /* new lower non recoverable threshold*/ + unsigned char upper_non_crit; /* new upper non critical threshold*/ + unsigned char upper_crit; /* new upper critical threshold*/ + unsigned char upper_non_recov; /* new upper non recoverable threshold*/ +} __attribute__ ((packed)); + + int ipmi_sensor_main(struct ipmi_intf *, int, char **); #endif /* IPMI_SENSOR_H */ diff --git a/ipmitool/lib/ipmi_sdr.c b/ipmitool/lib/ipmi_sdr.c index d4d65fa..bf64727 100644 --- a/ipmitool/lib/ipmi_sdr.c +++ b/ipmitool/lib/ipmi_sdr.c @@ -84,6 +84,29 @@ sdr_convert_sensor_reading(struct sdr_record_full_sensor * sensor, unsigned char } } +unsigned char +sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor * sensor, float val) +{ + int m, b, k1, k2; + double result; + + m = __TO_M(sensor->mtol); + b = __TO_B(sensor->bacc); + k1 = __TO_B_EXP(sensor->bacc); + k2 = __TO_R_EXP(sensor->bacc); + + if (sensor->unit.analog > 2) /* This isn't an analog sensor. */ + return 0; + if (m == 0) /* don't divide by zero */ + return 0; + + result = ((val / pow(10, k2)) - (b * pow(10, k1))) / m; + if ((result -(int)result) >= .5) + return (unsigned char)ceil(result); + else + return (unsigned char)result; +} + #define READING_UNAVAILABLE 0x20 #define SCANNING_DISABLED 0x80 @@ -109,7 +132,7 @@ ipmi_sdr_get_sensor_reading(struct ipmi_intf * intf, unsigned char sensor) return rsp; } -static const char * +const char * ipmi_sdr_get_sensor_type_desc(const unsigned char type) { if (type <= SENSOR_TYPE_MAX) @@ -191,7 +214,7 @@ ipmi_sdr_get_next_header(struct ipmi_intf * intf, struct ipmi_sdr_iterator * itr { struct sdr_get_rs *header; - if (itr->next > itr->total) + if (itr->next == 0xffff) return NULL; if (!(header = ipmi_sdr_get_header(intf, itr->reservation, itr->next))) @@ -932,6 +955,31 @@ ipmi_sdr_end(struct ipmi_intf * intf, struct ipmi_sdr_iterator * itr) free (itr); } +struct sdr_record_full_sensor * +ipmi_sdr_find_sdr(struct ipmi_intf * intf, char * id) +{ + struct sdr_get_rs * header; + struct ipmi_sdr_iterator * itr; + + itr = ipmi_sdr_start(intf); + if (!itr) + { + printf("Unable to open SDR for reading\n"); + return; + } + + while (header = ipmi_sdr_get_next_header(intf, itr)) + { + struct sdr_record_full_sensor * sdr; + if (header->type != SDR_RECORD_TYPE_FULL_SENSOR) + continue; + sdr = (struct sdr_record_full_sensor *)ipmi_sdr_get_record(intf, header, itr); + if (sdr && !strncmp(sdr->id_string, id, sdr->id_code & 0x3f)) + return sdr; + } + return NULL; +} + int ipmi_sdr_main(struct ipmi_intf * intf, int argc, char ** argv) { if (!argc) diff --git a/ipmitool/lib/ipmi_sensor.c b/ipmitool/lib/ipmi_sensor.c index 2fc40b3..3dacf97 100644 --- a/ipmitool/lib/ipmi_sensor.c +++ b/ipmitool/lib/ipmi_sensor.c @@ -44,98 +44,638 @@ extern int verbose; #define READING_UNAVAILABLE 0x20 -#define SCANNING_DISABLED 0x80 -static void -ipmi_get_sensor_info_compact(struct ipmi_intf * intf, - struct sdr_record_compact_sensor * sensor) +static +struct ipmi_rs * +ipmi_sensor_get_sensor_thresholds(struct ipmi_intf * intf, unsigned char sensor) { + struct ipmi_rs * rsp; + struct ipmi_rq req; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_SE; + req.msg.cmd = GET_SENSOR_THRESHOLDS; + req.msg.data = &sensor; + req.msg.data_len = sizeof(sensor); + + rsp = intf->sendrecv(intf, &req); + + return rsp; +} + +static +struct ipmi_rs * +ipmi_sensor_set_sensor_thresholds(struct ipmi_intf * intf, + unsigned char sensor, + unsigned char threshold, + unsigned char setting) +{ + struct ipmi_rs * rsp; + struct ipmi_rq req; + static struct sensor_set_thresh_rq set_thresh_rq; + + memset(&set_thresh_rq, 0, sizeof(set_thresh_rq)); + set_thresh_rq.sensor_num = sensor; + set_thresh_rq.set_mask = threshold; + if (threshold == UPPER_NON_RECOV_SPECIFIED) + set_thresh_rq.upper_non_recov = setting; + else if (threshold == UPPER_CRIT_SPECIFIED) + set_thresh_rq.upper_crit = setting; + else if (threshold == UPPER_NON_CRIT_SPECIFIED) + set_thresh_rq.upper_non_crit = setting; + else if (threshold == LOWER_NON_CRIT_SPECIFIED) + set_thresh_rq.lower_non_crit = setting; + else if (threshold == LOWER_CRIT_SPECIFIED) + set_thresh_rq.lower_crit = setting; + else if (threshold == LOWER_NON_RECOV_SPECIFIED) + set_thresh_rq.lower_non_recov = setting; + else + return NULL; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_SE; + req.msg.cmd = SET_SENSOR_THRESHOLDS; + req.msg.data = (unsigned char *)&set_thresh_rq; + req.msg.data_len = sizeof(set_thresh_rq); + + rsp = intf->sendrecv(intf, &req); + + return rsp; } static void -ipmi_get_sensor_info_full(struct ipmi_intf * intf, - struct sdr_record_full_sensor * sensor) +ipmi_sensor_print_full_discrete(struct ipmi_intf * intf, + struct sdr_record_full_sensor * sensor) { + char id[17]; + char * unitstr = "discrete"; + int i=0, validread=1; + unsigned char val; struct ipmi_rs * rsp; - char sval[16], unitstr[16], desc[17]; - float val, tol; - unsigned raw_tol; - int i=0, not_available=0; + char * status; - memset(desc, 0, sizeof(desc)); - memcpy(desc, sensor->id_string, 16); + if (!sensor) + return; + memset(id, 0, sizeof(id)); + memcpy(id, sensor->id_string, 16); + + /* + * Get current reading + */ rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num); - if ((rsp && (rsp->data[1] & READING_UNAVAILABLE)) || - (rsp && !(rsp->data[1] & SCANNING_DISABLED))) - not_available = 1; - else { - memset(unitstr, 0, sizeof(unitstr)); - /* determine units with possible modifiers */ - switch (sensor->unit.modifier) { - case 2: - i += snprintf(unitstr, sizeof(unitstr), "%s * %s", - unit_desc[sensor->unit.type.base], - unit_desc[sensor->unit.type.modifier]); - break; - case 1: - i += snprintf(unitstr, sizeof(unitstr), "%s/%s", - unit_desc[sensor->unit.type.base], - unit_desc[sensor->unit.type.modifier]); - break; - case 0: - default: - i += snprintf(unitstr, sizeof(unitstr), "%s", - unit_desc[sensor->unit.type.base]); - break; - } - - val = sdr_convert_sensor_reading(sensor, rsp->data[0]); - raw_tol = (sensor->mtol & 0x3f00) >> 8; - tol = sdr_convert_sensor_reading(sensor, raw_tol * 2); + if (!rsp) + { + printf("Error reading sensor %s (#%02x)\n", id, sensor->keys.sensor_num); + return; + } + else if (rsp->ccode || (rsp->data[1] & READING_UNAVAILABLE)) + { + validread = 0; + } + else + { + /* convert RAW reading into units */ + val = rsp->data[0]; } - if (!verbose) { - /* - * print sensor name, reading, state - */ - printf("%-16s | ", sensor->id_code ? desc : NULL); + if (csv_output) + { + } + else + { + if (!verbose) + { + /* output format + * id value units status thresholds.... + */ + printf("%-16s ", id); + if (validread) + { + printf("| 0x%-8x | %-10s | 0x%02x%02x", + val, + unitstr, + rsp->data[2], + rsp->data[3]); + } + else + { + printf("| %-10s | %-10s | %-6s", + "na", + unitstr, + "na"); + } + printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s", + "na", "na", "na", "na", "na", "na"); - i = 0; - memset(sval, 0, sizeof(sval)); - if (not_available) { - i += snprintf(sval, sizeof(sval), "no reading "); - } else { - i += snprintf(sval, sizeof(sval), "%.*f %s", (val==(int)val) ? 0 : 3, val, unitstr); + printf("\n"); } - printf("%s", sval); - - i--; - for (; idata[2])); - printf("\n"); - } else { - printf("Sensor ID : %s (0x%x)\n", desc, sensor->keys.sensor_num); - if (not_available) - printf("Sensor Reading : Unavailable"); else - printf("Sensor Reading : %.*f (+/- %.*f) %s\n", - (val==(int)val) ? 0 : 3, - val, - (tol==(int)tol) ? 0 : 3, - tol, - unitstr); - printf("\n"); + { + printf("Sensor ID : %s (0x%x)\n", + id, sensor->keys.sensor_num); + + printf("Sensor Type (Discrete) : %s\n", + ipmi_sdr_get_sensor_type_desc(sensor->sensor.type)); + + printf("Sensor Reading : "); + if (validread) + { + printf("0x%x\n", val); + } + else + { + printf("not present\n\n"); + return; + } + + printf("States Asserted : "); + if (!rsp->data[2] && !rsp->data[3]) + printf("none"); + else + { + if (rsp->data[2] & STATE_0_ASSERTED) + printf("%d ", 0); + if (rsp->data[2] & STATE_1_ASSERTED) + printf("%d ", 1); + if (rsp->data[2] & STATE_2_ASSERTED) + printf("%d ", 2); + if (rsp->data[2] & STATE_3_ASSERTED) + printf("%d ", 3); + if (rsp->data[2] & STATE_4_ASSERTED) + printf("%d ", 4); + if (rsp->data[2] & STATE_5_ASSERTED) + printf("%d ", 5); + if (rsp->data[2] & STATE_6_ASSERTED) + printf("%d ", 6); + if (rsp->data[2] & STATE_7_ASSERTED) + printf("%d ", 7); + if (rsp->data[3] & STATE_8_ASSERTED) + printf("%d ", 8); + if (rsp->data[3] & STATE_9_ASSERTED) + printf("%d ", 9); + if (rsp->data[3] & STATE_10_ASSERTED) + printf("%d ", 10); + if (rsp->data[3] & STATE_11_ASSERTED) + printf("%d ", 11); + if (rsp->data[3] & STATE_12_ASSERTED) + printf("%d ", 12); + if (rsp->data[3] & STATE_13_ASSERTED) + printf("%d ", 13); + if (rsp->data[3] & STATE_14_ASSERTED) + printf("%d ", 14); + } + + printf("\n\n"); + } + } +} + +static void +ipmi_sensor_print_full_analog(struct ipmi_intf * intf, + struct sdr_record_full_sensor * sensor) +{ + char unitstr[16], id[17]; + int i=0, validread=1, thresh_available = 1; + float val; + struct ipmi_rs * rsp; + char * status; + + if (!sensor) + return; + + /* only handle linear sensors (for now) */ + if (sensor->linearization) { + printf("non-linear!\n"); + return; + } + + memset(id, 0, sizeof(id)); + memcpy(id, sensor->id_string, 16); + + /* + * Get current reading + */ + rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num); + if (!rsp) + { + printf("Error reading sensor %s (#%02x)\n", id, sensor->keys.sensor_num); + return; + } + else if (rsp->ccode || (rsp->data[1] & READING_UNAVAILABLE)) + { + validread = 0; + } + else + { + /* convert RAW reading into units */ + val = rsp->data[0] ? sdr_convert_sensor_reading(sensor, rsp->data[0]) : 0; + status = (char*)ipmi_sdr_get_status(rsp->data[2]); + } + + /* + * Figure out units + */ + memset(unitstr, 0, sizeof(unitstr)); + switch (sensor->unit.modifier) + { + case 2: + i += snprintf(unitstr, sizeof(unitstr), "%s * %s", + unit_desc[sensor->unit.type.base], + unit_desc[sensor->unit.type.modifier]); + break; + case 1: + i += snprintf(unitstr, sizeof(unitstr), "%s/%s", + unit_desc[sensor->unit.type.base], + unit_desc[sensor->unit.type.modifier]); + break; + case 0: + default: + i += snprintf(unitstr, sizeof(unitstr), "%s", + unit_desc[sensor->unit.type.base]); + break; + } + + /* + * Get sensor thresholds + */ + rsp = ipmi_sensor_get_sensor_thresholds(intf, sensor->keys.sensor_num); + if (!rsp) + thresh_available = 0; + + if (csv_output) + { + } + else + { + if (!verbose) + { + /* output format + * id value units status thresholds.... + */ + printf("%-16s ", id); + if (validread) + { + printf("| %-10.3f | %-10s | %-6s", + val, + unitstr, + status); + } + else + { + printf("| %-11s | %-10s | %-6s", + "na", + unitstr, + "na"); + } + if (thresh_available) + { + if (rsp->data[0] & LOWER_NON_RECOV_SPECIFIED) + printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[3])); + else + printf("| %-10s", "na"); + if (rsp->data[0] & LOWER_CRIT_SPECIFIED) + printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[2])); + else + printf("| %-10s", "na"); + if (rsp->data[0] & LOWER_NON_CRIT_SPECIFIED) + printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[1])); + else + printf("| %-10s", "na"); + if (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) + printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[4])); + else + printf("| %-10s", "na"); + if (rsp->data[0] & UPPER_CRIT_SPECIFIED) + printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[5])); + else + printf("| %-10s", "na"); + if (rsp->data[0] & UPPER_NON_RECOV_SPECIFIED) + printf("| %-10.3f", sdr_convert_sensor_reading(sensor, rsp->data[6])); + else + printf("| %-10s", "na"); + } + else + { + printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s", + "na", "na", "na", "na", "na", "na"); + } + + printf("\n"); + } + else + { + printf("Sensor ID : %s (0x%x)\n", + id, sensor->keys.sensor_num); + + printf("Sensor Type (Analog) : %s\n", + ipmi_sdr_get_sensor_type_desc(sensor->sensor.type)); + + printf("Sensor Reading : "); + if (validread) { +#if WORDS_BIGENDIAN + unsigned raw_tol = sensor->mtol & 0x3f; +#else + unsigned raw_tol = (sensor->mtol & 0x3f00) >> 8; +#endif + + float tol = sdr_convert_sensor_reading(sensor, raw_tol * 2); + printf("%.*f (+/- %.*f) %s\n", + (val==(int)val) ? 0 : 3, + val, + (tol==(int)tol) ? 0 : 3, + tol, + unitstr); + printf("Status : %s\n", status); + + if (thresh_available) + { + if (rsp->data[0] & LOWER_NON_RECOV_SPECIFIED) + printf("Lower Non-Recoverable : %.3f\n", + sdr_convert_sensor_reading(sensor, rsp->data[3])); + else + printf("Lower Non-Recoverable : na\n"); + if (rsp->data[0] & LOWER_CRIT_SPECIFIED) + printf("Lower Critical : %.3f\n", + sdr_convert_sensor_reading(sensor, rsp->data[2])); + else + printf("Lower Critical : na\n"); + if (rsp->data[0] & LOWER_NON_CRIT_SPECIFIED) + printf("Lower Non-Critical : %.3f\n", + sdr_convert_sensor_reading(sensor, rsp->data[1])); + else + printf("Lower Non-Critical : na\n"); + if (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) + printf("Upper Non-Critical : %.3f\n", + sdr_convert_sensor_reading(sensor, rsp->data[4])); + else + printf("Upper Non-Critical : na\n"); + if (rsp->data[0] & UPPER_CRIT_SPECIFIED) + printf("Upper Critical : %.3f\n", + sdr_convert_sensor_reading(sensor, rsp->data[5])); + else + printf("Upper Critical : na\n"); + if (rsp->data[0] & UPPER_NON_RECOV_SPECIFIED) + printf("Upper Non-Recoverable : %.3f\n", + sdr_convert_sensor_reading(sensor, rsp->data[6])); + else + printf("Upper Non-Recoverable : na\n"); + } + } else + printf("not present\n"); + printf("\n"); + } + } +} + +static void +ipmi_sensor_print_full(struct ipmi_intf * intf, + struct sdr_record_full_sensor * sensor) +{ + if (sensor->unit.analog != 3) + ipmi_sensor_print_full_analog(intf, sensor); + else + ipmi_sensor_print_full_discrete(intf, sensor); +} + +static void +ipmi_sensor_print_compact(struct ipmi_intf * intf, + struct sdr_record_compact_sensor * sensor) +{ + char id[17]; + char * unitstr = "discrete"; + int i=0, validread=1; + unsigned char val; + struct ipmi_rs * rsp; + char * status; + + if (!sensor) + return; + + memset(id, 0, sizeof(id)); + memcpy(id, sensor->id_string, 16); + + /* + * Get current reading + */ + rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num); + if (!rsp) + { + printf("Error reading sensor %s (#%02x)\n", id, sensor->keys.sensor_num); + return; + } + else if (rsp->ccode || (rsp->data[1] & READING_UNAVAILABLE)) + { + validread = 0; + } + else + { + /* convert RAW reading into units */ + val = rsp->data[0]; + } + + if (csv_output) + { + } + else + { + if (!verbose) + { + /* output format + * id value units status thresholds.... + */ + printf("%-16s ", id); + if (validread) + { + printf("| 0x%-8x | %-10s | 0x%02x%02x", + val, + unitstr, + rsp->data[2], + rsp->data[3]); + } + else + { + printf("| %-10s | %-10s | %-6s", + "na", + unitstr, + "na"); + } + printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s", + "na", "na", "na", "na", "na", "na"); + + printf("\n"); + } + else + { + printf("Sensor ID : %s (0x%x)\n", + id, sensor->keys.sensor_num); + + printf("Sensor Type (Discrete) : %s\n", + ipmi_sdr_get_sensor_type_desc(sensor->sensor.type)); + + printf("Sensor Reading : "); + if (validread) + { + printf("0x%04x\n", val); + } + else + { + printf("not present\n\n"); + return; + } + + printf("States Asserted : "); + if (!rsp->data[2] && !rsp->data[3]) + printf("none"); + else + { + if (rsp->data[2] & STATE_0_ASSERTED) + printf("%d ", 0); + if (rsp->data[2] & STATE_1_ASSERTED) + printf("%d ", 1); + if (rsp->data[2] & STATE_2_ASSERTED) + printf("%d ", 2); + if (rsp->data[2] & STATE_3_ASSERTED) + printf("%d ", 3); + if (rsp->data[2] & STATE_4_ASSERTED) + printf("%d ", 4); + if (rsp->data[2] & STATE_5_ASSERTED) + printf("%d ", 5); + if (rsp->data[2] & STATE_6_ASSERTED) + printf("%d ", 6); + if (rsp->data[2] & STATE_7_ASSERTED) + printf("%d ", 7); + if (rsp->data[3] & STATE_8_ASSERTED) + printf("%d ", 8); + if (rsp->data[3] & STATE_9_ASSERTED) + printf("%d ", 9); + if (rsp->data[3] & STATE_10_ASSERTED) + printf("%d ", 10); + if (rsp->data[3] & STATE_11_ASSERTED) + printf("%d ", 11); + if (rsp->data[3] & STATE_12_ASSERTED) + printf("%d ", 12); + if (rsp->data[3] & STATE_13_ASSERTED) + printf("%d ", 13); + if (rsp->data[3] & STATE_14_ASSERTED) + printf("%d ", 14); + } + + printf("\n\n"); + } } } static void ipmi_sensor_list(struct ipmi_intf * intf) { - ipmi_sdr_print_sdr(intf, 0xff); + struct sdr_get_rs * header; + struct ipmi_sdr_iterator * itr; + + if (verbose > 1) + printf("Querying SDR for sensor list\n"); + + itr = ipmi_sdr_start(intf); + if (!itr) + { + printf("Unable to open SDRR for reading\n"); + return; + } + + while (header = ipmi_sdr_get_next_header(intf, itr)) + { + unsigned char * rec = ipmi_sdr_get_record(intf, header, itr); + if (!rec) + continue; + + switch(header->type) + { + case SDR_RECORD_TYPE_FULL_SENSOR: + ipmi_sensor_print_full(intf, (struct sdr_record_full_sensor *) rec); + break; + case SDR_RECORD_TYPE_COMPACT_SENSOR: + ipmi_sensor_print_compact(intf, (struct sdr_record_compact_sensor *) rec); + break; + default: + continue; + break; + } + } +} + +static void +ipmi_sensor_set_threshold(struct ipmi_intf * intf, int argc, char ** argv) +{ + char * id, + * thresh; + unsigned char settingMask; + float setting; + struct sdr_record_full_sensor * sdr; + struct ipmi_rs * rsp; + + if (argc < 3 || !strncmp(argv[0], "help", 4)) + { + printf("sensor thresh \n"); + printf(" id : name of the sensor for which threshold is to be set\n"); + printf(" threshold : which threshold to set\n"); + printf(" unr = upper non-recoverable\n"); + printf(" ucr = upper critical\n"); + printf(" unc = upper non-critical\n"); + printf(" lnc = lower non-critical\n"); + printf(" lcr = lower critical\n"); + printf(" lnr = lower non-recoverable\n"); + printf(" setting : the value to set the threshold to\n"); + return; + } + + id = argv[0]; + thresh = argv[1]; + setting = (float)atof(argv[2]); + if (!strcmp(thresh, "unr")) + { + settingMask = UPPER_NON_RECOV_SPECIFIED; + } + else if (!strcmp(thresh, "ucr")) + { + settingMask = UPPER_CRIT_SPECIFIED; + } + else if (!strcmp(thresh, "unc")) + { + settingMask = UPPER_NON_CRIT_SPECIFIED; + } + else if (!strcmp(thresh, "lnc")) + { + settingMask = LOWER_NON_CRIT_SPECIFIED; + } + else if (!strcmp(thresh, "lcr")) + { + settingMask = LOWER_CRIT_SPECIFIED; + } + else if (!strcmp(thresh, "lnr")) + { + settingMask = LOWER_NON_RECOV_SPECIFIED; + } + else + { + printf("Valid threshold not specified!\n"); + return; + } + + sdr = ipmi_sdr_find_sdr(intf, id); + if (sdr) + { + rsp = ipmi_sensor_set_sensor_thresholds(intf, + sdr->keys.sensor_num, + settingMask, + sdr_convert_sensor_value_to_raw(sdr, setting)); + if (rsp && rsp->ccode) + printf("Error setting threshold: 0x%x\n", rsp->ccode); + } + else + { + printf("Sensor data record not found!\n"); + return; + } } int @@ -144,11 +684,14 @@ ipmi_sensor_main(struct ipmi_intf * intf, int argc, char ** argv) if (!argc) ipmi_sensor_list(intf); else if (!strncmp(argv[0], "help", 4)) { - printf("Sensor Commands: list\n"); + printf("Sensor Commands: list thresh\n"); } else if (!strncmp(argv[0], "list", 4)) { ipmi_sensor_list(intf); } + else if (!strncmp(argv[0], "thresh", 5)) { + ipmi_sensor_set_threshold(intf, argc-1, &argv[1]); + } else printf("Invalid sensor command: %s\n", argv[0]); return 0;