diff --git a/ipmitool/include/ipmitool/ipmi_intf.h b/ipmitool/include/ipmitool/ipmi_intf.h index 894d2a0..8b5b6f6 100644 --- a/ipmitool/include/ipmitool/ipmi_intf.h +++ b/ipmitool/include/ipmitool/ipmi_intf.h @@ -165,6 +165,7 @@ struct ipmi_intf { int opened; int abort; int noanswer; + IPMI_OEM manufacturer_id; struct ipmi_session * session; struct ipmi_oem_handle * oem; diff --git a/ipmitool/include/ipmitool/ipmi_sdr.h b/ipmitool/include/ipmitool/ipmi_sdr.h index 5db1e75..3c88397 100644 --- a/ipmitool/include/ipmitool/ipmi_sdr.h +++ b/ipmitool/include/ipmitool/ipmi_sdr.h @@ -820,6 +820,22 @@ static const char *sensor_type_desc[] __attribute__ ((unused)) = { "Management Subsystem Health", "Battery","Session Audit", "Version Change","FRU State" }; +struct sensor_reading { + char s_id[17]; /* name of the sensor */ + struct sdr_record_full_sensor *full; + struct sdr_record_compact_sensor *compact; + uint8_t s_reading_valid; /* read value valididity */ + uint8_t s_scanning_disabled; /* read of value disabled */ + uint8_t s_reading_unavailable; /* read value unavailable */ + uint8_t s_reading; /* value which was read */ + uint8_t s_data2; /* data2 value read */ + uint8_t s_data3; /* data3 value read */ + uint8_t s_has_analog_value; /* sensor has analog value */ + double s_a_val; /* read value converted to analog */ + char s_a_str[16]; /* analog value as a string */ + const char *s_a_units; /* analog value units string */ +}; + struct ipmi_sdr_iterator *ipmi_sdr_start(struct ipmi_intf *intf, int use_builtin); struct sdr_get_rs *ipmi_sdr_get_next_header(struct ipmi_intf *intf, @@ -829,7 +845,7 @@ uint8_t *ipmi_sdr_get_record(struct ipmi_intf *intf, struct sdr_get_rs *header, void ipmi_sdr_end(struct ipmi_intf *intf, struct ipmi_sdr_iterator *i); int ipmi_sdr_print_sdr(struct ipmi_intf *intf, uint8_t type); -int ipmi_sdr_print_name_from_rawentry(struct ipmi_intf *intf,uint16_t id, +int ipmi_sdr_print_name_from_rawentry(struct ipmi_intf *intf,uint16_t id, uint8_t type,uint8_t * raw); int ipmi_sdr_print_rawentry(struct ipmi_intf *intf, uint8_t type, uint8_t * raw, int len); @@ -841,16 +857,17 @@ void ipmi_sdr_print_sensor_hysteresis(struct sdr_record_common_sensor *sensor, 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_thresh_status(struct ipmi_rs *rsp, - int validread, const char *invalidstr); +struct sensor_reading * +ipmi_sdr_read_sensor_value(struct ipmi_intf *intf, + struct sdr_record_common_sensor *sensor, + uint8_t sdr_record_type, int precision); +const char *ipmi_sdr_get_thresh_status(struct sensor_reading *sr, + 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, @@ -901,7 +918,7 @@ int ipmi_sdr_print_info(struct ipmi_intf *intf); void ipmi_sdr_print_discrete_state(const char *desc, uint8_t sensor_type, uint8_t event_type, uint8_t state1, uint8_t state2); -void ipmi_sdr_print_discrete_state_mini(const char *separator, +void ipmi_sdr_print_discrete_state_mini(const char *header, const char *separator, uint8_t sensor_type, uint8_t event_type, uint8_t state1, uint8_t state2); int ipmi_sdr_print_sensor_event_status(struct ipmi_intf *intf, diff --git a/ipmitool/lib/ipmi_event.c b/ipmitool/lib/ipmi_event.c index 6580975..ef2d733 100644 --- a/ipmitool/lib/ipmi_event.c +++ b/ipmitool/lib/ipmi_event.c @@ -227,8 +227,8 @@ ipmi_event_find_offset(uint8_t code, static void print_sensor_states(uint8_t sensor_type, uint8_t event_type) { - printf("Sensor States: \n "); - ipmi_sdr_print_discrete_state_mini("\n ", sensor_type, + ipmi_sdr_print_discrete_state_mini( + "Sensor States: \n ", "\n ", sensor_type, event_type, 0xff, 0xff); printf("\n"); } diff --git a/ipmitool/lib/ipmi_sdr.c b/ipmitool/lib/ipmi_sdr.c index 14951d8..9ea2526 100644 --- a/ipmitool/lib/ipmi_sdr.c +++ b/ipmitool/lib/ipmi_sdr.c @@ -1,4 +1,7 @@ /* + * Copyright (c) 2012 Hewlett-Packard Development Company, L.P. + * + * Based on code from * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -106,48 +109,67 @@ ipmi_sdr_get_unit_string(uint8_t pct, uint8_t type, uint8_t base, uint8_t modifi } break; } - return unitstr; } -/* sdr_convert_analog_reading - convert raw sensor reading to analog +/* sdr_sensor_has_analog_reading - Determine if sensor has an analog reading * - * @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) +static int +sdr_sensor_has_analog_reading(struct ipmi_intf *intf, + struct sensor_reading *sr) { - /* Compact sensors can't return analog values so we return zero */ - if (!full) { - return 0.0; + /* Compact sensors can't return analog values so we false */ + if (!sr->full) { + return 0; } /* - * Only Full Threshold sensors with analog readings can be converted. - * If this not the case, we return zero + * Per the IPMI Specification: + * Only Full Threshold sensors are identified as providing + * analog readings. + * + * But... HP didn't interpret this as meaning that "Only Threshold + * Sensors" can provide analog readings. So, HP packed analog + * readings into some of their non-Threshold Sensor. There is + * nothing that explictly prohibits this in the spec, so if + * an Analog reading is available in a Non-Threshod sensor and + * there are units specified for identifying the reading then + * we do an analog conversion even though the sensor is + * non-Threshold. To be safe, we provide this extension for + * HP. + * */ - if ( !(IS_THRESHOLD_SENSOR(&full->cmn) && - !UNITS_ARE_DISCRETE(&full->cmn)) ) { - return 0.0; + if ( UNITS_ARE_DISCRETE(&sr->full->cmn) ) { + return 0;/* Sensor specified as not having Analog Units */ + } + if ( !IS_THRESHOLD_SENSOR(&sr->full->cmn) ) { + /* Non-Threshold Sensors are not defined as having analog */ + /* But.. We have one with defined with Analog Units */ + if ( (sr->full->cmn.unit.pct | sr->full->cmn.unit.modifier | + sr->full->cmn.unit.type.base | + sr->full->cmn.unit.type.modifier)) { + /* And it does have the necessary units specs */ + if ( !(intf->manufacturer_id == IPMI_OEM_HP) ) { + /* But to be safe we only do this for HP */ + return 0; + } + } else { + return 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; + if (sr->full->linearization >= SDR_SENSOR_L_NONLINEAR && + sr->full->linearization <= 0x7F) { + if (ipmi_sensor_get_sensor_reading_factors(intf, sr->full, sr->s_reading) < 0){ + sr->s_reading_valid = 0; + return 0; } } - return sdr_convert_sensor_reading(full, read); + return 1; } /* sdr_convert_sensor_reading - convert raw sensor reading @@ -672,13 +694,13 @@ ipmi_sdr_get_sensor_type_desc(const uint8_t type) * ns = not specified */ const char * -ipmi_sdr_get_thresh_status(struct ipmi_rs *rsp, int validread, const char *invalidstr) +ipmi_sdr_get_thresh_status(struct sensor_reading *sr, const char *invalidstr) { uint8_t stat; - if (!validread) { + if (!sr->s_reading_valid) { return invalidstr; } - stat = rsp->data[2]; + stat = sr->s_data2; if (stat & SDR_SENSOR_STAT_LO_NR) { if (verbose) return "Lower Non-Recoverable"; @@ -938,7 +960,7 @@ ipmi_sdr_print_sensor_event_status(struct ipmi_intf *intf, sensor_num, val2str(rsp->ccode, completion_code_vals)); return -1; } - + /* There is an assumption here that data_len >= 1 */ if (IS_READING_UNAVAILABLE(rsp->data[0])) { printf(" Event Status : Unavailable\n"); return 0; @@ -1315,39 +1337,152 @@ print_sensor_min_max(struct sdr_record_full_sensor *full) /* 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 + * @sr: sensor reading * * returns void */ static void -print_csv_discrete(struct ipmi_rs *rsp, - struct sdr_record_common_sensor *sensor, - int validread) +print_csv_discrete(struct sdr_record_common_sensor *sensor, + const struct sensor_reading *sr) { - printf("%02Xh,", sensor->keys.sensor_num); - - if (validread == 0 || rsp->ccode != 0) { - printf("ns,%d.%d,No Reading", + if (!sr->s_reading_valid || sr->s_reading_unavailable) { + printf("%02Xh,ns,%d.%d,No Reading", + sensor->keys.sensor_num, 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]); - } + return; } + + if (sr->s_has_analog_value) { /* Sensor has an analog value */ + printf("%s,%s,", sr->s_a_str, sr->s_a_units); + } else { /* Sensor has a discrete value */ + printf("%02Xh,", sensor->keys.sensor_num); + } + printf("ok,%d.%d,", + sensor->entity.id, + sensor->entity.instance); + ipmi_sdr_print_discrete_state_mini(NULL, ", ", + sensor->sensor.type, + sensor->event_type, + sr->s_data2, + sr->s_data3); +} + +/* ipmi_sdr_read_sensor_value - read sensor value + * + * @intf Interface pointer + * @sensor Common sensor component pointer + * @sdr_record_type Type of sdr sensor record + * @precision decimal precision for analog format conversion + * + * returns a pointer to sensor value reading data structure + */ +struct sensor_reading * +ipmi_sdr_read_sensor_value(struct ipmi_intf *intf, + struct sdr_record_common_sensor *sensor, + uint8_t sdr_record_type, int precision) +{ + static struct sensor_reading sr; + + if (sensor == NULL) + return NULL; + + /* Initialize to reading valid value of zero */ + memset(&sr, 0, sizeof(sr)); + + switch (sdr_record_type) { + int idlen; + case (SDR_RECORD_TYPE_FULL_SENSOR): + sr.full = (struct sdr_record_full_sensor *)sensor; + idlen = sr.full->id_code & 0x1f; + idlen = idlen < sizeof(sr.s_id) ? + idlen : sizeof(sr.s_id) - 1; + memcpy(sr.s_id, sr.full->id_string, idlen); + break; + case SDR_RECORD_TYPE_COMPACT_SENSOR: + sr.compact = (struct sdr_record_compact_sensor *)sensor; + idlen = sr.compact->id_code & 0x1f; + idlen = idlen < sizeof(sr.s_id) ? + idlen : sizeof(sr.s_id) - 1; + memcpy(sr.s_id, sr.compact->id_string, idlen); + break; + default: + return NULL; + } + + /* + * Get current reading via IPMI interface + */ + struct ipmi_rs *rsp; + rsp = ipmi_sdr_get_sensor_reading_ipmb(intf, + sensor->keys.sensor_num, + sensor->keys.owner_id, + sensor->keys.lun, + sensor->keys.channel); + sr.s_a_val = 0.0; /* init analog value to a floating point 0 */ + sr.s_a_str[0] = '\0'; /* no converted analog value string */ + sr.s_a_units = ""; /* no converted analog units units */ + + + if (rsp == NULL) { + lprintf(LOG_DEBUG, "Error reading sensor %s (#%02x)", + sr.s_id, sensor->keys.sensor_num); + return &sr; + } + + if (rsp->ccode) { + if ( !((sr.full && rsp->ccode == 0xcb) || + (sr.compact && rsp->ccode == 0xcd)) ) { + lprintf(LOG_DEBUG, + "Error reading sensor %s (#%02x): %s", sr.s_id, + sensor->keys.sensor_num, + val2str(rsp->ccode, completion_code_vals)); + } + return &sr; + } + + if (rsp->data_len < 2) { + /* + * We must be returned both a value (data[0]), and the validity + * of the value (data[1]), in order to correctly interpret + * the reading. If we don't have both of these we can't have + * a valid sensor reading. + */ + lprintf(LOG_DEBUG, "Error reading sensor %s invalid len %d", + sr.s_id, rsp->data_len); + return &sr; + } + + + if (IS_READING_UNAVAILABLE(rsp->data[1])) + sr.s_reading_unavailable = 1; + + if (IS_SCANNING_DISABLED(rsp->data[1])) { + sr.s_scanning_disabled = 1; + lprintf(LOG_DEBUG, "Sensor %s (#%02x) scanning disabled", + sr.s_id, sensor->keys.sensor_num); + return &sr; + } + sr.s_reading_valid = 1; + sr.s_reading = rsp->data[0]; + if (rsp->data_len > 2) + sr.s_data2 = rsp->data[2]; + if (rsp->data_len > 3) + sr.s_data3 = rsp->data[3]; + if (sdr_sensor_has_analog_reading(intf, &sr)) { + sr.s_has_analog_value = 1; + sr.s_a_val = sdr_convert_sensor_reading(sr.full, sr.s_reading); + /* determine units string with possible modifiers */ + sr.s_a_units = ipmi_sdr_get_unit_string(sr.full->cmn.unit.pct, + sr.full->cmn.unit.modifier, + sr.full->cmn.unit.type.base, + sr.full->cmn.unit.type.modifier); + snprintf(sr.s_a_str, sizeof(sr.s_a_str), "%.*f", + (sr.s_a_val == (int) sr.s_a_val) ? 0 : + precision, sr.s_a_val); + } + return &sr; } /* ipmi_sdr_print_sensor_fc - print full & compact SDR records @@ -1364,88 +1499,21 @@ 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; - struct ipmi_rs *rsp; + char sval[16]; + int i = 0; uint8_t target, lun, channel; - struct sdr_record_full_sensor *full = NULL; - struct sdr_record_compact_sensor *compact = NULL; + struct sensor_reading *sr; - if (sensor == NULL) + + sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 2); + + if (sr == 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)); - 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) { - 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)); - } - } else { - if (IS_READING_UNAVAILABLE(rsp->data[1])) { - /* sensor reading unavailable */ - validread = 0; - } else if (IS_SCANNING_DISABLED(rsp->data[1])) { - validread = 0; - /* 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 { - val = sdr_convert_analog_reading(intf, full, rsp->data[0], &validread); - } - } - - - /* 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 */ @@ -1454,22 +1522,24 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf, /* * print sensor name, reading, unit, state */ - printf("%s,", desc); + printf("%s,", sr->s_id); if (!IS_THRESHOLD_SENSOR(sensor)) { /* Discrete/Non-Threshold */ - print_csv_discrete(rsp, sensor, validread); + print_csv_discrete(sensor, sr); printf("\n"); } else { /* Threshold Analog & Discrete*/ - if (validread) { - if (full && !UNITS_ARE_DISCRETE(&full->cmn)) { + if (sr->s_reading_valid) { + if (sr->s_has_analog_value) { /* Analog/Threshold */ - printf("%.*f,", (val == (int) val) ? 0 : 3, val); - printf("%s,%s", unitstr, - ipmi_sdr_get_thresh_status(rsp, validread, "ns")); + printf("%.*f,", (sr->s_a_val == + (int) sr->s_a_val) ? 0 : 3, + sr->s_a_val); + printf("%s,%s", sr->s_a_units, + ipmi_sdr_get_thresh_status(sr, "ns")); } else { /* Discrete/Threshold */ - print_csv_discrete(rsp, sensor, validread); + print_csv_discrete(sensor, sr); } } else { printf(",,ns"); @@ -1482,35 +1552,35 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf, ipmi_sdr_get_sensor_type_desc(sensor->sensor. type)); - 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); + if (sr->full) { + SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.nominal_read, + sr->full->nominal_read); + SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.normal_min, + sr->full->normal_min); + SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.normal_max, + sr->full->normal_max); + SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.unr, + sr->full->threshold.upper.non_recover); + SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.ucr, + sr->full->threshold.upper.critical); + SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.unc, + sr->full->threshold.upper.non_critical); + SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.lnr, + sr->full->threshold.lower.non_recover); + SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.lcr, + sr->full->threshold.lower.critical); + SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.lnc, + sr->full->threshold.lower.non_critical); - if (UNITS_ARE_DISCRETE(&full->cmn)) { - printf("0x%02X,0x%02X", full->sensor_min, full->sensor_max); + if (UNITS_ARE_DISCRETE(sensor)) { + printf("0x%02X,0x%02X", sr->full->sensor_min, sr->full->sensor_max); } else { printf("%.3f,%.3f", - sdr_convert_sensor_reading(full, - full->sensor_min), - sdr_convert_sensor_reading(full, - full->sensor_max)); + sdr_convert_sensor_reading(sr->full, + sr->full->sensor_min), + sdr_convert_sensor_reading(sr->full, + sr->full->sensor_max)); } } else { printf(",,,,,,,,,,"); @@ -1530,48 +1600,35 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf, /* * print sensor name, reading, state */ - printf("%-16s | ", desc); + printf("%-16s | ", sr->s_id); - i = 0; memset(sval, 0, sizeof (sval)); - 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]); - } + if (sr->s_reading_valid) { + if( sr->s_has_analog_value ) { + snprintf(sval, sizeof (sval), "%s %s", + sr->s_a_str, + sr->s_a_units); + } else /* Discrete */ + snprintf(sval, sizeof(sval), + "0x%02x", sr->s_reading); } - else if (rsp && (rsp->ccode == 0) && IS_SCANNING_DISABLED(rsp->data[1])) - i += snprintf(sval, sizeof (sval), full ? "disabled " : "Not Readable "); + else if (sr->s_scanning_disabled) + snprintf(sval, sizeof (sval), sr->full ? "disabled" : "Not Readable"); else - i += snprintf(sval, sizeof (sval), full ? "no reading " : "Not Readable "); + snprintf(sval, sizeof (sval), sr->full ? "no reading" : "Not Readable"); printf("%s", sval); - i--; - for (; i < sizeof (sval); i++) + for (i = strlen(sval); i <= sizeof (sval); i++) printf(" "); printf(" | "); if (IS_THRESHOLD_SENSOR(sensor)) { - printf("%s", ipmi_sdr_get_thresh_status(rsp, validread, "ns")); + printf("%s", ipmi_sdr_get_thresh_status(sr, "ns")); } else { - printf("%s", validread ? "ok" : "ns"); + printf("%s", sr->s_reading_valid ? "ok" : "ns"); } printf("\n"); @@ -1582,44 +1639,48 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf, * print sensor name, number, state, entity, reading */ printf("%-16s | %02Xh | ", - desc, sensor->keys.sensor_num); + sr->s_id, sensor->keys.sensor_num); if (IS_THRESHOLD_SENSOR(sensor)) { /* Threshold Analog & Discrete */ printf("%-3s | %2d.%1d | ", - ipmi_sdr_get_thresh_status(rsp, validread, "ns"), + ipmi_sdr_get_thresh_status(sr, "ns"), sensor->entity.id, sensor->entity.instance); } else { - /* Discrete */ + /* Non Threshold Analog & Discrete */ printf("%-3s | %2d.%1d | ", - (validread ? "ok" : "ns"), + (sr->s_reading_valid ? "ok" : "ns"), sensor->entity.id, sensor->entity.instance); } - i = 0; memset(sval, 0, sizeof (sval)); - if (validread) { + if (sr->s_reading_valid) { if (IS_THRESHOLD_SENSOR(sensor) && - (full && !UNITS_ARE_DISCRETE(sensor)) ) { + sr->s_has_analog_value ) { /* Threshold Analog */ - i += snprintf(sval, sizeof (sval), "%.*f %s", - (val == (int) val) ? 0 : 2, val, - unitstr); + snprintf(sval, sizeof (sval), "%s %s", + sr->s_a_str, + sr->s_a_units); } else { - /* Discrete & Threshold/Discrete */ - ipmi_sdr_print_discrete_state_mini(", ", + /* Analog & Discrete & Threshold/Discrete */ + char *header = NULL; + if (sr->s_has_analog_value) { /* Sensor has an analog value */ + printf("%s %s", sr->s_a_str, sr->s_a_units); + header = ", "; + } + ipmi_sdr_print_discrete_state_mini(header, ", ", sensor->sensor.type, sensor->event_type, - rsp->data[2], - rsp->data[3]); + sr->s_data2, + sr->s_data3); } } - else if (rsp && (rsp->ccode == 0) && IS_SCANNING_DISABLED(rsp->data[1])) - i += snprintf(sval, sizeof (sval), "Disabled"); + else if (sr->s_scanning_disabled) + snprintf(sval, sizeof (sval), "Disabled"); else - i += snprintf(sval, sizeof (sval), "No Reading"); + snprintf(sval, sizeof (sval), "No Reading"); printf("%s\n", sval); return 0; /* done */ @@ -1629,7 +1690,7 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf, */ printf("Sensor ID : %s (0x%x)\n", - desc, sensor->keys.sensor_num); + sr->s_id, sensor->keys.sensor_num); printf(" Entity ID : %d.%d (%s)\n", sensor->entity.id, sensor->entity.instance, val2str(sensor->entity.id, entity_id_vals)); @@ -1641,13 +1702,15 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf, 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", rsp ? rsp->data[0] : 0); - else if (rsp && (rsp->ccode == 0) && IS_SCANNING_DISABLED(rsp->data[1])) + if (sr->s_reading_valid) { + if (sr->s_has_analog_value) { /* Sensor has an analog value */ + printf("%s %s\n", sr->s_a_str, sr->s_a_units); + } else { + printf("%xh\n", sr->s_reading); + } + } + else if (sr->s_scanning_disabled) printf("Disabled\n"); else printf("Not Reading\n"); @@ -1671,8 +1734,8 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf, ipmi_sdr_print_discrete_state("States Asserted", sensor->sensor.type, sensor->event_type, - rsp ? rsp->data[2] : 0, - rsp ? rsp->data[3] : 0); + sr->s_data2, + sr->s_data3); ipmi_sdr_print_sensor_mask(&sensor->mask, sensor->sensor.type, sensor->event_type, DISCRETE_SENSOR); ipmi_sdr_print_sensor_event_status(intf, @@ -1690,7 +1753,7 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf, target, lun, channel); printf(" OEM : %X\n", - full ? full->oem : compact->oem); + sr->full ? sr->full->oem : sr->compact->oem); printf("\n"); return 0; /* done */ @@ -1699,48 +1762,50 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf, ipmi_sdr_get_sensor_type_desc(sensor->sensor.type)); printf(" Sensor Reading : "); - if (validread) { - 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); + if (sr->s_reading_valid) { + if (sr->full) { + uint16_t raw_tol = __TO_TOL(sr->full->mtol); + if (UNITS_ARE_DISCRETE(sensor)) { + printf("0x%02X (+/- 0x%02X) %s\n", + sr->s_reading, raw_tol, sr->s_a_units); } else { - double tol = sdr_convert_sensor_tolerance(full, raw_tol); + double tol = sdr_convert_sensor_tolerance(sr->full, raw_tol); printf("%.*f (+/- %.*f) %s\n", - (val == (int) val) ? 0 : 3, - val, (tol == (int) tol) ? 0 : 3, tol, unitstr); + (sr->s_a_val == (int) sr->s_a_val) ? 0 : 3, + sr->s_a_val, (tol == (int) tol) ? 0 : + 3, tol, sr->s_a_units); } } else { - printf("0x%02X %s\n", rsp->data[0], unitstr); + printf("0x%02X %s\n", sr->s_reading, sr->s_a_units); } - } else if (rsp && (rsp->ccode == 0) && IS_SCANNING_DISABLED(rsp->data[1])) + } else if (sr->s_scanning_disabled) printf("Disabled\n"); else printf("No Reading\n"); printf(" Status : %s\n", - ipmi_sdr_get_thresh_status(rsp, validread, "Not Available")); + ipmi_sdr_get_thresh_status(sr, "Not Available")); - 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); + if(sr->full) { + SENSOR_PRINT_NORMAL(sr->full, "Nominal Reading", nominal_read); + SENSOR_PRINT_NORMAL(sr->full, "Normal Minimum", normal_min); + SENSOR_PRINT_NORMAL(sr->full, "Normal Maximum", normal_max); - 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); + SENSOR_PRINT_THRESH(sr->full, "Upper non-recoverable", upper.non_recover, unr); + SENSOR_PRINT_THRESH(sr->full, "Upper critical", upper.critical, ucr); + SENSOR_PRINT_THRESH(sr->full, "Upper non-critical", upper.non_critical, unc); + SENSOR_PRINT_THRESH(sr->full, "Lower non-recoverable", lower.non_recover, lnr); + SENSOR_PRINT_THRESH(sr->full, "Lower critical", lower.critical, lcr); + SENSOR_PRINT_THRESH(sr->full, "Lower non-critical", lower.non_critical, lnc); } - ipmi_sdr_print_sensor_hysteresis(sensor, full, - full->threshold.hysteresis.positive, "Positive Hysteresis"); + ipmi_sdr_print_sensor_hysteresis(sensor, sr->full, + sr->full->threshold.hysteresis.positive, "Positive Hysteresis"); - ipmi_sdr_print_sensor_hysteresis(sensor, full, - full->threshold.hysteresis.negative, "Negative Hysteresis"); + ipmi_sdr_print_sensor_hysteresis(sensor, sr->full, + sr->full->threshold.hysteresis.negative, "Negative Hysteresis"); - print_sensor_min_max(full); + print_sensor_min_max(sr->full); printf(" Event Message Control : "); switch (sensor->sensor.capabilities.event_msg) { @@ -1866,6 +1931,8 @@ get_offset(uint8_t x) /* ipmi_sdr_print_discrete_state_mini - print list of asserted states * for a discrete sensor * + * @header : header string if necessary + * @separator : field separator string * @sensor_type : sensor type code * @event_type : event type code * @state : mask of asserted states @@ -1873,7 +1940,7 @@ get_offset(uint8_t x) * no meaningful return value */ void -ipmi_sdr_print_discrete_state_mini(const char *separator, +ipmi_sdr_print_discrete_state_mini(const char *header, const char *separator, uint8_t sensor_type, uint8_t event_type, uint8_t state1, uint8_t state2) { @@ -1892,6 +1959,9 @@ ipmi_sdr_print_discrete_state_mini(const char *separator, typ = event_type; } + if (header) + printf("%s", header); + for (; evt->type != NULL; evt++) { if ((evt->code != typ) || (evt->data != 0xFF)) diff --git a/ipmitool/lib/ipmi_sel.c b/ipmitool/lib/ipmi_sel.c index 4f50c69..367232b 100644 --- a/ipmitool/lib/ipmi_sel.c +++ b/ipmitool/lib/ipmi_sel.c @@ -281,6 +281,15 @@ ipmi_get_oem(struct ipmi_intf * intf) return IPMI_OEM_UNKNOWN; } + /* + * Return the cached manufacturer id if the device is open and + * we got an identified OEM owner. Otherwise just attempt to read + * it. + */ + if (intf->opened && intf->manufacturer_id != IPMI_OEM_UNKNOWN) { + return intf->manufacturer_id; + } + memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_APP; req.msg.cmd = BMC_GET_DEVICE_ID; @@ -299,7 +308,7 @@ ipmi_get_oem(struct ipmi_intf * intf) devid = (struct ipm_devid_rsp *) rsp->data; - lprintf(LOG_DEBUG,"Iana: 0x%ul", + lprintf(LOG_DEBUG,"Iana: 0x%u", IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id)); return IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id); diff --git a/ipmitool/lib/ipmi_sensor.c b/ipmitool/lib/ipmi_sensor.c index 95429e4..8d41de9 100644 --- a/ipmitool/lib/ipmi_sensor.c +++ b/ipmitool/lib/ipmi_sensor.c @@ -143,55 +143,13 @@ 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; + const char *id; + struct sensor_reading *sr; - if (sensor == NULL) + sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3); + + if (sr == 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, full ? full->id_string : compact->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) { - /* - * 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 || IS_READING_UNAVAILABLE(rsp->data[1])) { - validread = 0; - } else if (IS_SCANNING_DISABLED(rsp->data[1])) { - validread = 0; - } else { - /* convert RAW reading into units */ - val = rsp->data[0]; } if (csv_output) { @@ -201,14 +159,20 @@ ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf, /* 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]); + printf("%-16s ", sr->s_id); + if (sr->s_reading_valid) { + if (sr->s_has_analog_value) { + /* don't show discrete component */ + printf("| %-10s | %-10s | %-6s", + sr->s_a_str, sr->s_a_units, "ok"); + } else { + printf("| 0x%-8x | %-10s | 0x%02x%02x", + sr->s_reading, "discrete", + sr->s_data2, sr->s_data3); + } } else { printf("| %-10s | %-10s | %-6s", - "na", unitstr, "na"); + "na", "discrete", "na"); } printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s", "na", "na", "na", "na", "na", "na"); @@ -216,27 +180,22 @@ ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf, printf("\n"); } else { printf("Sensor ID : %s (0x%x)\n", - id, sensor->keys.sensor_num); + sr->s_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 ) + if( sr->s_reading_valid ) { + if (sr->s_has_analog_value) { + printf(" Sensor Reading : %s %s\n", sr->s_a_str, sr->s_a_units); + } 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"); - } + sr->s_data2, + sr->s_data3); printf("\n"); } else { printf(" Unable to read sensor: Device Not Present\n\n"); @@ -244,7 +203,7 @@ ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf, } } - return (validread ? 0 : -1 ); + return (sr->s_reading_valid ? 0 : -1 ); } static void @@ -272,100 +231,50 @@ 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; /* converted analog value if a valid read */ - uint8_t get_sens_read = 0;/* discrete value if a valid read*/ + int thresh_available = 1; struct ipmi_rs *rsp; - const char *thresh_status = ""; - struct sdr_record_full_sensor *full = NULL; - struct sdr_record_compact_sensor *compact = NULL; + struct sensor_reading *sr; - if (sensor == NULL) + sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3); + + if (sr == 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, full ? full->id_string : compact->id_string, 16); + const char *thresh_status = ipmi_sdr_get_thresh_status(sr, "ns"); - /* - * 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) { - /* - * 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 || IS_READING_UNAVAILABLE(rsp->data[1])) { - validread = 0; - } else if (IS_SCANNING_DISABLED(rsp->data[1])) { - validread = 0; - } else { - - /* Store off for use later */ - get_sens_read = rsp->data[0]; - - val = sdr_convert_analog_reading(intf, full, get_sens_read, &validread); - thresh_status = ipmi_sdr_get_thresh_status(rsp, validread, "ns"); - } - - /* - * Figure out units - */ - unitstr = ipmi_sdr_get_unit_string(sensor->unit.pct, - sensor->unit.modifier, - sensor->unit.type.base, - sensor->unit.type.modifier); /* * Get sensor thresholds */ - rsp = ipmi_sdr_get_sensor_thresholds(intf, sensor->keys.sensor_num, - sensor->keys.owner_id, sensor->keys.lun, sensor->keys.channel); - if ((rsp == NULL) || (rsp->ccode > 0)) + rsp = ipmi_sdr_get_sensor_thresholds(intf, + sensor->keys.sensor_num, sensor->keys.owner_id, + sensor->keys.lun, sensor->keys.channel); + + if ((rsp == NULL) || (rsp->ccode > 0) || (rsp->data_len == 0)) thresh_available = 0; if (csv_output) { - /* NOT IPMLEMENTED */ + /* NOT IMPLEMENTED */ } else { if (verbose == 0) { /* output format * id value units status thresholds.... */ - printf("%-16s ", id); - if (validread) { - if (full && !UNITS_ARE_DISCRETE(sensor)) + printf("%-16s ", sr->s_id); + if (sr->s_reading_valid) { + if (sr->s_has_analog_value) printf("| %-10.3f | %-10s | %-6s", - val, unitstr, thresh_status); + sr->s_a_val, sr->s_a_units, thresh_status); else printf("| 0x%-8x | %-10s | %-6s", - get_sens_read, unitstr, thresh_status); + sr->s_reading, sr->s_a_units, thresh_status); } else { printf("| %-10s | %-10s | %-6s", - "na", unitstr, "na"); + "na", sr->s_a_units, "na"); } - if (thresh_available && full) { + if (thresh_available && sr->full) { #define PTS(bit, dataidx) { \ - print_thresh_setting(full, rsp->data[0] & (bit), \ + print_thresh_setting(sr->full, rsp->data[0] & (bit), \ rsp->data[(dataidx)], "| ", "%-10.3f", "0x-8x", "%-10s"); \ } PTS(LOWER_NON_RECOV_SPECIFIED, 3); @@ -384,7 +293,7 @@ ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf, printf("\n"); } else { printf("Sensor ID : %s (0x%x)\n", - id, sensor->keys.sensor_num); + sr->s_id, sensor->keys.sensor_num); printf(" Entity ID : %d.%d\n", sensor->entity.id, sensor->entity.instance); @@ -394,32 +303,35 @@ ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf, type)); printf(" Sensor Reading : "); - if (validread) { - if (full) { - uint16_t raw_tol = __TO_TOL(full->mtol); - if (!UNITS_ARE_DISCRETE(sensor)) { + if (sr->s_reading_valid) { + if (sr->full) { + uint16_t raw_tol = __TO_TOL(sr->full->mtol); + if (sr->s_has_analog_value) { double tol = - sdr_convert_sensor_tolerance(full, + sdr_convert_sensor_tolerance(sr->full, raw_tol); printf("%.*f (+/- %.*f) %s\n", - (val == (int) val) ? 0 : 3, val, + (sr->s_a_val == (int) + sr->s_a_val) ? 0 : 3, + sr->s_a_val, (tol == (int) tol) ? 0 : 3, tol, - unitstr); + sr->s_a_units); } else { printf("0x%x (+/- 0x%x) %s\n", - get_sens_read, + sr->s_reading, raw_tol, - unitstr); + sr->s_a_units); } } else { - printf("0x%x %s\n", get_sens_read, unitstr); + printf("0x%x %s\n", sr->s_reading, + sr->s_a_units); } printf(" Status : %s\n", thresh_status); if (thresh_available) { - if (full) { + if (sr->full) { #define PTS(bit, dataidx, str) { \ -print_thresh_setting(full, rsp->data[0] & (bit), \ +print_thresh_setting(sr->full, rsp->data[0] & (bit), \ rsp->data[(dataidx)], \ (str), "%.3f\n", "0x%x\n", "%s\n"); \ } @@ -433,14 +345,14 @@ print_thresh_setting(full, rsp->data[0] & (bit), \ #undef PTS } - ipmi_sdr_print_sensor_hysteresis(sensor, full, - full ? full->threshold.hysteresis.positive : - compact->threshold.hysteresis.positive, + ipmi_sdr_print_sensor_hysteresis(sensor, sr->full, + sr->full ? sr->full->threshold.hysteresis.positive : + sr->compact->threshold.hysteresis.positive, "Positive Hysteresis"); - ipmi_sdr_print_sensor_hysteresis(sensor, full, - full ? full->threshold.hysteresis.negative : - compact->threshold.hysteresis.negative, + ipmi_sdr_print_sensor_hysteresis(sensor, sr->full, + sr->full ? sr->full->threshold.hysteresis.negative : + sr->compact->threshold.hysteresis.negative, "Negative Hysteresis"); } else { printf(" Sensor Threshold Settings not available\n"); @@ -472,7 +384,7 @@ print_thresh_setting(full, rsp->data[0] & (bit), \ } } - return (validread ? 0 : -1 ); + return (sr->s_reading_valid ? 0 : -1 ); } int @@ -502,7 +414,6 @@ ipmi_sensor_list(struct ipmi_intf *intf) } while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) { - int r = 0; uint8_t *rec; rec = ipmi_sdr_get_record(intf, header, itr); @@ -514,7 +425,7 @@ ipmi_sensor_list(struct ipmi_intf *intf) switch (header->type) { case SDR_RECORD_TYPE_FULL_SENSOR: case SDR_RECORD_TYPE_COMPACT_SENSOR: - r = ipmi_sensor_print_fc(intf, + ipmi_sensor_print_fc(intf, (struct sdr_record_common_sensor *) rec, @@ -781,9 +692,7 @@ static int ipmi_sensor_get_reading(struct ipmi_intf *intf, int argc, char **argv) { struct sdr_record_list *sdr; - struct ipmi_rs *rsp; int i, rc=0; - double val = 0.0; if (argc < 1 || strncmp(argv[0], "help", 4) == 0) { lprintf(LOG_NOTICE, "sensor reading ... [id]"); @@ -802,48 +711,34 @@ 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)) { + case SDR_RECORD_TYPE_COMPACT_SENSOR: + { + struct sensor_reading *sr; + struct sdr_record_common_sensor *sensor = sdr->record.common; + sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr->type, 3); + + if (sr == NULL) { + rc = -1; + continue; + } + + if (!sr->full) + continue; + + if (!sr->s_reading_valid) + continue; + + if (!sr->s_has_analog_value) { 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.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 (IS_READING_UNAVAILABLE(rsp->data[1])) { - continue; - } else if (IS_SCANNING_DISABLED(rsp->data[1])) { - continue; - } else if (rsp->data[0] > 0) { - /* convert RAW reading into units */ - val = sdr_convert_sensor_reading(sdr->record.full, rsp->data[0]); - } else { - val = 0.0; - } - if (csv_output) - printf("%s,%.*f\n", argv[i], - (val == (int)val) ? 0 : 3, val); + printf("%s,%s\n", argv[i], sr->s_a_str); else - printf("%-16s | %.*f\n", argv[i], - (val == (int)val) ? 0 : 3, val); + printf("%-16s | %s\n", argv[i], sr->s_a_str); break; - - case SDR_RECORD_TYPE_COMPACT_SENSOR: - break; + } default: continue; } diff --git a/ipmitool/src/plugins/bmc/bmc.c b/ipmitool/src/plugins/bmc/bmc.c index 9650cbe..0260980 100644 --- a/ipmitool/src/plugins/bmc/bmc.c +++ b/ipmitool/src/plugins/bmc/bmc.c @@ -81,6 +81,7 @@ ipmi_bmc_close(struct ipmi_intf *intf) close(intf->fd); intf->opened = 0; + intf->manufacturer_id = IPMI_OEM_UNKNOWN; intf->fd = -1; } @@ -111,6 +112,7 @@ ipmi_bmc_open(struct ipmi_intf *intf) sendrecv_fn = (method == BMC_PUTMSG_METHOD) ? ipmi_bmc_send_cmd_putmsg : ipmi_bmc_send_cmd_ioctl; + intf->manufacturer_id = ipmi_get_oem(intf); return (intf->fd); } diff --git a/ipmitool/src/plugins/free/free.c b/ipmitool/src/plugins/free/free.c index d1bb47a..f89925d 100644 --- a/ipmitool/src/plugins/free/free.c +++ b/ipmitool/src/plugins/free/free.c @@ -167,6 +167,7 @@ static int ipmi_free_open(struct ipmi_intf * intf) #endif intf->opened = 1; + intf->manufacturer_id = ipmi_get_oem(intf); return 0; cleanup: if (dev) { @@ -197,6 +198,7 @@ static void ipmi_free_close(struct ipmi_intf * intf) #endif } intf->opened = 0; + intf->manufacturer_id = IPMI_OEM_UNKNOWN; } static struct ipmi_rs * ipmi_free_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) diff --git a/ipmitool/src/plugins/imb/imb.c b/ipmitool/src/plugins/imb/imb.c index 2ebc492..cb97e81 100644 --- a/ipmitool/src/plugins/imb/imb.c +++ b/ipmitool/src/plugins/imb/imb.c @@ -63,6 +63,7 @@ static int ipmi_imb_open(struct ipmi_intf * intf) } intf->opened = 1; + intf->manufacturer_id = ipmi_get_oem(intf); return 0; } @@ -70,6 +71,7 @@ static int ipmi_imb_open(struct ipmi_intf * intf) static void ipmi_imb_close(struct ipmi_intf * intf) { intf->opened = 0; + intf->manufacturer_id = IPMI_OEM_UNKNOWN; } static struct ipmi_rs * ipmi_imb_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) diff --git a/ipmitool/src/plugins/lan/lan.c b/ipmitool/src/plugins/lan/lan.c index 5782843..9752985 100644 --- a/ipmitool/src/plugins/lan/lan.c +++ b/ipmitool/src/plugins/lan/lan.c @@ -1981,6 +1981,7 @@ ipmi_lan_close(struct ipmi_intf * intf) } intf->opened = 0; + intf->manufacturer_id = IPMI_OEM_UNKNOWN; intf = NULL; } @@ -2057,6 +2058,7 @@ ipmi_lan_open(struct ipmi_intf * intf) return -1; } + intf->manufacturer_id = ipmi_get_oem(intf); return intf->fd; } diff --git a/ipmitool/src/plugins/lanplus/lanplus.c b/ipmitool/src/plugins/lanplus/lanplus.c index e65db87..a90062f 100644 --- a/ipmitool/src/plugins/lanplus/lanplus.c +++ b/ipmitool/src/plugins/lanplus/lanplus.c @@ -3247,6 +3247,7 @@ ipmi_lanplus_close(struct ipmi_intf * intf) intf->session = NULL; intf->opened = 0; + intf->manufacturer_id = IPMI_OEM_UNKNOWN; intf = NULL; } @@ -3383,7 +3384,6 @@ ipmi_lanplus_open(struct ipmi_intf * intf) intf->opened = 1; - /* * * Make sure the BMC supports IPMI v2 / RMCP+ @@ -3441,6 +3441,7 @@ ipmi_lanplus_open(struct ipmi_intf * intf) if (rc < 0) goto fail; + intf->manufacturer_id = ipmi_get_oem(intf); return intf->fd; fail: diff --git a/ipmitool/src/plugins/lipmi/lipmi.c b/ipmitool/src/plugins/lipmi/lipmi.c index c9b950c..fa7845d 100644 --- a/ipmitool/src/plugins/lipmi/lipmi.c +++ b/ipmitool/src/plugins/lipmi/lipmi.c @@ -57,6 +57,7 @@ static int ipmi_lipmi_open(struct ipmi_intf * intf) return -1; } intf->opened = 1; + intf->manufacturer_id = ipmi_get_oem(intf); return intf->fd; } @@ -66,6 +67,7 @@ static void ipmi_lipmi_close(struct ipmi_intf * intf) close(intf->fd); intf->fd = -1; intf->opened = 0; + intf->manufacturer_id = IPMI_OEM_UNKNOWN; } static struct ipmi_rs * ipmi_lipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) diff --git a/ipmitool/src/plugins/open/open.c b/ipmitool/src/plugins/open/open.c index e40476c..1c06612 100644 --- a/ipmitool/src/plugins/open/open.c +++ b/ipmitool/src/plugins/open/open.c @@ -113,6 +113,7 @@ ipmi_openipmi_open(struct ipmi_intf * intf) intf->my_addr ); } + intf->manufacturer_id = ipmi_get_oem(intf); return intf->fd; } @@ -125,6 +126,7 @@ ipmi_openipmi_close(struct ipmi_intf * intf) } intf->opened = 0; + intf->manufacturer_id = IPMI_OEM_UNKNOWN; } static struct ipmi_rs *