Support for analog readings in discrete sensors on HP platforms. This was

implemented without an HP oem specific switch by modifying each interface
open routine to read and cache the OEM manufacturer (via the Get Device ID
command) immediately upon open and to reset the cached OEM manufacturer
id to unknown upon interface close.  The cached manufacturer value in the
interface is then be used at run time to implement the manufacturer
specific code.

A non threshold sensor has an analog value if it is defined as having
analog units and it has either valid percentage or modifier units
defined and the manufacturer is IPMI_OEM_HP.   The determination of
whether or not a given sensor has an analog value is contained in a
single function (sdr_sensor_has_analog_reading).

This patch also encapsulates the reading of all sensor values in
ipmitool into a a single ipmitool function, ipmi_sdr_read_sensor_value.
The prior independent sensor reading code paths have been collapsed into
one sensor reading code path.   This encapsulation enabled consistent
validation of all data returned by the IPMI get sensor reading command.
In implementing a single sensor value read function, I resolved the
inconsistencies between what the "sensor" and "sdr" arguments displayed
and  I also resolved numerous cases where uninitialized information in
the IPMI reply from get sensor reading was being interpreted and
incorrectly displayed.
This commit is contained in:
Jim Mankovich 2012-07-10 16:01:09 +00:00
parent 31cb04f155
commit 5d960089c9
13 changed files with 453 additions and 448 deletions

View File

@ -165,6 +165,7 @@ struct ipmi_intf {
int opened; int opened;
int abort; int abort;
int noanswer; int noanswer;
IPMI_OEM manufacturer_id;
struct ipmi_session * session; struct ipmi_session * session;
struct ipmi_oem_handle * oem; struct ipmi_oem_handle * oem;

View File

@ -820,6 +820,22 @@ static const char *sensor_type_desc[] __attribute__ ((unused)) = {
"Management Subsystem Health", "Battery","Session Audit", "Management Subsystem Health", "Battery","Session Audit",
"Version Change","FRU State" }; "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, struct ipmi_sdr_iterator *ipmi_sdr_start(struct ipmi_intf *intf,
int use_builtin); int use_builtin);
struct sdr_get_rs *ipmi_sdr_get_next_header(struct ipmi_intf *intf, struct sdr_get_rs *ipmi_sdr_get_next_header(struct ipmi_intf *intf,
@ -841,16 +857,17 @@ void ipmi_sdr_print_sensor_hysteresis(struct sdr_record_common_sensor *sensor,
const char *hdrstr); const char *hdrstr);
const char *ipmi_sdr_get_unit_string(uint8_t pct, uint8_t type, const char *ipmi_sdr_get_unit_string(uint8_t pct, uint8_t type,
uint8_t base, uint8_t modifier); uint8_t base, uint8_t modifier);
const char *ipmi_sdr_get_thresh_status(struct ipmi_rs *rsp, struct sensor_reading *
int validread, const char *invalidstr); 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); const char *ipmi_sdr_get_status(int, const char *, uint8_t stat);
double sdr_convert_sensor_tolerance(struct sdr_record_full_sensor *sensor, double sdr_convert_sensor_tolerance(struct sdr_record_full_sensor *sensor,
uint8_t val); uint8_t val);
double sdr_convert_sensor_reading(struct sdr_record_full_sensor *sensor, double sdr_convert_sensor_reading(struct sdr_record_full_sensor *sensor,
uint8_t val); 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, double sdr_convert_sensor_hysterisis(struct sdr_record_full_sensor *sensor,
uint8_t val); uint8_t val);
uint8_t sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor *sensor, 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, void ipmi_sdr_print_discrete_state(const char *desc, uint8_t sensor_type,
uint8_t event_type, uint8_t state1, uint8_t event_type, uint8_t state1,
uint8_t state2); 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 sensor_type, uint8_t event_type,
uint8_t state1, uint8_t state2); uint8_t state1, uint8_t state2);
int ipmi_sdr_print_sensor_event_status(struct ipmi_intf *intf, int ipmi_sdr_print_sensor_event_status(struct ipmi_intf *intf,

View File

@ -227,8 +227,8 @@ ipmi_event_find_offset(uint8_t code,
static void static void
print_sensor_states(uint8_t sensor_type, uint8_t event_type) print_sensor_states(uint8_t sensor_type, uint8_t event_type)
{ {
printf("Sensor States: \n "); ipmi_sdr_print_discrete_state_mini(
ipmi_sdr_print_discrete_state_mini("\n ", sensor_type, "Sensor States: \n ", "\n ", sensor_type,
event_type, 0xff, 0xff); event_type, 0xff, 0xff);
printf("\n"); printf("\n");
} }

View File

@ -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. * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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; break;
} }
return unitstr; 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 static int
sdr_convert_analog_reading(struct ipmi_intf *intf, sdr_sensor_has_analog_reading(struct ipmi_intf *intf,
struct sdr_record_full_sensor *full, uint8_t read, struct sensor_reading *sr)
int *convert_success)
{ {
/* Compact sensors can't return analog values so we return zero */ /* Compact sensors can't return analog values so we false */
if (!full) { if (!sr->full) {
return 0.0; return 0;
} }
/* /*
* Only Full Threshold sensors with analog readings can be converted. * Per the IPMI Specification:
* If this not the case, we return zero * 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) && if ( UNITS_ARE_DISCRETE(&sr->full->cmn) ) {
!UNITS_ARE_DISCRETE(&full->cmn)) ) { return 0;/* Sensor specified as not having Analog Units */
return 0.0; }
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 * If sensor has linearization, then we should be able to update the
* reading factors and if we cannot fail the conversion. * reading factors and if we cannot fail the conversion.
*/ */
if (full->linearization >= SDR_SENSOR_L_NONLINEAR && if (sr->full->linearization >= SDR_SENSOR_L_NONLINEAR &&
full->linearization <= 0x7F) { sr->full->linearization <= 0x7F) {
if (ipmi_sensor_get_sensor_reading_factors(intf, full, read) < 0){ if (ipmi_sensor_get_sensor_reading_factors(intf, sr->full, sr->s_reading) < 0){
*convert_success = 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 /* 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 * ns = not specified
*/ */
const char * 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; uint8_t stat;
if (!validread) { if (!sr->s_reading_valid) {
return invalidstr; return invalidstr;
} }
stat = rsp->data[2]; stat = sr->s_data2;
if (stat & SDR_SENSOR_STAT_LO_NR) { if (stat & SDR_SENSOR_STAT_LO_NR) {
if (verbose) if (verbose)
return "Lower Non-Recoverable"; 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)); sensor_num, val2str(rsp->ccode, completion_code_vals));
return -1; return -1;
} }
/* There is an assumption here that data_len >= 1 */
if (IS_READING_UNAVAILABLE(rsp->data[0])) { if (IS_READING_UNAVAILABLE(rsp->data[0])) {
printf(" Event Status : Unavailable\n"); printf(" Event Status : Unavailable\n");
return 0; return 0;
@ -1315,39 +1337,152 @@ print_sensor_min_max(struct sdr_record_full_sensor *full)
/* print_csv_discrete - print csv formatted discrete sensor /* print_csv_discrete - print csv formatted discrete sensor
* *
* @rsp: response from Get Sensor Reading comand
* @sensor: common sensor structure * @sensor: common sensor structure
* @validread: validity of get sensor read command data * @sr: sensor reading
* *
* returns void * returns void
*/ */
static void static void
print_csv_discrete(struct ipmi_rs *rsp, print_csv_discrete(struct sdr_record_common_sensor *sensor,
struct sdr_record_common_sensor *sensor, const struct sensor_reading *sr)
int validread)
{ {
printf("%02Xh,", sensor->keys.sensor_num); 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);
return;
}
if (validread == 0 || rsp->ccode != 0) { if (sr->s_has_analog_value) { /* Sensor has an analog value */
printf("ns,%d.%d,No Reading", printf("%s,%s,", sr->s_a_str, sr->s_a_units);
sensor->entity.id, } else { /* Sensor has a discrete value */
sensor->entity.instance); printf("%02Xh,", sensor->keys.sensor_num);
} 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,", printf("ok,%d.%d,",
sensor->entity.id, sensor->entity.id,
sensor->entity.instance); sensor->entity.instance);
ipmi_sdr_print_discrete_state_mini(", ", ipmi_sdr_print_discrete_state_mini(NULL, ", ",
sensor->sensor.type, sensor->sensor.type,
sensor->event_type, sensor->event_type,
rsp->data[2], sr->s_data2,
rsp->data[3]); 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 /* 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, struct sdr_record_common_sensor *sensor,
uint8_t sdr_record_type) uint8_t sdr_record_type)
{ {
const char *unitstr = NULL; char sval[16];
char sval[16], desc[17]; int i = 0;
int i = 0, validread = 1;
double val = 0.0;
struct ipmi_rs *rsp;
uint8_t target, lun, channel; uint8_t target, lun, channel;
struct sdr_record_full_sensor *full = NULL; struct sensor_reading *sr;
struct sdr_record_compact_sensor *compact = NULL;
if (sensor == NULL)
return -1;
switch (sdr_record_type) { sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 2);
case (SDR_RECORD_TYPE_FULL_SENSOR):
full = (struct sdr_record_full_sensor *)sensor; if (sr == NULL)
break;
case SDR_RECORD_TYPE_COMPACT_SENSOR:
compact = (struct sdr_record_compact_sensor *)sensor;
break;
default:
return -1; return -1;
}
target = sensor->keys.owner_id; target = sensor->keys.owner_id;
lun = sensor->keys.lun; lun = sensor->keys.lun;
channel = sensor->keys.channel; 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 * CSV OUTPUT
*/ */
@ -1454,22 +1522,24 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
/* /*
* print sensor name, reading, unit, state * print sensor name, reading, unit, state
*/ */
printf("%s,", desc); printf("%s,", sr->s_id);
if (!IS_THRESHOLD_SENSOR(sensor)) { if (!IS_THRESHOLD_SENSOR(sensor)) {
/* Discrete/Non-Threshold */ /* Discrete/Non-Threshold */
print_csv_discrete(rsp, sensor, validread); print_csv_discrete(sensor, sr);
printf("\n"); printf("\n");
} }
else { else {
/* Threshold Analog & Discrete*/ /* Threshold Analog & Discrete*/
if (validread) { if (sr->s_reading_valid) {
if (full && !UNITS_ARE_DISCRETE(&full->cmn)) { if (sr->s_has_analog_value) {
/* Analog/Threshold */ /* Analog/Threshold */
printf("%.*f,", (val == (int) val) ? 0 : 3, val); printf("%.*f,", (sr->s_a_val ==
printf("%s,%s", unitstr, (int) sr->s_a_val) ? 0 : 3,
ipmi_sdr_get_thresh_status(rsp, validread, "ns")); sr->s_a_val);
printf("%s,%s", sr->s_a_units,
ipmi_sdr_get_thresh_status(sr, "ns"));
} else { /* Discrete/Threshold */ } else { /* Discrete/Threshold */
print_csv_discrete(rsp, sensor, validread); print_csv_discrete(sensor, sr);
} }
} else { } else {
printf(",,ns"); printf(",,ns");
@ -1482,35 +1552,35 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
ipmi_sdr_get_sensor_type_desc(sensor->sensor. ipmi_sdr_get_sensor_type_desc(sensor->sensor.
type)); type));
if (full) { if (sr->full) {
SENSOR_PRINT_CSV(full, full->analog_flag.nominal_read, SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.nominal_read,
full->nominal_read); sr->full->nominal_read);
SENSOR_PRINT_CSV(full, full->analog_flag.normal_min, SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.normal_min,
full->normal_min); sr->full->normal_min);
SENSOR_PRINT_CSV(full, full->analog_flag.normal_max, SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.normal_max,
full->normal_max); sr->full->normal_max);
SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.unr, SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.unr,
full->threshold.upper.non_recover); sr->full->threshold.upper.non_recover);
SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.ucr, SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.ucr,
full->threshold.upper.critical); sr->full->threshold.upper.critical);
SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.unc, SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.unc,
full->threshold.upper.non_critical); sr->full->threshold.upper.non_critical);
SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.lnr, SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.lnr,
full->threshold.lower.non_recover); sr->full->threshold.lower.non_recover);
SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.lcr, SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.lcr,
full->threshold.lower.critical); sr->full->threshold.lower.critical);
SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.lnc, SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.lnc,
full->threshold.lower.non_critical); sr->full->threshold.lower.non_critical);
if (UNITS_ARE_DISCRETE(&full->cmn)) { if (UNITS_ARE_DISCRETE(sensor)) {
printf("0x%02X,0x%02X", full->sensor_min, full->sensor_max); printf("0x%02X,0x%02X", sr->full->sensor_min, sr->full->sensor_max);
} }
else { else {
printf("%.3f,%.3f", printf("%.3f,%.3f",
sdr_convert_sensor_reading(full, sdr_convert_sensor_reading(sr->full,
full->sensor_min), sr->full->sensor_min),
sdr_convert_sensor_reading(full, sdr_convert_sensor_reading(sr->full,
full->sensor_max)); sr->full->sensor_max));
} }
} else { } else {
printf(",,,,,,,,,,"); printf(",,,,,,,,,,");
@ -1530,48 +1600,35 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
/* /*
* print sensor name, reading, state * print sensor name, reading, state
*/ */
printf("%-16s | ", desc); printf("%-16s | ", sr->s_id);
i = 0;
memset(sval, 0, sizeof (sval)); memset(sval, 0, sizeof (sval));
if (validread) { if (sr->s_reading_valid) {
if (IS_THRESHOLD_SENSOR(sensor)) { if( sr->s_has_analog_value ) {
/* Threshold Analog & Discrete */ snprintf(sval, sizeof (sval), "%s %s",
if( full && (!UNITS_ARE_DISCRETE(sensor)) ) { sr->s_a_str,
i += snprintf(sval, sizeof (sval), "%.*f %s", sr->s_a_units);
(val == (int) val) ? 0 : 2, val,
unitstr);
} else /* Discrete */ } else /* Discrete */
/* snprintf(sval, sizeof(sval),
* N.B. data[0] is supposed to be ignored if not "0x%02x", sr->s_reading);
* 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 { else if (sr->s_scanning_disabled)
/* Discrete */ snprintf(sval, sizeof (sval), sr->full ? "disabled" : "Not Readable");
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 else
i += snprintf(sval, sizeof (sval), full ? "no reading " : "Not Readable "); snprintf(sval, sizeof (sval), sr->full ? "no reading" : "Not Readable");
printf("%s", sval); printf("%s", sval);
i--; for (i = strlen(sval); i <= sizeof (sval); i++)
for (; i < sizeof (sval); i++)
printf(" "); printf(" ");
printf(" | "); printf(" | ");
if (IS_THRESHOLD_SENSOR(sensor)) { 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 { else {
printf("%s", validread ? "ok" : "ns"); printf("%s", sr->s_reading_valid ? "ok" : "ns");
} }
printf("\n"); printf("\n");
@ -1582,44 +1639,48 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
* print sensor name, number, state, entity, reading * print sensor name, number, state, entity, reading
*/ */
printf("%-16s | %02Xh | ", printf("%-16s | %02Xh | ",
desc, sensor->keys.sensor_num); sr->s_id, sensor->keys.sensor_num);
if (IS_THRESHOLD_SENSOR(sensor)) { if (IS_THRESHOLD_SENSOR(sensor)) {
/* Threshold Analog & Discrete */ /* Threshold Analog & Discrete */
printf("%-3s | %2d.%1d | ", 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); sensor->entity.id, sensor->entity.instance);
} }
else { else {
/* Discrete */ /* Non Threshold Analog & Discrete */
printf("%-3s | %2d.%1d | ", printf("%-3s | %2d.%1d | ",
(validread ? "ok" : "ns"), (sr->s_reading_valid ? "ok" : "ns"),
sensor->entity.id, sensor->entity.instance); sensor->entity.id, sensor->entity.instance);
} }
i = 0;
memset(sval, 0, sizeof (sval)); memset(sval, 0, sizeof (sval));
if (validread) { if (sr->s_reading_valid) {
if (IS_THRESHOLD_SENSOR(sensor) && if (IS_THRESHOLD_SENSOR(sensor) &&
(full && !UNITS_ARE_DISCRETE(sensor)) ) { sr->s_has_analog_value ) {
/* Threshold Analog */ /* Threshold Analog */
i += snprintf(sval, sizeof (sval), "%.*f %s", snprintf(sval, sizeof (sval), "%s %s",
(val == (int) val) ? 0 : 2, val, sr->s_a_str,
unitstr); sr->s_a_units);
} else { } else {
/* Discrete & Threshold/Discrete */ /* Analog & Discrete & Threshold/Discrete */
ipmi_sdr_print_discrete_state_mini(", ", 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->sensor.type,
sensor->event_type, sensor->event_type,
rsp->data[2], sr->s_data2,
rsp->data[3]); sr->s_data3);
} }
} }
else if (rsp && (rsp->ccode == 0) && IS_SCANNING_DISABLED(rsp->data[1])) else if (sr->s_scanning_disabled)
i += snprintf(sval, sizeof (sval), "Disabled"); snprintf(sval, sizeof (sval), "Disabled");
else else
i += snprintf(sval, sizeof (sval), "No Reading"); snprintf(sval, sizeof (sval), "No Reading");
printf("%s\n", sval); printf("%s\n", sval);
return 0; /* done */ return 0; /* done */
@ -1629,7 +1690,7 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
*/ */
printf("Sensor ID : %s (0x%x)\n", 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", printf(" Entity ID : %d.%d (%s)\n",
sensor->entity.id, sensor->entity.instance, sensor->entity.id, sensor->entity.instance,
val2str(sensor->entity.id, entity_id_vals)); 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", lprintf(LOG_DEBUG, " Event Type Code : 0x%02x",
sensor->event_type); sensor->event_type);
if (compact && validread && verbose > 1)
printbuf(rsp->data, rsp->data_len, "COMPACT SENSOR");
printf(" Sensor Reading : "); printf(" Sensor Reading : ");
if (validread) if (sr->s_reading_valid) {
printf("%xh\n", rsp ? rsp->data[0] : 0); if (sr->s_has_analog_value) { /* Sensor has an analog value */
else if (rsp && (rsp->ccode == 0) && IS_SCANNING_DISABLED(rsp->data[1])) 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"); printf("Disabled\n");
else else
printf("Not Reading\n"); printf("Not Reading\n");
@ -1671,8 +1734,8 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
ipmi_sdr_print_discrete_state("States Asserted", ipmi_sdr_print_discrete_state("States Asserted",
sensor->sensor.type, sensor->sensor.type,
sensor->event_type, sensor->event_type,
rsp ? rsp->data[2] : 0, sr->s_data2,
rsp ? rsp->data[3] : 0); sr->s_data3);
ipmi_sdr_print_sensor_mask(&sensor->mask, sensor->sensor.type, ipmi_sdr_print_sensor_mask(&sensor->mask, sensor->sensor.type,
sensor->event_type, DISCRETE_SENSOR); sensor->event_type, DISCRETE_SENSOR);
ipmi_sdr_print_sensor_event_status(intf, ipmi_sdr_print_sensor_event_status(intf,
@ -1690,7 +1753,7 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
target, target,
lun, channel); lun, channel);
printf(" OEM : %X\n", printf(" OEM : %X\n",
full ? full->oem : compact->oem); sr->full ? sr->full->oem : sr->compact->oem);
printf("\n"); printf("\n");
return 0; /* done */ 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)); ipmi_sdr_get_sensor_type_desc(sensor->sensor.type));
printf(" Sensor Reading : "); printf(" Sensor Reading : ");
if (validread) { if (sr->s_reading_valid) {
if (full) { if (sr->full) {
uint16_t raw_tol = __TO_TOL(full->mtol); uint16_t raw_tol = __TO_TOL(sr->full->mtol);
if (UNITS_ARE_DISCRETE(&full->cmn)) { if (UNITS_ARE_DISCRETE(sensor)) {
printf("0x%02X (+/- 0x%02X) %s\n", rsp->data[0], raw_tol, unitstr); printf("0x%02X (+/- 0x%02X) %s\n",
sr->s_reading, raw_tol, sr->s_a_units);
} }
else { 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", printf("%.*f (+/- %.*f) %s\n",
(val == (int) val) ? 0 : 3, (sr->s_a_val == (int) sr->s_a_val) ? 0 : 3,
val, (tol == (int) tol) ? 0 : 3, tol, unitstr); sr->s_a_val, (tol == (int) tol) ? 0 :
3, tol, sr->s_a_units);
} }
} else { } 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"); printf("Disabled\n");
else else
printf("No Reading\n"); printf("No Reading\n");
printf(" Status : %s\n", printf(" Status : %s\n",
ipmi_sdr_get_thresh_status(rsp, validread, "Not Available")); ipmi_sdr_get_thresh_status(sr, "Not Available"));
if(full) { if(sr->full) {
SENSOR_PRINT_NORMAL(full, "Nominal Reading", nominal_read); SENSOR_PRINT_NORMAL(sr->full, "Nominal Reading", nominal_read);
SENSOR_PRINT_NORMAL(full, "Normal Minimum", normal_min); SENSOR_PRINT_NORMAL(sr->full, "Normal Minimum", normal_min);
SENSOR_PRINT_NORMAL(full, "Normal Maximum", normal_max); SENSOR_PRINT_NORMAL(sr->full, "Normal Maximum", normal_max);
SENSOR_PRINT_THRESH(full, "Upper non-recoverable", upper.non_recover, unr); SENSOR_PRINT_THRESH(sr->full, "Upper non-recoverable", upper.non_recover, unr);
SENSOR_PRINT_THRESH(full, "Upper critical", upper.critical, ucr); SENSOR_PRINT_THRESH(sr->full, "Upper critical", upper.critical, ucr);
SENSOR_PRINT_THRESH(full, "Upper non-critical", upper.non_critical, unc); SENSOR_PRINT_THRESH(sr->full, "Upper non-critical", upper.non_critical, unc);
SENSOR_PRINT_THRESH(full, "Lower non-recoverable", lower.non_recover, lnr); SENSOR_PRINT_THRESH(sr->full, "Lower non-recoverable", lower.non_recover, lnr);
SENSOR_PRINT_THRESH(full, "Lower critical", lower.critical, lcr); SENSOR_PRINT_THRESH(sr->full, "Lower critical", lower.critical, lcr);
SENSOR_PRINT_THRESH(full, "Lower non-critical", lower.non_critical, lnc); SENSOR_PRINT_THRESH(sr->full, "Lower non-critical", lower.non_critical, lnc);
} }
ipmi_sdr_print_sensor_hysteresis(sensor, full, ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
full->threshold.hysteresis.positive, "Positive Hysteresis"); sr->full->threshold.hysteresis.positive, "Positive Hysteresis");
ipmi_sdr_print_sensor_hysteresis(sensor, full, ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
full->threshold.hysteresis.negative, "Negative Hysteresis"); sr->full->threshold.hysteresis.negative, "Negative Hysteresis");
print_sensor_min_max(full); print_sensor_min_max(sr->full);
printf(" Event Message Control : "); printf(" Event Message Control : ");
switch (sensor->sensor.capabilities.event_msg) { 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 /* ipmi_sdr_print_discrete_state_mini - print list of asserted states
* for a discrete sensor * for a discrete sensor
* *
* @header : header string if necessary
* @separator : field separator string
* @sensor_type : sensor type code * @sensor_type : sensor type code
* @event_type : event type code * @event_type : event type code
* @state : mask of asserted states * @state : mask of asserted states
@ -1873,7 +1940,7 @@ get_offset(uint8_t x)
* no meaningful return value * no meaningful return value
*/ */
void 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 sensor_type, uint8_t event_type,
uint8_t state1, uint8_t state2) uint8_t state1, uint8_t state2)
{ {
@ -1892,6 +1959,9 @@ ipmi_sdr_print_discrete_state_mini(const char *separator,
typ = event_type; typ = event_type;
} }
if (header)
printf("%s", header);
for (; evt->type != NULL; evt++) { for (; evt->type != NULL; evt++) {
if ((evt->code != typ) || if ((evt->code != typ) ||
(evt->data != 0xFF)) (evt->data != 0xFF))

View File

@ -281,6 +281,15 @@ ipmi_get_oem(struct ipmi_intf * intf)
return IPMI_OEM_UNKNOWN; 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)); memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP; req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = BMC_GET_DEVICE_ID; 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; 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)); IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id));
return IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id); return IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id);

View File

@ -143,55 +143,13 @@ ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf,
struct sdr_record_common_sensor *sensor, struct sdr_record_common_sensor *sensor,
uint8_t sdr_record_type) uint8_t sdr_record_type)
{ {
char id[17]; const char *id;
char *unitstr = "discrete"; struct sensor_reading *sr;
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) sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3);
if (sr == NULL) {
return -1; 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) { if (csv_output) {
@ -201,14 +159,20 @@ ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf,
/* output format /* output format
* id value units status thresholds.... * id value units status thresholds....
*/ */
printf("%-16s ", id); printf("%-16s ", sr->s_id);
if (validread) { 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", printf("| 0x%-8x | %-10s | 0x%02x%02x",
val, sr->s_reading, "discrete",
unitstr, rsp->data[2], rsp->data[3]); sr->s_data2, sr->s_data3);
}
} else { } else {
printf("| %-10s | %-10s | %-6s", printf("| %-10s | %-10s | %-6s",
"na", unitstr, "na"); "na", "discrete", "na");
} }
printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s", printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
"na", "na", "na", "na", "na", "na"); "na", "na", "na", "na", "na", "na");
@ -216,27 +180,22 @@ ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf,
printf("\n"); printf("\n");
} else { } else {
printf("Sensor ID : %s (0x%x)\n", 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", printf(" Entity ID : %d.%d\n",
sensor->entity.id, sensor->entity.instance); sensor->entity.id, sensor->entity.instance);
printf(" Sensor Type (Discrete): %s\n", printf(" Sensor Type (Discrete): %s\n",
ipmi_sdr_get_sensor_type_desc(sensor->sensor. ipmi_sdr_get_sensor_type_desc(sensor->sensor.
type)); 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", ipmi_sdr_print_discrete_state("States Asserted",
sensor->sensor.type, sensor->sensor.type,
sensor->event_type, sensor->event_type,
rsp->data[2], sr->s_data2,
rsp->data[3]); sr->s_data3);
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"); printf("\n");
} else { } else {
printf(" Unable to read sensor: Device Not Present\n\n"); 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 static void
@ -272,100 +231,50 @@ ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf,
struct sdr_record_common_sensor *sensor, struct sdr_record_common_sensor *sensor,
uint8_t sdr_record_type) uint8_t sdr_record_type)
{ {
const char *unitstr = NULL; int thresh_available = 1;
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*/
struct ipmi_rs *rsp; struct ipmi_rs *rsp;
const char *thresh_status = ""; struct sensor_reading *sr;
struct sdr_record_full_sensor *full = NULL;
struct sdr_record_compact_sensor *compact = NULL;
if (sensor == NULL) sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3);
return -1;
switch (sdr_record_type) { if (sr == NULL) {
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; return -1;
} }
memset(id, 0, sizeof (id)); const char *thresh_status = ipmi_sdr_get_thresh_status(sr, "ns");
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 {
/* 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 * Get sensor thresholds
*/ */
rsp = ipmi_sdr_get_sensor_thresholds(intf, sensor->keys.sensor_num, rsp = ipmi_sdr_get_sensor_thresholds(intf,
sensor->keys.owner_id, sensor->keys.lun, sensor->keys.channel); sensor->keys.sensor_num, sensor->keys.owner_id,
if ((rsp == NULL) || (rsp->ccode > 0)) sensor->keys.lun, sensor->keys.channel);
if ((rsp == NULL) || (rsp->ccode > 0) || (rsp->data_len == 0))
thresh_available = 0; thresh_available = 0;
if (csv_output) { if (csv_output) {
/* NOT IPMLEMENTED */ /* NOT IMPLEMENTED */
} else { } else {
if (verbose == 0) { if (verbose == 0) {
/* output format /* output format
* id value units status thresholds.... * id value units status thresholds....
*/ */
printf("%-16s ", id); printf("%-16s ", sr->s_id);
if (validread) { if (sr->s_reading_valid) {
if (full && !UNITS_ARE_DISCRETE(sensor)) if (sr->s_has_analog_value)
printf("| %-10.3f | %-10s | %-6s", printf("| %-10.3f | %-10s | %-6s",
val, unitstr, thresh_status); sr->s_a_val, sr->s_a_units, thresh_status);
else else
printf("| 0x%-8x | %-10s | %-6s", printf("| 0x%-8x | %-10s | %-6s",
get_sens_read, unitstr, thresh_status); sr->s_reading, sr->s_a_units, thresh_status);
} else { } else {
printf("| %-10s | %-10s | %-6s", 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) { \ #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"); \ rsp->data[(dataidx)], "| ", "%-10.3f", "0x-8x", "%-10s"); \
} }
PTS(LOWER_NON_RECOV_SPECIFIED, 3); PTS(LOWER_NON_RECOV_SPECIFIED, 3);
@ -384,7 +293,7 @@ ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf,
printf("\n"); printf("\n");
} else { } else {
printf("Sensor ID : %s (0x%x)\n", 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", printf(" Entity ID : %d.%d\n",
sensor->entity.id, sensor->entity.instance); sensor->entity.id, sensor->entity.instance);
@ -394,32 +303,35 @@ ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf,
type)); type));
printf(" Sensor Reading : "); printf(" Sensor Reading : ");
if (validread) { if (sr->s_reading_valid) {
if (full) { if (sr->full) {
uint16_t raw_tol = __TO_TOL(full->mtol); uint16_t raw_tol = __TO_TOL(sr->full->mtol);
if (!UNITS_ARE_DISCRETE(sensor)) { if (sr->s_has_analog_value) {
double tol = double tol =
sdr_convert_sensor_tolerance(full, sdr_convert_sensor_tolerance(sr->full,
raw_tol); raw_tol);
printf("%.*f (+/- %.*f) %s\n", 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, (tol == (int) tol) ? 0 : 3, tol,
unitstr); sr->s_a_units);
} else { } else {
printf("0x%x (+/- 0x%x) %s\n", printf("0x%x (+/- 0x%x) %s\n",
get_sens_read, sr->s_reading,
raw_tol, raw_tol,
unitstr); sr->s_a_units);
} }
} else { } 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); printf(" Status : %s\n", thresh_status);
if (thresh_available) { if (thresh_available) {
if (full) { if (sr->full) {
#define PTS(bit, dataidx, str) { \ #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)], \ rsp->data[(dataidx)], \
(str), "%.3f\n", "0x%x\n", "%s\n"); \ (str), "%.3f\n", "0x%x\n", "%s\n"); \
} }
@ -433,14 +345,14 @@ print_thresh_setting(full, rsp->data[0] & (bit), \
#undef PTS #undef PTS
} }
ipmi_sdr_print_sensor_hysteresis(sensor, full, ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
full ? full->threshold.hysteresis.positive : sr->full ? sr->full->threshold.hysteresis.positive :
compact->threshold.hysteresis.positive, sr->compact->threshold.hysteresis.positive,
"Positive Hysteresis"); "Positive Hysteresis");
ipmi_sdr_print_sensor_hysteresis(sensor, full, ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
full ? full->threshold.hysteresis.negative : sr->full ? sr->full->threshold.hysteresis.negative :
compact->threshold.hysteresis.negative, sr->compact->threshold.hysteresis.negative,
"Negative Hysteresis"); "Negative Hysteresis");
} else { } else {
printf(" Sensor Threshold Settings not available\n"); 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 int
@ -502,7 +414,6 @@ ipmi_sensor_list(struct ipmi_intf *intf)
} }
while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) { while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) {
int r = 0;
uint8_t *rec; uint8_t *rec;
rec = ipmi_sdr_get_record(intf, header, itr); rec = ipmi_sdr_get_record(intf, header, itr);
@ -514,7 +425,7 @@ ipmi_sensor_list(struct ipmi_intf *intf)
switch (header->type) { switch (header->type) {
case SDR_RECORD_TYPE_FULL_SENSOR: case SDR_RECORD_TYPE_FULL_SENSOR:
case SDR_RECORD_TYPE_COMPACT_SENSOR: case SDR_RECORD_TYPE_COMPACT_SENSOR:
r = ipmi_sensor_print_fc(intf, ipmi_sensor_print_fc(intf,
(struct (struct
sdr_record_common_sensor *) sdr_record_common_sensor *)
rec, rec,
@ -781,9 +692,7 @@ static int
ipmi_sensor_get_reading(struct ipmi_intf *intf, int argc, char **argv) ipmi_sensor_get_reading(struct ipmi_intf *intf, int argc, char **argv)
{ {
struct sdr_record_list *sdr; struct sdr_record_list *sdr;
struct ipmi_rs *rsp;
int i, rc=0; int i, rc=0;
double val = 0.0;
if (argc < 1 || strncmp(argv[0], "help", 4) == 0) { if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
lprintf(LOG_NOTICE, "sensor reading <id> ... [id]"); lprintf(LOG_NOTICE, "sensor reading <id> ... [id]");
@ -802,48 +711,34 @@ ipmi_sensor_get_reading(struct ipmi_intf *intf, int argc, char **argv)
switch (sdr->type) { switch (sdr->type) {
case SDR_RECORD_TYPE_FULL_SENSOR: case SDR_RECORD_TYPE_FULL_SENSOR:
/* Only Threshold can return an analog reading */ case SDR_RECORD_TYPE_COMPACT_SENSOR:
if (!IS_THRESHOLD_SENSOR(sdr->record.common)) { {
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]); lprintf(LOG_ERR, "Sensor \"%s\" is a discrete sensor!", argv[i]);
continue; 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) if (csv_output)
printf("%s,%.*f\n", argv[i], printf("%s,%s\n", argv[i], sr->s_a_str);
(val == (int)val) ? 0 : 3, val);
else else
printf("%-16s | %.*f\n", argv[i], printf("%-16s | %s\n", argv[i], sr->s_a_str);
(val == (int)val) ? 0 : 3, val);
break; break;
}
case SDR_RECORD_TYPE_COMPACT_SENSOR:
break;
default: default:
continue; continue;
} }

View File

@ -81,6 +81,7 @@ ipmi_bmc_close(struct ipmi_intf *intf)
close(intf->fd); close(intf->fd);
intf->opened = 0; intf->opened = 0;
intf->manufacturer_id = IPMI_OEM_UNKNOWN;
intf->fd = -1; intf->fd = -1;
} }
@ -111,6 +112,7 @@ ipmi_bmc_open(struct ipmi_intf *intf)
sendrecv_fn = (method == BMC_PUTMSG_METHOD) ? sendrecv_fn = (method == BMC_PUTMSG_METHOD) ?
ipmi_bmc_send_cmd_putmsg : ipmi_bmc_send_cmd_ioctl; ipmi_bmc_send_cmd_putmsg : ipmi_bmc_send_cmd_ioctl;
intf->manufacturer_id = ipmi_get_oem(intf);
return (intf->fd); return (intf->fd);
} }

View File

@ -167,6 +167,7 @@ static int ipmi_free_open(struct ipmi_intf * intf)
#endif #endif
intf->opened = 1; intf->opened = 1;
intf->manufacturer_id = ipmi_get_oem(intf);
return 0; return 0;
cleanup: cleanup:
if (dev) { if (dev) {
@ -197,6 +198,7 @@ static void ipmi_free_close(struct ipmi_intf * intf)
#endif #endif
} }
intf->opened = 0; 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) static struct ipmi_rs * ipmi_free_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)

View File

@ -63,6 +63,7 @@ static int ipmi_imb_open(struct ipmi_intf * intf)
} }
intf->opened = 1; intf->opened = 1;
intf->manufacturer_id = ipmi_get_oem(intf);
return 0; return 0;
} }
@ -70,6 +71,7 @@ static int ipmi_imb_open(struct ipmi_intf * intf)
static void ipmi_imb_close(struct ipmi_intf * intf) static void ipmi_imb_close(struct ipmi_intf * intf)
{ {
intf->opened = 0; 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) static struct ipmi_rs * ipmi_imb_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)

View File

@ -1981,6 +1981,7 @@ ipmi_lan_close(struct ipmi_intf * intf)
} }
intf->opened = 0; intf->opened = 0;
intf->manufacturer_id = IPMI_OEM_UNKNOWN;
intf = NULL; intf = NULL;
} }
@ -2057,6 +2058,7 @@ ipmi_lan_open(struct ipmi_intf * intf)
return -1; return -1;
} }
intf->manufacturer_id = ipmi_get_oem(intf);
return intf->fd; return intf->fd;
} }

View File

@ -3247,6 +3247,7 @@ ipmi_lanplus_close(struct ipmi_intf * intf)
intf->session = NULL; intf->session = NULL;
intf->opened = 0; intf->opened = 0;
intf->manufacturer_id = IPMI_OEM_UNKNOWN;
intf = NULL; intf = NULL;
} }
@ -3383,7 +3384,6 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
intf->opened = 1; intf->opened = 1;
/* /*
* *
* Make sure the BMC supports IPMI v2 / RMCP+ * Make sure the BMC supports IPMI v2 / RMCP+
@ -3441,6 +3441,7 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
if (rc < 0) if (rc < 0)
goto fail; goto fail;
intf->manufacturer_id = ipmi_get_oem(intf);
return intf->fd; return intf->fd;
fail: fail:

View File

@ -57,6 +57,7 @@ static int ipmi_lipmi_open(struct ipmi_intf * intf)
return -1; return -1;
} }
intf->opened = 1; intf->opened = 1;
intf->manufacturer_id = ipmi_get_oem(intf);
return intf->fd; return intf->fd;
} }
@ -66,6 +67,7 @@ static void ipmi_lipmi_close(struct ipmi_intf * intf)
close(intf->fd); close(intf->fd);
intf->fd = -1; intf->fd = -1;
intf->opened = 0; 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) static struct ipmi_rs * ipmi_lipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)

View File

@ -113,6 +113,7 @@ ipmi_openipmi_open(struct ipmi_intf * intf)
intf->my_addr ); intf->my_addr );
} }
intf->manufacturer_id = ipmi_get_oem(intf);
return intf->fd; return intf->fd;
} }
@ -125,6 +126,7 @@ ipmi_openipmi_close(struct ipmi_intf * intf)
} }
intf->opened = 0; intf->opened = 0;
intf->manufacturer_id = IPMI_OEM_UNKNOWN;
} }
static struct ipmi_rs * static struct ipmi_rs *