mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-10 18:47:22 +00:00
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:
parent
31cb04f155
commit
5d960089c9
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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> ... [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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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 *
|
||||
|
Loading…
x
Reference in New Issue
Block a user