From 5f11bb25b0f5a6cbdd7cdf85f76b9bfd37ac2eeb Mon Sep 17 00:00:00 2001 From: Jim Mankovich Date: Tue, 1 May 2012 16:59:23 +0000 Subject: [PATCH] Correct Threshold/Discrete Sensor Display - Patch Tracker ID - 3508759 --- ipmitool/include/ipmitool/ipmi_sdr.h | 115 +-- ipmitool/include/ipmitool/ipmi_sensor.h | 3 +- ipmitool/lib/ipmi_dcmi.c | 11 +- ipmitool/lib/ipmi_delloem.c | 18 +- ipmitool/lib/ipmi_event.c | 22 +- ipmitool/lib/ipmi_sdr.c | 967 ++++++++++++------------ ipmitool/lib/ipmi_sel.c | 35 +- ipmitool/lib/ipmi_sensor.c | 548 ++++++-------- ipmitool/src/ipmievd.c | 8 +- ipmitool/src/plugins/lanplus/lanplus.c | 19 +- 10 files changed, 807 insertions(+), 939 deletions(-) diff --git a/ipmitool/include/ipmitool/ipmi_sdr.h b/ipmitool/include/ipmitool/ipmi_sdr.h index d51a9bb..5db1e75 100644 --- a/ipmitool/include/ipmitool/ipmi_sdr.h +++ b/ipmitool/include/ipmitool/ipmi_sdr.h @@ -322,7 +322,7 @@ struct sdr_record_mask { #ifdef HAVE_PRAGMA_PACK #pragma pack(1) #endif -struct sdr_record_compact_sensor { +struct sdr_record_common_sensor { struct { uint8_t owner_id; #if WORDS_BIGENDIAN @@ -376,7 +376,7 @@ struct sdr_record_compact_sensor { uint8_t ignore:1; #endif } ATTRIBUTE_PACKING capabilities; - uint8_t type; /* sensor type */ + uint8_t type; } ATTRIBUTE_PACKING sensor; uint8_t event_type; /* event/reading type code */ @@ -400,7 +400,21 @@ struct sdr_record_compact_sensor { uint8_t modifier; } ATTRIBUTE_PACKING type; } ATTRIBUTE_PACKING unit; +} ATTRIBUTE_PACKING; +/* SDR Record Common Sensor header macros */ +#define IS_THRESHOLD_SENSOR(s) ((s)->event_type == 1) +#define UNITS_ARE_DISCRETE(s) ((s)->unit.analog == 3) + +#ifdef HAVE_PRAGMA_PACK +#pragma pack(0) +#endif + +#ifdef HAVE_PRAGMA_PACK +#pragma pack(1) +#endif +struct sdr_record_compact_sensor { + struct sdr_record_common_sensor cmn; struct { #if WORDS_BIGENDIAN uint8_t __reserved:2; @@ -492,83 +506,7 @@ struct sdr_record_eventonly_sensor { #pragma pack(1) #endif struct sdr_record_full_sensor { - struct { - uint8_t owner_id; -#if WORDS_BIGENDIAN - uint8_t channel:4; /* channel number */ - uint8_t __reserved:2; - uint8_t lun:2; /* sensor owner lun */ -#else - uint8_t lun:2; /* sensor owner lun */ - uint8_t __reserved:2; - uint8_t channel:4; /* channel number */ -#endif - uint8_t sensor_num; /* unique sensor number */ - } ATTRIBUTE_PACKING keys; - - struct entity_id entity; - - struct { - struct { -#if WORDS_BIGENDIAN - uint8_t __reserved:1; - uint8_t scanning:1; - uint8_t events:1; - uint8_t thresholds:1; - uint8_t hysteresis:1; - uint8_t type:1; - uint8_t event_gen:1; - uint8_t sensor_scan:1; -#else - uint8_t sensor_scan:1; - uint8_t event_gen:1; - uint8_t type:1; - uint8_t hysteresis:1; - uint8_t thresholds:1; - uint8_t events:1; - uint8_t scanning:1; - uint8_t __reserved:1; -#endif - } ATTRIBUTE_PACKING init; - struct { -#if WORDS_BIGENDIAN - uint8_t ignore:1; - uint8_t rearm:1; - uint8_t hysteresis:2; - uint8_t threshold:2; - uint8_t event_msg:2; -#else - uint8_t event_msg:2; - uint8_t threshold:2; - uint8_t hysteresis:2; - uint8_t rearm:1; - uint8_t ignore:1; -#endif - } ATTRIBUTE_PACKING capabilities; - uint8_t type; - } ATTRIBUTE_PACKING sensor; - - uint8_t event_type; /* event/reading type code */ - - struct sdr_record_mask mask; - - struct { -#if WORDS_BIGENDIAN - uint8_t analog:2; - uint8_t rate:3; - uint8_t modifier:2; - uint8_t pct:1; -#else - uint8_t pct:1; - uint8_t modifier:2; - uint8_t rate:3; - uint8_t analog:2; -#endif - struct { - uint8_t base; - uint8_t modifier; - } ATTRIBUTE_PACKING type; - } ATTRIBUTE_PACKING unit; + struct sdr_record_common_sensor cmn; #define SDR_SENSOR_L_LINEAR 0x00 #define SDR_SENSOR_L_LN 0x01 @@ -822,6 +760,7 @@ struct sdr_record_list { uint8_t *raw; struct sdr_record_list *next; union { + struct sdr_record_common_sensor *common; struct sdr_record_full_sensor *full; struct sdr_record_compact_sensor *compact; struct sdr_record_eventonly_sensor *eventonly; @@ -896,14 +835,22 @@ int ipmi_sdr_print_rawentry(struct ipmi_intf *intf, uint8_t type, uint8_t * raw, int len); int ipmi_sdr_print_listentry(struct ipmi_intf *intf, struct sdr_record_list *entry); -const char *ipmi_sdr_get_unit_string(uint8_t pct, uint8_t type, +void ipmi_sdr_print_sensor_hysteresis(struct sdr_record_common_sensor *sensor, + struct sdr_record_full_sensor *full, + uint8_t hysteresis_value, + const char *hdrstr); +const char *ipmi_sdr_get_unit_string(uint8_t pct, uint8_t type, uint8_t base, uint8_t modifier); -const char *ipmi_sdr_get_status(struct sdr_record_full_sensor *sensor, - uint8_t stat); +const char *ipmi_sdr_get_thresh_status(struct ipmi_rs *rsp, + int validread, const char *invalidstr); +const char *ipmi_sdr_get_status(int, const char *, uint8_t stat); double sdr_convert_sensor_tolerance(struct sdr_record_full_sensor *sensor, uint8_t val); double sdr_convert_sensor_reading(struct sdr_record_full_sensor *sensor, uint8_t val); +double sdr_convert_analog_reading(struct ipmi_intf *intf, + struct sdr_record_full_sensor *sensor, uint8_t read, + int *convert_success); double sdr_convert_sensor_hysterisis(struct sdr_record_full_sensor *sensor, uint8_t val); uint8_t sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor *sensor, @@ -925,10 +872,6 @@ const char *ipmi_sdr_get_sensor_type_desc(const uint8_t type); int ipmi_sdr_get_reservation(struct ipmi_intf *intf, int use_builtin, uint16_t * reserve_id); -int ipmi_sdr_print_sensor_full(struct ipmi_intf *intf, - struct sdr_record_full_sensor *sensor); -int ipmi_sdr_print_sensor_compact(struct ipmi_intf *intf, - struct sdr_record_compact_sensor *sensor); int ipmi_sdr_print_sensor_eventonly(struct ipmi_intf *intf, struct sdr_record_eventonly_sensor *sensor); int ipmi_sdr_print_sensor_generic_locator(struct ipmi_intf *intf, diff --git a/ipmitool/include/ipmitool/ipmi_sensor.h b/ipmitool/include/ipmitool/ipmi_sensor.h index 78f1c6e..63fc4aa 100644 --- a/ipmitool/include/ipmitool/ipmi_sensor.h +++ b/ipmitool/include/ipmitool/ipmi_sensor.h @@ -84,7 +84,6 @@ struct sensor_set_thresh_rq { int ipmi_sensor_main(struct ipmi_intf *, int, char **); -int ipmi_sensor_print_full(struct ipmi_intf *, struct sdr_record_full_sensor *); -int ipmi_sensor_print_compact(struct ipmi_intf *, struct sdr_record_compact_sensor *); +int ipmi_sensor_print_fc(struct ipmi_intf *, struct sdr_record_common_sensor *, uint8_t); int ipmi_sensor_get_sensor_reading_factors( struct ipmi_intf * intf, struct sdr_record_full_sensor * sensor, uint8_t reading); #endif /* IPMI_SENSOR_H */ diff --git a/ipmitool/lib/ipmi_dcmi.c b/ipmitool/lib/ipmi_dcmi.c index a735709..f33ba5a 100755 --- a/ipmitool/lib/ipmi_dcmi.c +++ b/ipmitool/lib/ipmi_dcmi.c @@ -1997,14 +1997,13 @@ static int ipmi_print_sensor_info(struct ipmi_intf *intf, uint16_t rec_id) rc = -1; } - if(header->type == SDR_RECORD_TYPE_FULL_SENSOR) { - r = ipmi_sensor_print_full(intf, (struct sdr_record_full_sensor *)rec); - } - else if(header->type == SDR_RECORD_TYPE_COMPACT_SENSOR) { - r = ipmi_sensor_print_compact(intf, (struct sdr_record_compact_sensor *)rec); + if((header->type == SDR_RECORD_TYPE_FULL_SENSOR) || + (header->type == SDR_RECORD_TYPE_COMPACT_SENSOR)) { + r = ipmi_sensor_print_fc(intf, + (struct sdr_record_common_sensor *)rec, header->type); } else - rc = -1; + rc = -1; } else { rc = -1; /* record id not found */ diff --git a/ipmitool/lib/ipmi_delloem.c b/ipmitool/lib/ipmi_delloem.c index 430e2cb..b17a1ac 100644 --- a/ipmitool/lib/ipmi_delloem.c +++ b/ipmitool/lib/ipmi_delloem.c @@ -3579,20 +3579,20 @@ static int ipmi_get_power_consumption_data(struct ipmi_intf* intf,uint8_t unit) if (NULL ==sdr) { printf ("Error : Can not access the System Level sensor data \n\n"); - return -1; - } + return -1; + } - sensor_number = sdr->record.full->keys.sensor_num; - ipmi_get_sensor_reading (intf,sensor_number,&sensorReadingData); + sensor_number = sdr->record.common->keys.sensor_num; + ipmi_get_sensor_reading (intf,sensor_number,&sensorReadingData); rsp = ipmi_sdr_get_sensor_thresholds(intf, - sdr->record.full->keys.sensor_num, - sdr->record.full->keys.owner_id, - sdr->record.full->keys.lun, - sdr->record.full->keys.channel); + sdr->record.common->keys.sensor_num, + sdr->record.common->keys.owner_id, + sdr->record.common->keys.lun, + sdr->record.common->keys.channel); if (rsp != NULL && rsp->ccode == 0) - { + { readingbtuphr=sdr_convert_sensor_reading (sdr->record.full, sensorReadingData.sensorReading); warning_threshbtuphr=sdr_convert_sensor_reading diff --git a/ipmitool/lib/ipmi_event.c b/ipmitool/lib/ipmi_event.c index ebc8e34..6580975 100644 --- a/ipmitool/lib/ipmi_event.c +++ b/ipmitool/lib/ipmi_event.c @@ -273,25 +273,15 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e switch (sdr->type) { case SDR_RECORD_TYPE_FULL_SENSOR: - - emsg.sensor_type = sdr->record.full->sensor.type; - emsg.sensor_num = sdr->record.full->keys.sensor_num; - emsg.event_type = sdr->record.full->event_type; - target = sdr->record.full->keys.owner_id; - lun = sdr->record.full->keys.lun; - channel = sdr->record.full->keys.channel; - break; - case SDR_RECORD_TYPE_COMPACT_SENSOR: - emsg.sensor_type = sdr->record.compact->sensor.type; - emsg.sensor_num = sdr->record.compact->keys.sensor_num; - emsg.event_type = sdr->record.compact->event_type; - target = sdr->record.compact->keys.owner_id; - lun = sdr->record.compact->keys.lun; - channel = sdr->record.compact->keys.channel; + emsg.sensor_type = sdr->record.common->sensor.type; + emsg.sensor_num = sdr->record.common->keys.sensor_num; + emsg.event_type = sdr->record.common->event_type; + target = sdr->record.common->keys.owner_id; + lun = sdr->record.common->keys.lun; + channel = sdr->record.common->keys.channel; break; - default: lprintf(LOG_ERR, "Unknown sensor type for id '%s'", id); return -1; diff --git a/ipmitool/lib/ipmi_sdr.c b/ipmitool/lib/ipmi_sdr.c index 86ab1d0..14951d8 100644 --- a/ipmitool/lib/ipmi_sdr.c +++ b/ipmitool/lib/ipmi_sdr.c @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include #include #include @@ -107,6 +109,47 @@ ipmi_sdr_get_unit_string(uint8_t pct, uint8_t type, uint8_t base, uint8_t modifi return unitstr; } + +/* sdr_convert_analog_reading - convert raw sensor reading to analog + * + * @sensor: sensor record + * @raed: raw sensor reading + * @convert_success: raw sensor reading + * + * + * returns floating-point sensor reading and conversion status + */ +double +sdr_convert_analog_reading(struct ipmi_intf *intf, + struct sdr_record_full_sensor *full, uint8_t read, + int *convert_success) +{ + /* Compact sensors can't return analog values so we return zero */ + if (!full) { + return 0.0; + } + /* + * Only Full Threshold sensors with analog readings can be converted. + * If this not the case, we return zero + */ + if ( !(IS_THRESHOLD_SENSOR(&full->cmn) && + !UNITS_ARE_DISCRETE(&full->cmn)) ) { + return 0.0; + } + /* + * If sensor has linearization, then we should be able to update the + * reading factors and if we cannot fail the conversion. + */ + if (full->linearization >= SDR_SENSOR_L_NONLINEAR && + full->linearization <= 0x7F) { + if (ipmi_sensor_get_sensor_reading_factors(intf, full, read) < 0){ + *convert_success = 0; + } + } + + return sdr_convert_sensor_reading(full, read); +} + /* sdr_convert_sensor_reading - convert raw sensor reading * * @sensor: sensor record @@ -125,7 +168,7 @@ sdr_convert_sensor_reading(struct sdr_record_full_sensor *sensor, uint8_t val) k1 = __TO_B_EXP(sensor->bacc); k2 = __TO_R_EXP(sensor->bacc); - switch (sensor->unit.analog) { + switch (sensor->cmn.unit.analog) { case 0: result = (double) (((m * val) + (b * pow(10, k1))) * pow(10, k2)); @@ -199,15 +242,14 @@ sdr_convert_sensor_reading(struct sdr_record_full_sensor *sensor, uint8_t val) double sdr_convert_sensor_hysterisis(struct sdr_record_full_sensor *sensor, uint8_t val) { - int m, k1, k2; + int m, k2; double result; m = __TO_M(sensor->mtol); - k1 = __TO_B_EXP(sensor->bacc); k2 = __TO_R_EXP(sensor->bacc); - switch (sensor->unit.analog) { + switch (sensor->cmn.unit.analog) { case 0: result = (double) (((m * val)) * pow(10, k2)); break; @@ -281,7 +323,7 @@ sdr_convert_sensor_tolerance(struct sdr_record_full_sensor *sensor, uint8_t val) m = __TO_M(sensor->mtol); k2 = __TO_R_EXP(sensor->bacc); - switch (sensor->unit.analog) { + switch (sensor->cmn.unit.analog) { case 0: /* as suggested in section 30.4.1 of IPMI 1.5 spec */ result = (double) ((((m * (double)val/2)) ) * pow(10, k2)); @@ -353,15 +395,15 @@ sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor * sensor, int m, b, k1, k2; double result; + /* only works for analog sensors */ + if (UNITS_ARE_DISCRETE((&sensor->cmn))) + return 0; + m = __TO_M(sensor->mtol); b = __TO_B(sensor->bacc); k1 = __TO_B_EXP(sensor->bacc); k2 = __TO_R_EXP(sensor->bacc); - /* only works for analog sensors */ - if (sensor->unit.analog > 2) - return 0; - /* don't divide by zero */ if (m == 0) return 0; @@ -490,9 +532,17 @@ ipmi_sdr_get_sensor_reading_ipmb(struct ipmi_intf *intf, uint8_t sensor, uint8_t save_addr; uint8_t save_channel; - if ((strncmp(intf->name, "ipmb", 4)) != 0) +#if 0 + /* Enabling this code will cause sensors with an SDR Owner ID + * not equal to IPMI_BMC_SLAVE_ADDR to be not readable when + * running over the lanplus interface. The + * ipmi_sdr_get_sensor_reading function does not update the interface + * target address or channel, so the failure makes sense. I believe + * the following code and function being called should be removed. + */ + if ((strncmp(intf->name, "ipmb", 4)) != 0) return ipmi_sdr_get_sensor_reading(intf, sensor); - +#endif save_addr = intf->target_addr; intf->target_addr = target; save_channel = intf->target_channel; @@ -608,20 +658,27 @@ ipmi_sdr_get_sensor_type_desc(const uint8_t type) return desc; } -/* ipmi_sdr_get_status - Return 2-character status indicator +/* ipmi_sdr_get_thresh_status - threshold status indicator * - * @stat: ipmi SDR status field + * @rsp: response from Get Sensor Reading comand + * @validread: validity of the status field argument + * @invalidstr: string to return if status field is not valid * * returns * cr = critical * nc = non-critical * nr = non-recoverable * ok = ok - * us = unspecified (not used) + * ns = not specified */ const char * -ipmi_sdr_get_status(struct sdr_record_full_sensor *sensor, uint8_t stat) +ipmi_sdr_get_thresh_status(struct ipmi_rs *rsp, int validread, const char *invalidstr) { + uint8_t stat; + if (!validread) { + return invalidstr; + } + stat = rsp->data[2]; if (stat & SDR_SENSOR_STAT_LO_NR) { if (verbose) return "Lower Non-Recoverable"; @@ -794,30 +851,48 @@ ipmi_sdr_get_next_header(struct ipmi_intf *intf, struct ipmi_sdr_iterator *itr) return header; } -/* helper macro for printing CSV output */ -#define SENSOR_PRINT_CSV(FLAG, READ) \ - if (FLAG) \ - printf("%.3f,", \ - sdr_convert_sensor_reading( \ - sensor, READ)); \ - else \ - printf(","); - -/* helper macro for priting analog values */ -#define SENSOR_PRINT_NORMAL(NAME, READ) \ - if (sensor->analog_flag.READ != 0) { \ - printf(" %-21s : ", NAME); \ - printf("%.3f\n", sdr_convert_sensor_reading( \ - sensor, sensor->READ)); \ +/* + * This macro is used to print nominal, normal and threshold settings, + * but it is not compatible with PRINT_NORMAL/PRINT_THRESH since it does + * not have the sensor.init.thresholds setting qualifier as is done in + * PRINT_THRESH. This means CSV output can be different than non CSV + * output if sensor.init.thresholds is ever zero + */ +/* helper macro for printing CSV output for Full SDR Threshold reading */ +#define SENSOR_PRINT_CSV(FULLSENS, FLAG, READ) \ + if ((FLAG)) { \ + if (UNITS_ARE_DISCRETE((&FULLSENS->cmn))) \ + printf("0x%02X,", READ); \ + else \ + printf("%.3f,", sdr_convert_sensor_reading( \ + (FULLSENS), READ)); \ + } else { \ + printf(","); \ } -/* helper macro for printing sensor thresholds */ -#define SENSOR_PRINT_THRESH(NAME, READ, FLAG) \ - if (sensor->sensor.init.thresholds && \ - sensor->mask.type.threshold.read.FLAG != 0) { \ - printf(" %-21s : ", NAME); \ - printf("%.3f\n", sdr_convert_sensor_reading( \ - sensor, sensor->threshold.READ)); \ +/* helper macro for printing analog values for Full SDR Threshold readings */ +#define SENSOR_PRINT_NORMAL(FULLSENS, NAME, READ) \ + if ((FULLSENS)->analog_flag.READ != 0) { \ + printf(" %-21s : ", NAME); \ + if (UNITS_ARE_DISCRETE((&FULLSENS->cmn))) \ + printf("0x%02X\n", \ + (FULLSENS)->READ); \ + else \ + printf("%.3f\n", sdr_convert_sensor_reading( \ + (FULLSENS), (FULLSENS)->READ));\ + } + +/* helper macro for printing Full SDR sensor Thresholds */ +#define SENSOR_PRINT_THRESH(FULLSENS, NAME, READ, FLAG) \ + if ((FULLSENS)->cmn.sensor.init.thresholds && \ + (FULLSENS)->cmn.mask.type.threshold.read.FLAG != 0) { \ + printf(" %-21s : ", NAME); \ + if (UNITS_ARE_DISCRETE((&FULLSENS->cmn))) \ + printf("0x%02X\n", \ + (FULLSENS)->threshold.READ); \ + else \ + printf("%.3f\n", sdr_convert_sensor_reading( \ + (FULLSENS), (FULLSENS)->threshold.READ)); \ } int @@ -1156,91 +1231,221 @@ ipmi_sdr_print_sensor_event_enable(struct ipmi_intf *intf, return 0; } -/* ipmi_sdr_print_sensor_full - print full SDR record +/* ipmi_sdr_print_sensor_hysteresis - print hysteresis for Discrete & Analog * - * @intf: ipmi interface - * @sensor: full sensor structure + * @sensor: Common Sensor Record SDR pointer + * @full: Full Sensor Record SDR pointer (if applicable) + * @hysteresis_value: Actual hysteresis value + * @hvstr: hysteresis value Identifier String + * + * returns void + */ +void +ipmi_sdr_print_sensor_hysteresis(struct sdr_record_common_sensor *sensor, + struct sdr_record_full_sensor *full, + uint8_t hysteresis_value, + const char *hvstr) +{ + /* + * compact can have pos/neg hysteresis, but they cannot be analog! + * We use not full in addition to our discrete units check just in + * case a compact sensor is incorrectly identified as analog. + */ + if (!full || UNITS_ARE_DISCRETE(sensor)) { + if ( hysteresis_value == 0x00 || hysteresis_value == 0xff ) { + printf(" %s : Unspecified\n", hvstr); + } else { + printf(" %s : 0x%02X\n", hvstr, hysteresis_value); + } + return; + } + /* A Full analog sensor */ + double creading = sdr_convert_sensor_hysterisis(full, hysteresis_value); + if ( hysteresis_value == 0x00 || hysteresis_value == 0xff || + creading == 0.0 ) { + printf(" %s : Unspecified\n", hvstr); + } else { + printf(" %s : %.3f\n", hvstr, creading); + } +} + +/* print_sensor_min_max - print Discrete & Analog Minimum/Maximum Sensor Range + * + * @full: Full Sensor Record SDR pointer + * + * returns void + */ +static void +print_sensor_min_max(struct sdr_record_full_sensor *full) +{ + if (!full) { /* No min/max for compact SDR record */ + return; + } + + double creading = 0.0; + uint8_t is_analog = !UNITS_ARE_DISCRETE(&full->cmn); + if (is_analog) + creading = sdr_convert_sensor_reading(full, full->sensor_min); + if ((full->cmn.unit.analog == 0 && full->sensor_min == 0x00) || + (full->cmn.unit.analog == 1 && full->sensor_min == 0xff) || + (full->cmn.unit.analog == 2 && full->sensor_min == 0x80) || + (is_analog && (creading == 0.0))) + printf(" Minimum sensor range : Unspecified\n"); + else { + if (is_analog) + printf(" Minimum sensor range : %.3f\n", creading); + else + printf(" Minimum sensor range : 0x%02X\n", full->sensor_min); + + } + if (is_analog) + creading = sdr_convert_sensor_reading(full, full->sensor_max); + if ((full->cmn.unit.analog == 0 && full->sensor_max == 0xff) || + (full->cmn.unit.analog == 1 && full->sensor_max == 0x00) || + (full->cmn.unit.analog == 2 && full->sensor_max == 0x7f) || + (is_analog && (creading == 0.0))) + printf(" Maximum sensor range : Unspecified\n"); + else { + if (is_analog) + printf(" Maximum sensor range : %.3f\n", creading); + else + printf(" Maximum sensor range : 0x%02X\n", full->sensor_max); + } +} + +/* print_csv_discrete - print csv formatted discrete sensor + * + * @rsp: response from Get Sensor Reading comand + * @sensor: common sensor structure + * @validread: validity of get sensor read command data + * + * returns void + */ +static void +print_csv_discrete(struct ipmi_rs *rsp, + struct sdr_record_common_sensor *sensor, + int validread) +{ + printf("%02Xh,", sensor->keys.sensor_num); + + if (validread == 0 || rsp->ccode != 0) { + printf("ns,%d.%d,No Reading", + sensor->entity.id, + sensor->entity.instance); + } else if (rsp->ccode == 0) { + if (IS_READING_UNAVAILABLE(rsp->data[1])) { + printf("ns,%d.%d,No Reading", + sensor->entity.id, + sensor->entity.instance); + } else { + printf("ok,%d.%d,", + sensor->entity.id, + sensor->entity.instance); + ipmi_sdr_print_discrete_state_mini(", ", + sensor->sensor.type, + sensor->event_type, + rsp->data[2], + rsp->data[3]); + } + } +} + +/* ipmi_sdr_print_sensor_fc - print full & compact SDR records + * + * @intf: ipmi interface + * @sensor: common sensor structure + * @sdr_record_type: type of sdr record, either full or compact * * returns 0 on success * returns -1 on error */ int -ipmi_sdr_print_sensor_full(struct ipmi_intf *intf, - struct sdr_record_full_sensor *sensor) +ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf, + struct sdr_record_common_sensor *sensor, + uint8_t sdr_record_type) { const char *unitstr = NULL; char sval[16], desc[17]; int i = 0, validread = 1; - double val = 0.0, creading = 0.0; + double val = 0.0; struct ipmi_rs *rsp; uint8_t target, lun, channel; + struct sdr_record_full_sensor *full = NULL; + struct sdr_record_compact_sensor *compact = NULL; if (sensor == NULL) return -1; + switch (sdr_record_type) { + case (SDR_RECORD_TYPE_FULL_SENSOR): + full = (struct sdr_record_full_sensor *)sensor; + break; + case SDR_RECORD_TYPE_COMPACT_SENSOR: + compact = (struct sdr_record_compact_sensor *)sensor; + break; + default: + return -1; + } + target = sensor->keys.owner_id; lun = sensor->keys.lun; channel = sensor->keys.channel; memset(desc, 0, sizeof (desc)); - snprintf(desc, (sensor->id_code & 0x1f) + 1, "%s", sensor->id_string); - + if (full) { + snprintf(desc, (full->id_code & 0x1f) + 1, "%s", full->id_string); + } else { + snprintf(desc, (compact->id_code & 0x1f) + 1, "%s", compact->id_string); + } /* get sensor reading */ rsp = ipmi_sdr_get_sensor_reading_ipmb(intf, sensor->keys.sensor_num, sensor->keys.owner_id, sensor->keys.lun, sensor->keys.channel); - if (rsp == NULL) { lprintf(LOG_DEBUG, "Error reading sensor %s (#%02x)", desc, sensor->keys.sensor_num); validread = 0; } else if (rsp->ccode > 0) { - if (rsp->ccode == 0xcb) { - /* sensor not found */ - validread = 0; - } else { + validread = 0; + if ( !((full && rsp->ccode == 0xcb) || + (compact && rsp->ccode == 0xcd)) ) { lprintf(LOG_DEBUG, "Error reading sensor %s (#%02x): %s", desc, - sensor->keys.sensor_num, val2str(rsp->ccode, - completion_code_vals)); - validread = 0; + sensor->keys.sensor_num, + val2str(rsp->ccode, completion_code_vals)); } } else { if (IS_READING_UNAVAILABLE(rsp->data[1])) { /* sensor reading unavailable */ validread = 0; } else if (IS_SCANNING_DISABLED(rsp->data[1])) { - /* Sensor Scanning Disabled */ validread = 0; - if (rsp->data[0] != 0) { - /* we might still get a valid reading , but even 0 might be a valid reading */ - if (sensor->linearization>=SDR_SENSOR_L_NONLINEAR && sensor->linearization<=0x7F) - ipmi_sensor_get_sensor_reading_factors(intf, sensor, rsp->data[0]); - val = sdr_convert_sensor_reading(sensor, - rsp->data[0]); - if (val != 0.0) /* .. an 0.0 might as well be valid */ - validread = 1; + /* Sensor Scanning Disabled */ + lprintf(LOG_DEBUG, "Sensor %s (#%02x) scanning disabled", + desc, sensor->keys.sensor_num); + /* + * No scanning, but when we read we got something other than 0. + * Alas, someone believes that this might mean there is more + * interesting information yet to be gained, so the keep digging + * the hole deeper. Beware of miss-information if you take + * this path. + */ + if (rsp->data[0] != 0) { + val = sdr_convert_analog_reading(intf, full, rsp->data[0], &validread); + if (val != 0.0) /* .. an 0.0 might as well be valid */ + validread = 1; } } else { - /* Non linear sensors might provide updated reading factors */ - if (sensor->linearization>=SDR_SENSOR_L_NONLINEAR && sensor->linearization<=0x7F) { - if (ipmi_sensor_get_sensor_reading_factors(intf, sensor, rsp->data[0]) < 0){ - validread = 0; - } - } - /* convert RAW reading into units */ - val = sdr_convert_sensor_reading(sensor, rsp->data[0]); + val = sdr_convert_analog_reading(intf, full, rsp->data[0], &validread); } } - /* determine units with possible modifiers */ - if (validread) { - unitstr = ipmi_sdr_get_unit_string(sensor->unit.pct, - sensor->unit.modifier, - sensor->unit.type.base, - sensor->unit.type.modifier); - } + /* determine units with possible modifiers */ + unitstr = ipmi_sdr_get_unit_string(sensor->unit.pct, + sensor->unit.modifier, + sensor->unit.type.base, + sensor->unit.type.modifier); /* * CSV OUTPUT */ @@ -1249,49 +1454,70 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf *intf, /* * print sensor name, reading, unit, state */ - printf("%s,", sensor->id_code ? desc : ""); - - if (validread) { - printf("%.*f,", (val == (int) val) ? 0 : 3, val); - printf("%s,%s", unitstr, - ipmi_sdr_get_status(sensor, rsp->data[2])); - } else { - printf(",,ns"); + printf("%s,", desc); + if (!IS_THRESHOLD_SENSOR(sensor)) { + /* Discrete/Non-Threshold */ + print_csv_discrete(rsp, sensor, validread); + printf("\n"); } + else { + /* Threshold Analog & Discrete*/ + if (validread) { + if (full && !UNITS_ARE_DISCRETE(&full->cmn)) { + /* Analog/Threshold */ + printf("%.*f,", (val == (int) val) ? 0 : 3, val); + printf("%s,%s", unitstr, + ipmi_sdr_get_thresh_status(rsp, validread, "ns")); + } else { /* Discrete/Threshold */ + print_csv_discrete(rsp, sensor, validread); + } + } else { + printf(",,ns"); + } - if (verbose) { - printf(",%d.%d,%s,%s,", - sensor->entity.id, sensor->entity.instance, - val2str(sensor->entity.id, entity_id_vals), - ipmi_sdr_get_sensor_type_desc(sensor->sensor. - type)); + if (verbose) { + printf(",%d.%d,%s,%s,", + sensor->entity.id, sensor->entity.instance, + val2str(sensor->entity.id, entity_id_vals), + ipmi_sdr_get_sensor_type_desc(sensor->sensor. + type)); - SENSOR_PRINT_CSV(sensor->analog_flag.nominal_read, - sensor->nominal_read); - SENSOR_PRINT_CSV(sensor->analog_flag.normal_min, - sensor->normal_min); - SENSOR_PRINT_CSV(sensor->analog_flag.normal_max, - sensor->normal_max); - SENSOR_PRINT_CSV(sensor->mask.type.threshold.read.unr, - sensor->threshold.upper.non_recover); - SENSOR_PRINT_CSV(sensor->mask.type.threshold.read.ucr, - sensor->threshold.upper.critical); - SENSOR_PRINT_CSV(sensor->mask.type.threshold.read.unc, - sensor->threshold.upper.non_critical); - SENSOR_PRINT_CSV(sensor->mask.type.threshold.read.lnr, - sensor->threshold.lower.non_recover); - SENSOR_PRINT_CSV(sensor->mask.type.threshold.read.lcr, - sensor->threshold.lower.critical); - SENSOR_PRINT_CSV(sensor->mask.type.threshold.read.lnc, - sensor->threshold.lower.non_critical); + if (full) { + SENSOR_PRINT_CSV(full, full->analog_flag.nominal_read, + full->nominal_read); + SENSOR_PRINT_CSV(full, full->analog_flag.normal_min, + full->normal_min); + SENSOR_PRINT_CSV(full, full->analog_flag.normal_max, + full->normal_max); + SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.unr, + full->threshold.upper.non_recover); + SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.ucr, + full->threshold.upper.critical); + SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.unc, + full->threshold.upper.non_critical); + SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.lnr, + full->threshold.lower.non_recover); + SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.lcr, + full->threshold.lower.critical); + SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.lnc, + full->threshold.lower.non_critical); - printf("%.3f,%.3f", - sdr_convert_sensor_reading(sensor, - sensor->sensor_min), - sdr_convert_sensor_reading(sensor, - sensor->sensor_max)); + if (UNITS_ARE_DISCRETE(&full->cmn)) { + printf("0x%02X,0x%02X", full->sensor_min, full->sensor_max); + } + else { + printf("%.3f,%.3f", + sdr_convert_sensor_reading(full, + full->sensor_min), + sdr_convert_sensor_reading(full, + full->sensor_max)); + } + } else { + printf(",,,,,,,,,,"); + } + } + printf("\n"); } - printf("\n"); return 0; /* done */ } @@ -1304,18 +1530,35 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf *intf, /* * print sensor name, reading, state */ - printf("%-16s | ", sensor->id_code ? desc : ""); + printf("%-16s | ", desc); i = 0; memset(sval, 0, sizeof (sval)); - if (validread) - i += snprintf(sval, sizeof (sval), "%.*f %s", - (val == (int) val) ? 0 : 2, val, unitstr); - else if (rsp && IS_SCANNING_DISABLED(rsp->data[1])) - i += snprintf(sval, sizeof (sval), "disabled "); + if (validread) { + if (IS_THRESHOLD_SENSOR(sensor)) { + /* Threshold Analog & Discrete */ + if( full && (!UNITS_ARE_DISCRETE(sensor)) ) { + i += snprintf(sval, sizeof (sval), "%.*f %s", + (val == (int) val) ? 0 : 2, val, + unitstr); + } else /* Discrete */ + /* + * N.B. data[0] is supposed to be ignored if not + * an analog reading. Should this be data[2] + * like the following non-threshold print? + */ + i += snprintf(sval, sizeof (sval), "0x%02X", rsp->data[0]); + } + else { + /* Discrete */ + i += snprintf(sval, sizeof (sval), "0x%02x", rsp->data[2]); + } + } + else if (rsp && (rsp->ccode == 0) && IS_SCANNING_DISABLED(rsp->data[1])) + i += snprintf(sval, sizeof (sval), full ? "disabled " : "Not Readable "); else - i += snprintf(sval, sizeof (sval), "no reading "); + i += snprintf(sval, sizeof (sval), full ? "no reading " : "Not Readable "); printf("%s", sval); @@ -1324,8 +1567,13 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf *intf, printf(" "); printf(" | "); - printf("%s", validread ? - ipmi_sdr_get_status(sensor, rsp->data[2]) : "ns"); + if (IS_THRESHOLD_SENSOR(sensor)) { + printf("%s", ipmi_sdr_get_thresh_status(rsp, validread, "ns")); + } + else { + printf("%s", validread ? "ok" : "ns"); + } + printf("\n"); return 0; /* done */ @@ -1333,19 +1581,42 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf *intf, /* * print sensor name, number, state, entity, reading */ - printf("%-16s | %02Xh | %-3s | %2d.%1d | ", - sensor->id_code ? desc : "", sensor->keys.sensor_num, - validread ? ipmi_sdr_get_status(sensor, - rsp->data[2]) : "ns", - sensor->entity.id, sensor->entity.instance); + printf("%-16s | %02Xh | ", + desc, sensor->keys.sensor_num); + + if (IS_THRESHOLD_SENSOR(sensor)) { + /* Threshold Analog & Discrete */ + printf("%-3s | %2d.%1d | ", + ipmi_sdr_get_thresh_status(rsp, validread, "ns"), + sensor->entity.id, sensor->entity.instance); + } + else { + /* Discrete */ + printf("%-3s | %2d.%1d | ", + (validread ? "ok" : "ns"), + sensor->entity.id, sensor->entity.instance); + } i = 0; memset(sval, 0, sizeof (sval)); - if (validread) - i += snprintf(sval, sizeof (sval), "%.*f %s", - (val == (int) val) ? 0 : 2, val, unitstr); - else if (rsp && IS_SCANNING_DISABLED(rsp->data[1])) + if (validread) { + if (IS_THRESHOLD_SENSOR(sensor) && + (full && !UNITS_ARE_DISCRETE(sensor)) ) { + /* Threshold Analog */ + i += snprintf(sval, sizeof (sval), "%.*f %s", + (val == (int) val) ? 0 : 2, val, + unitstr); + } else { + /* Discrete & Threshold/Discrete */ + ipmi_sdr_print_discrete_state_mini(", ", + sensor->sensor.type, + sensor->event_type, + rsp->data[2], + rsp->data[3]); + } + } + else if (rsp && (rsp->ccode == 0) && IS_SCANNING_DISABLED(rsp->data[1])) i += snprintf(sval, sizeof (sval), "Disabled"); else i += snprintf(sval, sizeof (sval), "No Reading"); @@ -1353,25 +1624,30 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf *intf, printf("%s\n", sval); return 0; /* done */ } - /* * VERBOSE OUTPUT */ printf("Sensor ID : %s (0x%x)\n", - sensor->id_code ? desc : "", sensor->keys.sensor_num); + desc, sensor->keys.sensor_num); printf(" Entity ID : %d.%d (%s)\n", sensor->entity.id, sensor->entity.instance, val2str(sensor->entity.id, entity_id_vals)); - if (sensor->unit.analog == 3) { - /* discrete sensor */ + if (!IS_THRESHOLD_SENSOR(sensor)) { + /* Discrete */ printf(" Sensor Type (Discrete): %s\n", ipmi_sdr_get_sensor_type_desc(sensor->sensor.type)); + lprintf(LOG_DEBUG, " Event Type Code : 0x%02x", + sensor->event_type); + + if (compact && validread && verbose > 1) + printbuf(rsp->data, rsp->data_len, "COMPACT SENSOR"); + printf(" Sensor Reading : "); if (validread) - printf("%xh\n", (uint32_t) val); - else if (rsp && IS_SCANNING_DISABLED(rsp->data[1])) + printf("%xh\n", rsp ? rsp->data[0] : 0); + else if (rsp && (rsp->ccode == 0) && IS_SCANNING_DISABLED(rsp->data[1])) printf("Disabled\n"); else printf("Not Reading\n"); @@ -1405,89 +1681,66 @@ ipmi_sdr_print_sensor_full(struct ipmi_intf *intf, sensor->event_type, DISCRETE_SENSOR, target, - lun, - channel); + lun, channel); ipmi_sdr_print_sensor_event_enable(intf, sensor->keys.sensor_num, sensor->sensor.type, sensor->event_type, DISCRETE_SENSOR, target, - lun, - channel); + lun, channel); printf(" OEM : %X\n", - sensor->oem); + full ? full->oem : compact->oem); printf("\n"); return 0; /* done */ } - - /* analog sensor */ - printf(" Sensor Type (Analog) : %s\n", + printf(" Sensor Type (Threshold) : %s\n", ipmi_sdr_get_sensor_type_desc(sensor->sensor.type)); printf(" Sensor Reading : "); if (validread) { - uint16_t raw_tol = __TO_TOL(sensor->mtol); - double tol = sdr_convert_sensor_tolerance(sensor, raw_tol); - printf("%.*f (+/- %.*f) %s\n", - (val == (int) val) ? 0 : 3, - val, (tol == (int) tol) ? 0 : 3, tol, unitstr); - } else if (rsp && IS_SCANNING_DISABLED(rsp->data[1])) + if (full) { + uint16_t raw_tol = __TO_TOL(full->mtol); + if (UNITS_ARE_DISCRETE(&full->cmn)) { + printf("0x%02X (+/- 0x%02X) %s\n", rsp->data[0], raw_tol, unitstr); + } + else { + double tol = sdr_convert_sensor_tolerance(full, raw_tol); + printf("%.*f (+/- %.*f) %s\n", + (val == (int) val) ? 0 : 3, + val, (tol == (int) tol) ? 0 : 3, tol, unitstr); + } + } else { + printf("0x%02X %s\n", rsp->data[0], unitstr); + } + } else if (rsp && (rsp->ccode == 0) && IS_SCANNING_DISABLED(rsp->data[1])) printf("Disabled\n"); else printf("No Reading\n"); printf(" Status : %s\n", - validread ? ipmi_sdr_get_status(sensor, - rsp->data[2]) : "Disabled"); + ipmi_sdr_get_thresh_status(rsp, validread, "Not Available")); - SENSOR_PRINT_NORMAL("Nominal Reading", nominal_read); - SENSOR_PRINT_NORMAL("Normal Minimum", normal_min); - SENSOR_PRINT_NORMAL("Normal Maximum", normal_max); + if(full) { + SENSOR_PRINT_NORMAL(full, "Nominal Reading", nominal_read); + SENSOR_PRINT_NORMAL(full, "Normal Minimum", normal_min); + SENSOR_PRINT_NORMAL(full, "Normal Maximum", normal_max); - SENSOR_PRINT_THRESH("Upper non-recoverable", upper.non_recover, unr); - SENSOR_PRINT_THRESH("Upper critical", upper.critical, ucr); - SENSOR_PRINT_THRESH("Upper non-critical", upper.non_critical, unc); - SENSOR_PRINT_THRESH("Lower non-recoverable", lower.non_recover, lnr); - SENSOR_PRINT_THRESH("Lower critical", lower.critical, lcr); - SENSOR_PRINT_THRESH("Lower non-critical", lower.non_critical, lnc); + SENSOR_PRINT_THRESH(full, "Upper non-recoverable", upper.non_recover, unr); + SENSOR_PRINT_THRESH(full, "Upper critical", upper.critical, ucr); + SENSOR_PRINT_THRESH(full, "Upper non-critical", upper.non_critical, unc); + SENSOR_PRINT_THRESH(full, "Lower non-recoverable", lower.non_recover, lnr); + SENSOR_PRINT_THRESH(full, "Lower critical", lower.critical, lcr); + SENSOR_PRINT_THRESH(full, "Lower non-critical", lower.non_critical, lnc); + } + ipmi_sdr_print_sensor_hysteresis(sensor, full, + full->threshold.hysteresis.positive, "Positive Hysteresis"); - creading = - sdr_convert_sensor_hysterisis(sensor, - sensor->threshold.hysteresis.positive); - if (sensor->threshold.hysteresis.positive == 0x00 - || sensor->threshold.hysteresis.positive == 0xff || creading == 0) - printf(" Positive Hysteresis : Unspecified\n"); - else - printf(" Positive Hysteresis : %.3f\n", creading); + ipmi_sdr_print_sensor_hysteresis(sensor, full, + full->threshold.hysteresis.negative, "Negative Hysteresis"); - creading = - sdr_convert_sensor_hysterisis(sensor, - sensor->threshold.hysteresis.negative); - if (sensor->threshold.hysteresis.negative == 0x00 - || sensor->threshold.hysteresis.negative == 0xff || creading == 0.0) - printf(" Negative Hysteresis : Unspecified\n"); - else - printf(" Negative Hysteresis : %.3f\n", creading); - - creading = sdr_convert_sensor_reading(sensor, sensor->sensor_min); - if ((sensor->unit.analog == 0 && sensor->sensor_min == 0x00) || - (sensor->unit.analog == 1 && sensor->sensor_min == 0xff) || - (sensor->unit.analog == 2 && sensor->sensor_min == 0x80) || - creading == 0.0) - printf(" Minimum sensor range : Unspecified\n"); - else - printf(" Minimum sensor range : %.3f\n", creading); - - creading = sdr_convert_sensor_reading(sensor, sensor->sensor_max); - if ((sensor->unit.analog == 0 && sensor->sensor_max == 0xff) || - (sensor->unit.analog == 1 && sensor->sensor_max == 0x00) || - (sensor->unit.analog == 2 && sensor->sensor_max == 0x7f) || - creading == 0.0) - printf(" Maximum sensor range : Unspecified\n"); - else - printf(" Maximum sensor range : %.3f\n", creading); + print_sensor_min_max(full); printf(" Event Message Control : "); switch (sensor->sensor.capabilities.event_msg) { @@ -1648,13 +1901,15 @@ ipmi_sdr_print_discrete_state_mini(const char *separator, if ((1 << (evt->offset - 8)) & (state2 & 0x7f)) { if (pre++ != 0) printf("%s", separator); - printf("%s", evt->desc); + if (evt->desc) + printf("%s", evt->desc); } } else { if ((1 << evt->offset) & state1) { if (pre++ != 0) printf("%s", separator); - printf("%s", evt->desc); + if (evt->desc) + printf("%s", evt->desc); } } c++; @@ -1728,198 +1983,6 @@ ipmi_sdr_print_discrete_state(const char *desc, } } -/* ipmi_sdr_print_sensor_compact - print SDR compact record - * - * @intf: ipmi interface - * @sensor: compact sdr record - * - * returns 0 on success - * returns -1 on error - */ -int -ipmi_sdr_print_sensor_compact(struct ipmi_intf *intf, - struct sdr_record_compact_sensor *sensor) -{ - struct ipmi_rs *rsp; - char desc[17]; - int validread = 1; - uint8_t target, lun, channel; - - if (sensor == NULL) - return -1; - - target = sensor->keys.owner_id; - lun = sensor->keys.lun; - channel = sensor->keys.channel; - - memset(desc, 0, sizeof (desc)); - snprintf(desc, (sensor->id_code & 0x1f) + 1, "%s", sensor->id_string); - - /* get sensor reading */ - rsp = ipmi_sdr_get_sensor_reading_ipmb(intf, sensor->keys.sensor_num, - sensor->keys.owner_id, sensor->keys.lun, sensor->keys.channel); - if (rsp == NULL) { - lprintf(LOG_DEBUG, "Error reading sensor %s (#%02x)", - desc, sensor->keys.sensor_num); - validread = 0; - } - - else if (rsp->ccode > 0) { - /* completion code 0xcd is special case */ - if (rsp->ccode == 0xcd) { - /* sensor not found */ - validread = 0; - } else { - lprintf(LOG_DEBUG, "Error reading sensor %s (#%02x): %s", - desc, sensor->keys.sensor_num, - val2str(rsp->ccode, completion_code_vals)); - validread = 0; - } - } else { - if (IS_READING_UNAVAILABLE(rsp->data[1])) { - /* sensor reading unavailable */ - validread = 0; - } else if (IS_SCANNING_DISABLED(rsp->data[1])) { - validread = 0; - /* check for sensor scanning disabled bit */ - lprintf(LOG_DEBUG, "Sensor %s (#%02x) scanning disabled", - desc, sensor->keys.sensor_num); - } - } - - if (verbose) { - printf("Sensor ID : %s (0x%x)\n", - (sensor->id_code) ? desc : "", sensor->keys.sensor_num); - printf(" Entity ID : %d.%d (%s)\n", - sensor->entity.id, sensor->entity.instance, - val2str(sensor->entity.id, entity_id_vals)); - printf(" Sensor Type (Discrete): %s\n", - ipmi_sdr_get_sensor_type_desc(sensor->sensor.type)); - - lprintf(LOG_DEBUG, " Event Type Code : 0x%02x", - sensor->event_type); - - if (validread && verbose > 1) - printbuf(rsp->data, rsp->data_len, "COMPACT SENSOR"); - - if (validread) - ipmi_sdr_print_discrete_state("States Asserted", - sensor->sensor.type, - sensor->event_type, - rsp->data[2], - rsp->data[3]); - ipmi_sdr_print_sensor_mask(&sensor->mask, - sensor->sensor.type, - sensor->event_type, DISCRETE_SENSOR); - ipmi_sdr_print_sensor_event_status(intf, - sensor->keys.sensor_num, - sensor->sensor.type, - sensor->event_type, - DISCRETE_SENSOR, - target, - lun, - channel); - ipmi_sdr_print_sensor_event_enable(intf, - sensor->keys.sensor_num, - sensor->sensor.type, - sensor->event_type, - DISCRETE_SENSOR, - target, - lun, - channel); - printf(" OEM : %X\n", - sensor->oem); - printf("\n"); - } else { - int dostate = 1; - - if (csv_output) { - printf("%s,%02Xh,", - sensor->id_code ? desc : "", - sensor->keys.sensor_num); - if (validread == 0 || rsp->ccode != 0) { - printf("ns,%d.%d,No Reading", - sensor->entity.id, - sensor->entity.instance); - dostate = 0; - } else if (rsp->ccode == 0) { - if (IS_READING_UNAVAILABLE(rsp->data[1])) { - printf("ns,%d.%d,No Reading", - sensor->entity.id, - sensor->entity.instance); - dostate = 0; - } else - printf("ok,%d.%d,", - sensor->entity.id, - sensor->entity.instance); - } - } else if (sdr_extended) { - - printf("%-16s | %02Xh | ", - sensor->id_code ? desc : "", - sensor->keys.sensor_num); - if (validread == 0 || rsp->ccode != 0) { - printf("ns | %2d.%1d | ", - sensor->entity.id, - sensor->entity.instance); - if (IS_SCANNING_DISABLED(rsp->data[1])) - printf("Disabled"); - else - printf("No Reading"); - dostate = 0; - } else { - if (IS_READING_UNAVAILABLE(rsp->data[1])) { - printf("ns | %2d.%1d | No Reading", - sensor->entity.id, - sensor->entity.instance); - dostate = 0; - } else - printf("ok | %2d.%1d | ", - sensor->entity.id, - sensor->entity.instance); - } - } else { - char *state; - char temp[18]; - - if (validread == 0) { - state = csv_output ? - "Not Readable" : "Not Readable "; - } else if (rsp->data_len > 1 && - IS_READING_UNAVAILABLE(rsp->data[1])) { - state = csv_output ? - "Not Readable" : "Not Readable "; - } else { - sprintf(temp, "0x%02x", rsp->data[2]); - state = temp; - } - - printf("%-16s | ", sensor->id_code ? desc : ""); - if (validread == 0) { - printf("%-17s | ns", state); - } else if (rsp->ccode == 0) { - printf("%-17s | %s", state, - IS_READING_UNAVAILABLE(rsp->data[1]) ? - "ns" : "ok"); - } else { - printf("%-17s | ok", state); - } - - dostate = 0; - } - - if (dostate) - ipmi_sdr_print_discrete_state_mini(", ", - sensor->sensor.type, - sensor->event_type, - rsp->data[2], - rsp->data[3]); - - printf("\n"); - } - - return 0; -} /* ipmi_sdr_print_sensor_eventonly - print SDR event only record * @@ -2392,15 +2455,10 @@ ipmi_sdr_print_rawentry(struct ipmi_intf *intf, uint8_t type, switch (type) { case SDR_RECORD_TYPE_FULL_SENSOR: - rc = ipmi_sdr_print_sensor_full(intf, - (struct sdr_record_full_sensor - *) raw); - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - rc = ipmi_sdr_print_sensor_compact(intf, - (struct - sdr_record_compact_sensor *) - raw); + rc = ipmi_sdr_print_sensor_fc(intf, + (struct sdr_record_common_sensor *) raw, + type); break; case SDR_RECORD_TYPE_EVENTONLY_SENSOR: rc = ipmi_sdr_print_sensor_eventonly(intf, @@ -2466,10 +2524,8 @@ ipmi_sdr_print_listentry(struct ipmi_intf *intf, struct sdr_record_list *entry) switch (entry->type) { case SDR_RECORD_TYPE_FULL_SENSOR: - rc = ipmi_sdr_print_sensor_full(intf, entry->record.full); - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - rc = ipmi_sdr_print_sensor_compact(intf, entry->record.compact); + rc = ipmi_sdr_print_sensor_fc(intf, entry->record.common, entry->type); break; case SDR_RECORD_TYPE_EVENTONLY_SENSOR: rc = ipmi_sdr_print_sensor_eventonly(intf, @@ -2563,12 +2619,9 @@ ipmi_sdr_print_sdr(struct ipmi_intf *intf, uint8_t type) switch (header->type) { case SDR_RECORD_TYPE_FULL_SENSOR: - sdrr->record.full = - (struct sdr_record_full_sensor *) rec; - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - sdrr->record.compact = - (struct sdr_record_compact_sensor *) rec; + sdrr->record.common = + (struct sdr_record_common_sensor *) rec; break; case SDR_RECORD_TYPE_EVENTONLY_SENSOR: sdrr->record.eventonly = @@ -2978,12 +3031,9 @@ ipmi_sdr_list_empty(struct ipmi_intf *intf) for (list = sdr_list_head; list != NULL; list = next) { switch (list->type) { case SDR_RECORD_TYPE_FULL_SENSOR: - if (list->record.full) - free(list->record.full); - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - if (list->record.compact) - free(list->record.compact); + if (list->record.common) + free(list->record.common); break; case SDR_RECORD_TYPE_EVENTONLY_SENSOR: if (list->record.eventonly) @@ -3044,15 +3094,10 @@ ipmi_sdr_find_sdr_bynumtype(struct ipmi_intf *intf, uint16_t gen_id, uint8_t num for (e = sdr_list_head; e != NULL; e = e->next) { switch (e->type) { case SDR_RECORD_TYPE_FULL_SENSOR: - if (e->record.full->keys.sensor_num == num && - e->record.full->keys.owner_id == (gen_id & 0x00ff) && - e->record.full->sensor.type == type) - return e; - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - if (e->record.compact->keys.sensor_num == num && - e->record.compact->keys.owner_id == (gen_id & 0x00ff) && - e->record.compact->sensor.type == type) + if (e->record.common->keys.sensor_num == num && + e->record.common->keys.owner_id == (gen_id & 0x00ff) && + e->record.common->sensor.type == type) return e; break; case SDR_RECORD_TYPE_EVENTONLY_SENSOR: @@ -3084,19 +3129,12 @@ ipmi_sdr_find_sdr_bynumtype(struct ipmi_intf *intf, uint16_t gen_id, uint8_t num switch (header->type) { case SDR_RECORD_TYPE_FULL_SENSOR: - sdrr->record.full = - (struct sdr_record_full_sensor *) rec; - if (sdrr->record.full->keys.sensor_num == num - && sdrr->record.full->keys.owner_id == (gen_id & 0x00ff) - && sdrr->record.full->sensor.type == type) - found = 1; - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - sdrr->record.compact = - (struct sdr_record_compact_sensor *) rec; - if (sdrr->record.compact->keys.sensor_num == num - && sdrr->record.compact->keys.owner_id == (gen_id & 0x00ff) - && sdrr->record.compact->sensor.type == type) + sdrr->record.common = + (struct sdr_record_common_sensor *) rec; + if (sdrr->record.common->keys.sensor_num == num + && sdrr->record.common->keys.owner_id == (gen_id & 0x00ff) + && sdrr->record.common->sensor.type == type) found = 1; break; case SDR_RECORD_TYPE_EVENTONLY_SENSOR: @@ -3177,11 +3215,8 @@ ipmi_sdr_find_sdr_bysensortype(struct ipmi_intf *intf, uint8_t type) for (e = sdr_list_head; e != NULL; e = e->next) { switch (e->type) { case SDR_RECORD_TYPE_FULL_SENSOR: - if (e->record.full->sensor.type == type) - __sdr_list_add(head, e); - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - if (e->record.compact->sensor.type == type) + if (e->record.common->sensor.type == type) __sdr_list_add(head, e); break; case SDR_RECORD_TYPE_EVENTONLY_SENSOR: @@ -3211,15 +3246,10 @@ ipmi_sdr_find_sdr_bysensortype(struct ipmi_intf *intf, uint8_t type) switch (header->type) { case SDR_RECORD_TYPE_FULL_SENSOR: - sdrr->record.full = - (struct sdr_record_full_sensor *) rec; - if (sdrr->record.full->sensor.type == type) - __sdr_list_add(head, sdrr); - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - sdrr->record.compact = - (struct sdr_record_compact_sensor *) rec; - if (sdrr->record.compact->sensor.type == type) + sdrr->record.common = + (struct sdr_record_common_sensor *) rec; + if (sdrr->record.common->sensor.type == type) __sdr_list_add(head, sdrr); break; case SDR_RECORD_TYPE_EVENTONLY_SENSOR: @@ -3295,16 +3325,10 @@ ipmi_sdr_find_sdr_byentity(struct ipmi_intf *intf, struct entity_id *entity) for (e = sdr_list_head; e != NULL; e = e->next) { switch (e->type) { case SDR_RECORD_TYPE_FULL_SENSOR: - if (e->record.full->entity.id == entity->id && - (entity->instance == 0x7f || - e->record.full->entity.instance == - entity->instance)) - __sdr_list_add(head, e); - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - if (e->record.compact->entity.id == entity->id && + if (e->record.common->entity.id == entity->id && (entity->instance == 0x7f || - e->record.compact->entity.instance == + e->record.common->entity.instance == entity->instance)) __sdr_list_add(head, e); break; @@ -3366,20 +3390,12 @@ ipmi_sdr_find_sdr_byentity(struct ipmi_intf *intf, struct entity_id *entity) switch (header->type) { case SDR_RECORD_TYPE_FULL_SENSOR: - sdrr->record.full = - (struct sdr_record_full_sensor *) rec; - if (sdrr->record.full->entity.id == entity->id - && (entity->instance == 0x7f - || sdrr->record.full->entity.instance == - entity->instance)) - __sdr_list_add(head, sdrr); - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - sdrr->record.compact = - (struct sdr_record_compact_sensor *) rec; - if (sdrr->record.compact->entity.id == entity->id + sdrr->record.common = + (struct sdr_record_common_sensor *) rec; + if (sdrr->record.common->entity.id == entity->id && (entity->instance == 0x7f - || sdrr->record.compact->entity.instance == + || sdrr->record.common->entity.instance == entity->instance)) __sdr_list_add(head, sdrr); break; @@ -3500,12 +3516,9 @@ ipmi_sdr_find_sdr_bytype(struct ipmi_intf *intf, uint8_t type) switch (header->type) { case SDR_RECORD_TYPE_FULL_SENSOR: - sdrr->record.full = - (struct sdr_record_full_sensor *) rec; - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - sdrr->record.compact = - (struct sdr_record_compact_sensor *) rec; + sdrr->record.common = + (struct sdr_record_common_sensor *) rec; break; case SDR_RECORD_TYPE_EVENTONLY_SENSOR: sdrr->record.eventonly = @@ -3806,12 +3819,9 @@ ipmi_sdr_list_cache_fromfile(struct ipmi_intf *intf, const char *ifile) switch (header.type) { case SDR_RECORD_TYPE_FULL_SENSOR: - sdrr->record.full = - (struct sdr_record_full_sensor *) rec; - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - sdrr->record.compact = - (struct sdr_record_compact_sensor *) rec; + sdrr->record.common = + (struct sdr_record_common_sensor *) rec; break; case SDR_RECORD_TYPE_EVENTONLY_SENSOR: sdrr->record.eventonly = @@ -3904,12 +3914,9 @@ ipmi_sdr_list_cache(struct ipmi_intf *intf) switch (header->type) { case SDR_RECORD_TYPE_FULL_SENSOR: - sdrr->record.full = - (struct sdr_record_full_sensor *) rec; - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - sdrr->record.compact = - (struct sdr_record_compact_sensor *) rec; + sdrr->record.common = + (struct sdr_record_common_sensor *) rec; break; case SDR_RECORD_TYPE_EVENTONLY_SENSOR: sdrr->record.eventonly = diff --git a/ipmitool/lib/ipmi_sel.c b/ipmitool/lib/ipmi_sel.c index 64f679d..4f50c69 100644 --- a/ipmitool/lib/ipmi_sel.c +++ b/ipmitool/lib/ipmi_sel.c @@ -1124,10 +1124,10 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt) ((evt->sel_type.standard_type.event_data[0] & 0xf) % 2) ? ">" : "<", (threshold_reading==(int)threshold_reading) ? 0 : 2, threshold_reading, - ipmi_sdr_get_unit_string(sdr->record.full->unit.pct, - sdr->record.full->unit.modifier, - sdr->record.full->unit.type.base, - sdr->record.full->unit.type.modifier)); + ipmi_sdr_get_unit_string(sdr->record.common->unit.pct, + sdr->record.common->unit.modifier, + sdr->record.common->unit.type.base, + sdr->record.common->unit.type.modifier)); } else if (evt->sel_type.standard_type.event_type == 0x6f) { /* @@ -1312,10 +1312,10 @@ ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_ sdr_convert_sensor_reading(sdr->record.full, evt->sel_type.standard_type.event_data[1])); /* determine units with possible modifiers */ - printf ("%s\n", ipmi_sdr_get_unit_string(sdr->record.full->unit.pct, - sdr->record.full->unit.modifier, - sdr->record.full->unit.type.base, - sdr->record.full->unit.type.modifier)); + printf ("%s\n", ipmi_sdr_get_unit_string(sdr->record.common->unit.pct, + sdr->record.common->unit.modifier, + sdr->record.common->unit.type.base, + sdr->record.common->unit.type.modifier)); break; case 2: /* oem code in byte 2 */ @@ -1338,10 +1338,10 @@ ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_ sdr_convert_sensor_reading(sdr->record.full, evt->sel_type.standard_type.event_data[2])); /* determine units with possible modifiers */ - printf ("%s\n", ipmi_sdr_get_unit_string(sdr->record.full->unit.pct, - sdr->record.full->unit.modifier, - sdr->record.full->unit.type.base, - sdr->record.full->unit.type.modifier)); + printf ("%s\n", ipmi_sdr_get_unit_string(sdr->record.common->unit.pct, + sdr->record.common->unit.modifier, + sdr->record.common->unit.type.base, + sdr->record.common->unit.type.modifier)); break; case 2: /* OEM code in byte 3 */ @@ -2052,14 +2052,11 @@ ipmi_sel_show_entry(struct ipmi_intf * intf, int argc, char ** argv) verbose = verbose ? : 1; switch (sdr->type) { case SDR_RECORD_TYPE_FULL_SENSOR: - ipmi_sensor_print_full(intf, sdr->record.full); - entity.id = sdr->record.full->entity.id; - entity.instance = sdr->record.full->entity.instance; - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - ipmi_sensor_print_compact(intf, sdr->record.compact); - entity.id = sdr->record.compact->entity.id; - entity.instance = sdr->record.compact->entity.instance; + ipmi_sensor_print_fc(intf, sdr->record.common, + sdr->type); + entity.id = sdr->record.common->entity.id; + entity.instance = sdr->record.common->entity.instance; break; case SDR_RECORD_TYPE_EVENTONLY_SENSOR: ipmi_sdr_print_sensor_eventonly(intf, sdr->record.eventonly); diff --git a/ipmitool/lib/ipmi_sensor.c b/ipmitool/lib/ipmi_sensor.c index 58b793b..95429e4 100644 --- a/ipmitool/lib/ipmi_sensor.c +++ b/ipmitool/lib/ipmi_sensor.c @@ -43,9 +43,6 @@ extern int verbose; -#define SCANNING_DISABLED 0x40 -#define READING_UNAVAILABLE 0x20 - // static int ipmi_sensor_get_sensor_reading_factors( @@ -65,7 +62,7 @@ ipmi_sensor_get_sensor_reading_factors( memset(id, 0, sizeof(id)); memcpy(id, sensor->id_string, 16); - req_data[0] = sensor->keys.sensor_num; + req_data[0] = sensor->cmn.keys.sensor_num; req_data[1] = reading; memset(&req, 0, sizeof(req)); @@ -78,7 +75,7 @@ ipmi_sensor_get_sensor_reading_factors( if (rsp == NULL) { lprintf(LOG_ERR, "Error updating reading factor for sensor %s (#%02x)", - id, sensor->keys.sensor_num); + id, sensor->cmn.keys.sensor_num); return -1; } else if (rsp->ccode) { return -1; @@ -142,20 +139,34 @@ ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf, } static int -ipmi_sensor_print_full_discrete(struct ipmi_intf *intf, - struct sdr_record_full_sensor *sensor) +ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf, + struct sdr_record_common_sensor *sensor, + uint8_t sdr_record_type) { char id[17]; char *unitstr = "discrete"; int validread = 1; uint8_t val = 0; struct ipmi_rs *rsp; + struct sdr_record_full_sensor *full = NULL; + struct sdr_record_compact_sensor *compact = NULL; if (sensor == NULL) return -1; + switch (sdr_record_type) { + case (SDR_RECORD_TYPE_FULL_SENSOR): + full = (struct sdr_record_full_sensor *)sensor; + break; + case SDR_RECORD_TYPE_COMPACT_SENSOR: + compact = (struct sdr_record_compact_sensor *)sensor; + break; + default: + return -1; + } + memset(id, 0, sizeof (id)); - memcpy(id, sensor->id_string, 16); + memcpy(id, full ? full->id_string : compact->id_string, 16); /* * Get current reading @@ -166,12 +177,17 @@ ipmi_sensor_print_full_discrete(struct ipmi_intf *intf, sensor->keys.lun, sensor->keys.channel); if (rsp == NULL) { + /* + * Why can't we just set validread equal to zero and fall + * though in the same way ipmi_sdr_print_sensor_fc does? + * All the cases below correctly handle validread. + */ lprintf(LOG_ERR, "Error reading sensor %s (#%02x)", id, sensor->keys.sensor_num); return -1; - } else if (rsp->ccode > 0 || (rsp->data[1] & READING_UNAVAILABLE)) { + } else if (rsp->ccode || IS_READING_UNAVAILABLE(rsp->data[1])) { validread = 0; - } else if (!(rsp->data[1] & SCANNING_DISABLED)) { + } else if (IS_SCANNING_DISABLED(rsp->data[1])) { validread = 0; } else { /* convert RAW reading into units */ @@ -206,41 +222,82 @@ ipmi_sensor_print_full_discrete(struct ipmi_intf *intf, printf(" Sensor Type (Discrete): %s\n", ipmi_sdr_get_sensor_type_desc(sensor->sensor. type)); - if( validread ) - { - ipmi_sdr_print_discrete_state("States Asserted", - sensor->sensor.type, - sensor->event_type, - rsp->data[2], - rsp->data[3]); + if( validread ) + { + ipmi_sdr_print_discrete_state("States Asserted", + sensor->sensor.type, + sensor->event_type, + rsp->data[2], + rsp->data[3]); + if (compact) { + printf(" Raw Data: %X", rsp->data[1]); + if(rsp->data_len > 2) + printf(" %X", rsp->data[2]); + if(rsp->data_len > 3) + printf(" %X", rsp->data[3]); + printf("\n"); + } printf("\n"); - } else { - printf(" Unable to read sensor: Device Not Present\n\n"); - } - + } else { + printf(" Unable to read sensor: Device Not Present\n\n"); + } } } return (validread ? 0 : -1 ); } +static void +print_thresh_setting(struct sdr_record_full_sensor *full, + uint8_t thresh_is_avail, uint8_t setting, + const char *field_sep, + const char *analog_fmt, + const char *discrete_fmt, + const char *na_fmt) +{ + printf("%s", field_sep); + if (!thresh_is_avail) { + printf(na_fmt, "na"); + return; + } + if (full && !UNITS_ARE_DISCRETE(&full->cmn)) { + printf(analog_fmt, sdr_convert_sensor_reading (full, setting)); + } else { + printf(discrete_fmt, setting); + } +} + static int -ipmi_sensor_print_full_analog(struct ipmi_intf *intf, - struct sdr_record_full_sensor *sensor) +ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf, + struct sdr_record_common_sensor *sensor, + uint8_t sdr_record_type) { const char *unitstr = NULL; char id[17]; int validread = 1, thresh_available = 1; - double val = 0.0; + double val = 0.0; /* converted analog value if a valid read */ + uint8_t get_sens_read = 0;/* discrete value if a valid read*/ struct ipmi_rs *rsp; - char *status = NULL; + const char *thresh_status = ""; + struct sdr_record_full_sensor *full = NULL; + struct sdr_record_compact_sensor *compact = NULL; if (sensor == NULL) return -1; - memset(id, 0, sizeof (id)); - memcpy(id, sensor->id_string, 16); + switch (sdr_record_type) { + case (SDR_RECORD_TYPE_FULL_SENSOR): + full = (struct sdr_record_full_sensor *)sensor; + break; + case SDR_RECORD_TYPE_COMPACT_SENSOR: + compact = (struct sdr_record_compact_sensor *)sensor; + break; + default: + return -1; + } + memset(id, 0, sizeof (id)); + memcpy(id, full ? full->id_string : compact->id_string, 16); /* * Get current reading @@ -251,28 +308,25 @@ ipmi_sensor_print_full_analog(struct ipmi_intf *intf, sensor->keys.lun, sensor->keys.channel); if (rsp == NULL) { + /* + * Why can't we just set validread equal to zero and fall + * though in the same way ipmi_sdr_print_sensor_fc does? + * All the cases below correctly handle validread. + */ lprintf(LOG_ERR, "Error reading sensor %s (#%02x)", id, sensor->keys.sensor_num); return -1; - } else if (rsp->ccode || (rsp->data[1] & READING_UNAVAILABLE)) { + } else if (rsp->ccode || IS_READING_UNAVAILABLE(rsp->data[1])) { validread = 0; - } else if (!(rsp->data[1] & SCANNING_DISABLED)) { + } else if (IS_SCANNING_DISABLED(rsp->data[1])) { validread = 0; } else { - /* Non linear sensors might provide updated reading factors */ - if (sensor->linearization>=SDR_SENSOR_L_NONLINEAR && sensor->linearization<=0x7F) { - if (ipmi_sensor_get_sensor_reading_factors(intf, sensor, rsp->data[0]) < 0){ - printf("sensor %s non-linear!\n", id); - return -1; - } - } + /* Store off for use later */ + get_sens_read = rsp->data[0]; - /* convert RAW reading into units */ - /* a raw reading of 0 is perfectly valid, and might be converted to a positive or - negative value, as any other raw values */ - val = sdr_convert_sensor_reading(sensor, rsp->data[0]); - status = (char *) ipmi_sdr_get_status(sensor, rsp->data[2]); + val = sdr_convert_analog_reading(intf, full, get_sens_read, &validread); + thresh_status = ipmi_sdr_get_thresh_status(rsp, validread, "ns"); } /* @@ -299,49 +353,28 @@ ipmi_sensor_print_full_analog(struct ipmi_intf *intf, */ printf("%-16s ", id); if (validread) { - printf("| %-10.3f | %-10s | %-6s", - val, unitstr, status ? : ""); + if (full && !UNITS_ARE_DISCRETE(sensor)) + printf("| %-10.3f | %-10s | %-6s", + val, unitstr, thresh_status); + else + printf("| 0x%-8x | %-10s | %-6s", + get_sens_read, unitstr, thresh_status); } else { printf("| %-10s | %-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"); + if (thresh_available && full) { +#define PTS(bit, dataidx) { \ + print_thresh_setting(full, rsp->data[0] & (bit), \ + rsp->data[(dataidx)], "| ", "%-10.3f", "0x-8x", "%-10s"); \ +} + PTS(LOWER_NON_RECOV_SPECIFIED, 3); + PTS(LOWER_CRIT_SPECIFIED, 2); + PTS(LOWER_NON_CRIT_SPECIFIED, 1); + PTS(UPPER_NON_CRIT_SPECIFIED, 4); + PTS(UPPER_CRIT_SPECIFIED, 5); + PTS(UPPER_NON_RECOV_SPECIFIED, 6); +#undef PTS } else { printf ("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s", @@ -356,99 +389,64 @@ ipmi_sensor_print_full_analog(struct ipmi_intf *intf, printf(" Entity ID : %d.%d\n", sensor->entity.id, sensor->entity.instance); - printf(" Sensor Type (Analog) : %s\n", + printf(" Sensor Type (Threshold) : %s\n", ipmi_sdr_get_sensor_type_desc(sensor->sensor. type)); printf(" Sensor Reading : "); if (validread) { - uint16_t raw_tol = __TO_TOL(sensor->mtol); - double tol = - sdr_convert_sensor_tolerance(sensor, - raw_tol); - printf("%.*f (+/- %.*f) %s\n", - (val == (int) val) ? 0 : 3, val, - (tol == (int) tol) ? 0 : 3, tol, - unitstr); - printf(" Status : %s\n", - status ? : ""); + if (full) { + uint16_t raw_tol = __TO_TOL(full->mtol); + if (!UNITS_ARE_DISCRETE(sensor)) { + double tol = + sdr_convert_sensor_tolerance(full, + raw_tol); + printf("%.*f (+/- %.*f) %s\n", + (val == (int) val) ? 0 : 3, val, + (tol == (int) tol) ? 0 : 3, tol, + unitstr); + } else { + printf("0x%x (+/- 0x%x) %s\n", + get_sens_read, + raw_tol, + unitstr); + } + } else { + printf("0x%x %s\n", get_sens_read, unitstr); + } + printf(" Status : %s\n", thresh_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"); + if (full) { +#define PTS(bit, dataidx, str) { \ +print_thresh_setting(full, rsp->data[0] & (bit), \ + rsp->data[(dataidx)], \ + (str), "%.3f\n", "0x%x\n", "%s\n"); \ +} - if ( - sensor->threshold.hysteresis.positive == 0x00 - || - sensor->threshold.hysteresis.positive == 0xff - ) - printf(" Positive Hysteresis : Unspecified\n"); - else - printf(" Positive Hysteresis : %.3f\n", - sdr_convert_sensor_hysterisis - (sensor,sensor->threshold.hysteresis.positive)); + PTS(LOWER_NON_RECOV_SPECIFIED, 3, " Lower Non-Recoverable : "); + PTS(LOWER_CRIT_SPECIFIED, 2, " Lower Critical : "); + PTS(LOWER_NON_CRIT_SPECIFIED, 1, " Lower Non-Critical : "); + PTS(UPPER_NON_CRIT_SPECIFIED, 4, " Upper Non-Critical : "); + PTS(UPPER_CRIT_SPECIFIED, 5, " Upper Critical : "); + PTS(UPPER_NON_RECOV_SPECIFIED, 6, " Upper Non-Recoverable : "); +#undef PTS - if ( - sensor->threshold.hysteresis.negative == 0x00 - || - sensor->threshold.hysteresis.negative == 0xff - ) - printf(" Negative Hysteresis : Unspecified\n"); - else - printf(" Negative Hysteresis : %.3f\n", - sdr_convert_sensor_hysterisis - (sensor,sensor->threshold.hysteresis.negative)); + } + ipmi_sdr_print_sensor_hysteresis(sensor, full, + full ? full->threshold.hysteresis.positive : + compact->threshold.hysteresis.positive, + "Positive Hysteresis"); + + ipmi_sdr_print_sensor_hysteresis(sensor, full, + full ? full->threshold.hysteresis.negative : + compact->threshold.hysteresis.negative, + "Negative Hysteresis"); } else { printf(" Sensor Threshold Settings not available\n"); } } else { - printf(" Unable to read sensor: Device Not Present\n\n"); + printf(" Unable to read sensor: Device Not Present\n\n"); } ipmi_sdr_print_sensor_event_status(intf, @@ -478,104 +476,14 @@ ipmi_sensor_print_full_analog(struct ipmi_intf *intf, } int -ipmi_sensor_print_full(struct ipmi_intf *intf, - struct sdr_record_full_sensor *sensor) +ipmi_sensor_print_fc(struct ipmi_intf *intf, + struct sdr_record_common_sensor *sensor, + uint8_t sdr_record_type) { - if (sensor->unit.analog != 3) - return ipmi_sensor_print_full_analog(intf, sensor); + if (IS_THRESHOLD_SENSOR(sensor)) + return ipmi_sensor_print_fc_threshold(intf, sensor, sdr_record_type); else - return ipmi_sensor_print_full_discrete(intf, sensor); -} - -int -ipmi_sensor_print_compact(struct ipmi_intf *intf, - struct sdr_record_compact_sensor *sensor) -{ - char id[17]; - char *unitstr = "discrete"; - int validread = 1; - uint8_t val = 0; - struct ipmi_rs *rsp; - - if (sensor == NULL) - return -1; - - memset(id, 0, sizeof (id)); - memcpy(id, sensor->id_string, 16); - - /* - * Get current reading - */ - rsp = ipmi_sdr_get_sensor_reading_ipmb(intf, - sensor->keys.sensor_num, - sensor->keys.owner_id, - sensor->keys.lun, - sensor->keys.channel); - if (rsp == NULL) { - lprintf(LOG_ERR, "Error reading sensor %s (#%02x)", - id, sensor->keys.sensor_num); - return -1; - } else if (rsp->ccode || (rsp->data[1] & READING_UNAVAILABLE)) { - validread = 0; - } else if (!(rsp->data[1] & SCANNING_DISABLED)) { - validread = 0; - } else { - /* convert RAW reading into units */ - val = rsp->data[0]; - } - - if (csv_output) { - /* NOT IMPLEMENTED */ - } 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(" Entity ID : %d.%d\n", - sensor->entity.id, sensor->entity.instance); - printf(" Sensor Type (Discrete): %s\n", - ipmi_sdr_get_sensor_type_desc(sensor->sensor. - type)); - - if(validread) - { - ipmi_sdr_print_discrete_state("States Asserted", - sensor->sensor.type, - sensor->event_type, - rsp->data[2], - rsp->data[3]); - printf(" Raw Data: %X", rsp->data[1]); - if(rsp->data_len > 2) - printf(" %X", rsp->data[2]); - if(rsp->data_len > 3) - printf(" %X", rsp->data[3]); - printf("\n"); - printf("\n"); - } else { - printf(" Unable to read sensor: Device Not Present\n\n"); - } - - } - } - - return (validread ? 0 : -1 ); + return ipmi_sensor_print_fc_discrete(intf, sensor, sdr_record_type); } static int @@ -605,16 +513,12 @@ ipmi_sensor_list(struct ipmi_intf *intf) switch (header->type) { case SDR_RECORD_TYPE_FULL_SENSOR: - r = ipmi_sensor_print_full(intf, - (struct - sdr_record_full_sensor *) - rec); - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - r = ipmi_sensor_print_compact(intf, - (struct - sdr_record_compact_sensor - *) rec); + r = ipmi_sensor_print_fc(intf, + (struct + sdr_record_common_sensor *) + rec, + header->type); break; } free(rec); @@ -662,6 +566,28 @@ __ipmi_sensor_set_threshold(struct ipmi_intf *intf, return 0; } +static uint8_t +__ipmi_sensor_threshold_value_to_raw(struct sdr_record_full_sensor *full, double value) +{ + if (!UNITS_ARE_DISCRETE(&full->cmn)) { /* Has an analog reading */ + /* Has an analog reading and supports mx+b */ + return sdr_convert_sensor_value_to_raw(full, value); + } + else { + /* Does not have an analog reading and/or does not support mx+b */ + if (value > 255) { + return 255; + } + else if (value < 0) { + return 0; + } + else { + return (uint8_t )value; + } + } +} + + static int ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv) { @@ -763,90 +689,89 @@ ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv) return -1; } + if (!IS_THRESHOLD_SENSOR(sdr->record.common)) { + lprintf(LOG_ERR, "Invalid sensor event type %02x", sdr->record.common->event_type); + return -1; + } + + if (allUpper) { settingMask = UPPER_NON_CRIT_SPECIFIED; printf("Setting sensor \"%s\" %s threshold to %.3f\n", sdr->record.full->id_string, val2str(settingMask, threshold_vals), setting1); ret = __ipmi_sensor_set_threshold(intf, - sdr->record.full->keys. + sdr->record.common->keys. sensor_num, settingMask, - sdr_convert_sensor_value_to_raw - (sdr->record.full, setting1), - sdr->record.full->keys.owner_id, - sdr->record.full->keys.lun); + __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1), + sdr->record.common->keys.owner_id, + sdr->record.common->keys.lun); settingMask = UPPER_CRIT_SPECIFIED; printf("Setting sensor \"%s\" %s threshold to %.3f\n", sdr->record.full->id_string, val2str(settingMask, threshold_vals), setting2); ret = __ipmi_sensor_set_threshold(intf, - sdr->record.full->keys. + sdr->record.common->keys. sensor_num, settingMask, - sdr_convert_sensor_value_to_raw - (sdr->record.full, setting2), - sdr->record.full->keys.owner_id, - sdr->record.full->keys.lun); + __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2), + sdr->record.common->keys.owner_id, + sdr->record.common->keys.lun); settingMask = UPPER_NON_RECOV_SPECIFIED; printf("Setting sensor \"%s\" %s threshold to %.3f\n", sdr->record.full->id_string, val2str(settingMask, threshold_vals), setting3); ret = __ipmi_sensor_set_threshold(intf, - sdr->record.full->keys. + sdr->record.common->keys. sensor_num, settingMask, - sdr_convert_sensor_value_to_raw - (sdr->record.full, setting3), - sdr->record.full->keys.owner_id, - sdr->record.full->keys.lun); + __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3), + sdr->record.common->keys.owner_id, + sdr->record.common->keys.lun); } else if (allLower) { settingMask = LOWER_NON_RECOV_SPECIFIED; printf("Setting sensor \"%s\" %s threshold to %.3f\n", sdr->record.full->id_string, val2str(settingMask, threshold_vals), setting1); ret = __ipmi_sensor_set_threshold(intf, - sdr->record.full->keys. + sdr->record.common->keys. sensor_num, settingMask, - sdr_convert_sensor_value_to_raw - (sdr->record.full, setting1), - sdr->record.full->keys.owner_id, - sdr->record.full->keys.lun); + __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1), + sdr->record.common->keys.owner_id, + sdr->record.common->keys.lun); settingMask = LOWER_CRIT_SPECIFIED; printf("Setting sensor \"%s\" %s threshold to %.3f\n", sdr->record.full->id_string, val2str(settingMask, threshold_vals), setting2); ret = __ipmi_sensor_set_threshold(intf, - sdr->record.full->keys. + sdr->record.common->keys. sensor_num, settingMask, - sdr_convert_sensor_value_to_raw - (sdr->record.full, setting2), - sdr->record.full->keys.owner_id, - sdr->record.full->keys.lun); + __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2), + sdr->record.common->keys.owner_id, + sdr->record.common->keys.lun); settingMask = LOWER_NON_CRIT_SPECIFIED; printf("Setting sensor \"%s\" %s threshold to %.3f\n", sdr->record.full->id_string, val2str(settingMask, threshold_vals), setting3); ret = __ipmi_sensor_set_threshold(intf, - sdr->record.full->keys. + sdr->record.common->keys. sensor_num, settingMask, - sdr_convert_sensor_value_to_raw - (sdr->record.full, setting3), - sdr->record.full->keys.owner_id, - sdr->record.full->keys.lun); + __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3), + sdr->record.common->keys.owner_id, + sdr->record.common->keys.lun); } else { printf("Setting sensor \"%s\" %s threshold to %.3f\n", sdr->record.full->id_string, val2str(settingMask, threshold_vals), setting1); ret = __ipmi_sensor_set_threshold(intf, - sdr->record.full->keys. + sdr->record.common->keys. sensor_num, settingMask, - sdr_convert_sensor_value_to_raw - (sdr->record.full, setting1), - sdr->record.full->keys.owner_id, - sdr->record.full->keys.lun); + __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1), + sdr->record.common->keys.owner_id, + sdr->record.common->keys.lun); } return ret; @@ -877,24 +802,29 @@ ipmi_sensor_get_reading(struct ipmi_intf *intf, int argc, char **argv) switch (sdr->type) { case SDR_RECORD_TYPE_FULL_SENSOR: + /* Only Threshold can return an analog reading */ + if (!IS_THRESHOLD_SENSOR(sdr->record.common)) { + lprintf(LOG_ERR, "Sensor \"%s\" is a discrete sensor!", argv[i]); + continue; + } if (sdr->record.full->linearization >= SDR_SENSOR_L_NONLINEAR) { lprintf(LOG_ERR, "Sensor \"%s\" non-linear!", argv[i]); continue; } rsp = ipmi_sdr_get_sensor_reading_ipmb(intf, - sdr->record.full->keys.sensor_num, - sdr->record.full->keys.owner_id, - sdr->record.full->keys.lun, - sdr->record.full->keys.channel); + sdr->record.common->keys.sensor_num, + sdr->record.common->keys.owner_id, + sdr->record.common->keys.lun, + sdr->record.common->keys.channel); if (rsp == NULL) { lprintf(LOG_ERR, "Error reading sensor \"%s\"", argv[i]); rc = -1; continue; } else if (rsp->ccode > 0) { continue; - } else if (rsp->data[1] & READING_UNAVAILABLE) { + } else if (IS_READING_UNAVAILABLE(rsp->data[1])) { continue; - } else if (!(rsp->data[1] & SCANNING_DISABLED)) { + } else if (IS_SCANNING_DISABLED(rsp->data[1])) { continue; } else if (rsp->data[0] > 0) { /* convert RAW reading into units */ @@ -953,11 +883,9 @@ ipmi_sensor_get(struct ipmi_intf *intf, int argc, char **argv) verbose = 1; switch (sdr->type) { case SDR_RECORD_TYPE_FULL_SENSOR: - r = ipmi_sensor_print_full(intf, sdr->record.full); - break; case SDR_RECORD_TYPE_COMPACT_SENSOR: - r = ipmi_sensor_print_compact(intf, - sdr->record.compact); + r = ipmi_sensor_print_fc(intf, sdr->record.common, + sdr->type); break; case SDR_RECORD_TYPE_EVENTONLY_SENSOR: r = ipmi_sdr_print_sensor_eventonly(intf, diff --git a/ipmitool/src/ipmievd.c b/ipmitool/src/ipmievd.c index 2512250..19cdea6 100644 --- a/ipmitool/src/ipmievd.c +++ b/ipmitool/src/ipmievd.c @@ -284,10 +284,10 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt) ((evt->sel_type.standard_type.event_data[0] & 0xf) % 2) ? ">" : "<", (threshold_reading==(int)threshold_reading) ? 0 : 2, threshold_reading, - ipmi_sdr_get_unit_string(sdr->record.full->unit.pct, - sdr->record.full->unit.modifier, - sdr->record.full->unit.type.base, - sdr->record.full->unit.type.modifier)); + ipmi_sdr_get_unit_string(sdr->record.common->unit.pct, + sdr->record.common->unit.modifier, + sdr->record.common->unit.type.base, + sdr->record.common->unit.type.modifier)); } else if ((evt->sel_type.standard_type.event_type >= 0x2 && evt->sel_type.standard_type.event_type <= 0xc) || (evt->sel_type.standard_type.event_type == 0x6f)) { diff --git a/ipmitool/src/plugins/lanplus/lanplus.c b/ipmitool/src/plugins/lanplus/lanplus.c index 45eb2f8..e65db87 100644 --- a/ipmitool/src/plugins/lanplus/lanplus.c +++ b/ipmitool/src/plugins/lanplus/lanplus.c @@ -746,7 +746,8 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf) rsp->payload.ipmi_response.cmd == 0x34) { memcpy(rsp->data, &rsp->data[offset], (rsp->data_len-offset)); - printbuf( &rsp->data[offset], + if (verbose > 2) + printbuf( &rsp->data[offset], (rsp->data_len-offset), "bridge command response"); } @@ -2089,10 +2090,16 @@ ipmi_lanplus_send_payload( int try = 0; int xmit = 1; time_t ltime; + uint32_t timeout; if (!intf->opened && intf->open && intf->open(intf) < 0) return NULL; + /* + * The session timeout is initialized in the above interface open, + * so it will only be valid after the open completes. + */ + timeout = session->timeout; while (try < session->retry) { //ltime = time(NULL); @@ -2287,21 +2294,19 @@ ipmi_lanplus_send_payload( break; } - xmit = ((time(NULL) - ltime) >= intf->session->timeout); + /* only timeout if time exceeds the timeout value */ + xmit = ((time(NULL) - ltime) > timeout); usleep(5000); if (xmit) { - /* incremet session timeout each retry */ - intf->session->timeout++; + /* increment session timeout by 1 second each retry */ + timeout++; } try++; } - /* Reset timeout after retry loop completes */ - intf->session->timeout = IPMI_LAN_TIMEOUT; - /* IPMI messages are deleted under ipmi_lan_poll_recv() */ switch (payload->payload_type) { case IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST: