summaryrefslogtreecommitdiff
path: root/lib/ipmi_sel.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ipmi_sel.c')
-rw-r--r--lib/ipmi_sel.c330
1 files changed, 191 insertions, 139 deletions
diff --git a/lib/ipmi_sel.c b/lib/ipmi_sel.c
index b6629a2..8b0395e 100644
--- a/lib/ipmi_sel.c
+++ b/lib/ipmi_sel.c
@@ -49,6 +49,7 @@
#include <ipmitool/ipmi_sdr.h>
#include <ipmitool/ipmi_fru.h>
#include <ipmitool/ipmi_sensor.h>
+#include <ipmitool/ipmi_strings.h>
extern int verbose;
static int sel_extended = 0;
@@ -446,13 +447,14 @@ ipmi_sel_add_entries_fromfile(struct ipmi_intf * intf, const char * filename)
return rc;
}
-static struct ipmi_event_sensor_types oem_kontron_event_reading_types[] __attribute__((unused)) = {
- { 0x70 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "OEM Firmware Info 1", "Code Assert" },
- { 0x71 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "OEM Firmware Info 2", "Code Assert" },
+static struct ipmi_event_sensor_types oem_kontron_event_reading_types[] __attribute__((unused)) = {
+ { 0x70 , 0x00 , 0xff, "Code Assert" },
+ { 0x71 , 0x00 , 0xff, "Code Assert" },
+ { 0, 0, 0xFF, NULL }
};
char *
-get_kontron_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
+get_kontron_evt_desc(struct ipmi_intf *intf, struct sel_event_record * rec)
{
char * description = NULL;
/*
@@ -462,8 +464,8 @@ get_kontron_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
/* Only standard records are defined so far */
if( rec->record_type < 0xC0 ){
- struct ipmi_event_sensor_types *st=NULL;
- for ( st=oem_kontron_event_reading_types ; st->type != NULL; st++){
+ const struct ipmi_event_sensor_types *st=NULL;
+ for ( st=oem_kontron_event_types ; st->desc != NULL; st++){
if (st->code == rec->sel_type.standard_type.event_type ){
size_t len =strlen(st->desc);
description = (char*)malloc( len + 1 );
@@ -546,7 +548,7 @@ get_supermicro_evt_desc(struct ipmi_intf *intf, struct sel_event_record *rec)
struct ipmi_rs *rsp;
struct ipmi_rq req;
char *desc = NULL;
- int chipset_type = 1;
+ int chipset_type = 4;
int data1;
int data2;
int data3;
@@ -612,12 +614,48 @@ get_supermicro_evt_desc(struct ipmi_intf *intf, struct sel_event_record *rec)
break;
}
}
+ for (i = 0; supermicro_older[i] != 0xFFFF; i++) {
+ if (oem_id == supermicro_older[i]) {
+ chipset_type = 0;
+ break;
+ }
+ }
+ for (i = 0; supermicro_romely[i] != 0xFFFF; i++) {
+ if (oem_id == supermicro_romely[i]) {
+ chipset_type = 1;
+ break;
+ }
+ }
for (i = 0; supermicro_x9[i] != 0xFFFF; i++) {
if (oem_id == supermicro_x9[i]) {
chipset_type = 2;
break;
}
}
+ for (i = 0; supermicro_brickland[i] != 0xFFFF; i++) {
+ if (oem_id == supermicro_brickland[i]) {
+ chipset_type = 3;
+ break;
+ }
+ }
+ for (i = 0; supermicro_x10QRH[i] != 0xFFFF; i++) {
+ if (oem_id == supermicro_x10QRH[i]) {
+ chipset_type = 4;
+ break;
+ }
+ }
+ for (i = 0; supermicro_x10QBL[i] != 0xFFFF; i++) {
+ if (oem_id == supermicro_x10QBL[i]) {
+ chipset_type = 4;
+ break;
+ }
+ }
+ for (i = 0; supermicro_x10OBi[i] != 0xFFFF; i++) {
+ if (oem_id == supermicro_x10OBi[i]) {
+ chipset_type = 5;
+ break;
+ }
+ }
if (chipset_type == 0) {
snprintf(desc, SIZE_OF_DESC, "@DIMM%2X(CPU%x)",
data2,
@@ -630,6 +668,21 @@ get_supermicro_evt_desc(struct ipmi_intf *intf, struct sel_event_record *rec)
snprintf(desc, SIZE_OF_DESC, "@DIMM%c%c(CPU%x)",
(data2 >> 4) + 0x40 + (data3 & 0x3) * 3,
(data2 & 0xf) + 0x27, (data3 & 0x03) + 1);
+ } else if (chipset_type == 3) {
+ snprintf(desc, SIZE_OF_DESC, "@DIMM%c%d(P%dM%d)",
+ ((data2 & 0xf) >> 4) > 4
+ ? '@' - 4 + ((data2 & 0xff) >> 4)
+ : '@' + ((data2 & 0xff) >> 4),
+ (data2 & 0xf) - 0x09, (data3 & 0x0f) + 1,
+ (data2 & 0xff) >> 4 > 4 ? 2 : 1);
+ } else if (chipset_type == 4) {
+ snprintf(desc, SIZE_OF_DESC, "@DIMM%c%c(CPU%x)",
+ (data2 >> 4) + 0x40,
+ (data2 & 0xf) + 0x27, (data3 & 0x03) + 1);
+ } else if (chipset_type == 5) {
+ snprintf(desc, SIZE_OF_DESC, "@DIMM%c%c(CPU%x)",
+ (data2 >> 4) + 0x40,
+ (data2 & 0xf) + 0x27, (data3 & 0x07) + 1);
} else {
/* No description. */
desc[0] = '\0';
@@ -1200,11 +1253,71 @@ ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
}
+const struct ipmi_event_sensor_types *
+ipmi_get_first_event_sensor_type(struct ipmi_intf *intf,
+ uint8_t sensor_type, uint8_t event_type)
+{
+ const struct ipmi_event_sensor_types *evt, *start, *next = NULL;
+ uint8_t code;
+
+ if (event_type == 0x6f) {
+ if (sensor_type >= 0xC0
+ && sensor_type < 0xF0
+ && ipmi_get_oem(intf) == IPMI_OEM_KONTRON) {
+ /* check Kontron OEM sensor event types */
+ start = oem_kontron_event_types;
+ } else if (intf->vita_avail) {
+ /* check VITA sensor event types first */
+ start = vita_sensor_event_types;
+
+ /* then check generic sensor types */
+ next = sensor_specific_event_types;
+ } else {
+ /* check generic sensor types */
+ start = sensor_specific_event_types;
+ }
+ code = sensor_type;
+ } else {
+ start = generic_event_types;
+ code = event_type;
+ }
+
+ for (evt = start; evt->desc != NULL || next != NULL; evt++) {
+ /* check if VITA sensor event types has finished */
+ if (evt->desc == NULL) {
+ /* proceed with next table */
+ evt = next;
+ next = NULL;
+ }
+
+ if (code == evt->code)
+ return evt;
+ }
+
+ return NULL;
+}
+
+
+const struct ipmi_event_sensor_types *
+ipmi_get_next_event_sensor_type(const struct ipmi_event_sensor_types *evt)
+{
+ const struct ipmi_event_sensor_types *start = evt;
+
+ for (evt = start + 1; evt->desc != NULL; evt++) {
+ if (evt->code == start->code) {
+ return evt;
+ }
+ }
+
+ return NULL;
+}
+
+
void
ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char ** desc)
{
- uint8_t code, offset;
- struct ipmi_event_sensor_types *evt = NULL;
+ uint8_t offset;
+ const struct ipmi_event_sensor_types *evt = NULL;
char *sfx = NULL; /* This will be assigned if the Platform is DELL,
additional info is appended to the current Description */
@@ -1223,86 +1336,61 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
case IPMI_OEM_KONTRON:
lprintf(LOG_DEBUG, "oem sensor type %x %d using oem type supplied description",
rec->sel_type.standard_type.sensor_type , iana);
-
- evt = oem_kontron_event_types;
- code = rec->sel_type.standard_type.sensor_type;
break;
case IPMI_OEM_DELL: /* OEM Bytes Decoding for DELLi */
- evt = sensor_specific_types;
- code = rec->sel_type.standard_type.sensor_type;
if ( (OEM_CODE_IN_BYTE2 == (rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK)) ||
(OEM_CODE_IN_BYTE3 == (rec->sel_type.standard_type.event_data[0] & DATA_BYTE3_SPECIFIED_MASK)) )
{
- if(rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK)
- evt->data = rec->sel_type.standard_type.event_data[1];
-
sfx = ipmi_get_oem_desc(intf, rec);
}
break;
case IPMI_OEM_SUPERMICRO:
case IPMI_OEM_SUPERMICRO_47488:
- evt = sensor_specific_types;
- code = rec->sel_type.standard_type.sensor_type;
sfx = ipmi_get_oem_desc(intf, rec);
break;
/* add your oem sensor assignation here */
default:
+ lprintf(LOG_DEBUG, "oem sensor type %x using standard type supplied description",
+ rec->sel_type.standard_type.sensor_type );
break;
- }
- if( evt == NULL ){
- lprintf(LOG_DEBUG, "oem sensor type %x using standard type supplied description",
- rec->sel_type.standard_type.sensor_type );
}
} else {
switch (ipmi_get_oem(intf)) {
case IPMI_OEM_SUPERMICRO:
case IPMI_OEM_SUPERMICRO_47488:
- evt = sensor_specific_types;
- code = rec->sel_type.standard_type.sensor_type;
sfx = ipmi_get_oem_desc(intf, rec);
break;
default:
break;
}
}
- if( evt == NULL ){
- evt = sensor_specific_types;
- code = rec->sel_type.standard_type.sensor_type;
- }
/*
* Check for the OEM DELL Interface based on the Dell Specific Vendor Code.
* If its Dell Platform, do the OEM Byte decode from the SEL Records.
* Additional information should be written by the ipmi_get_oem_desc()
*/
if(ipmi_get_oem(intf) == IPMI_OEM_DELL) {
- code = rec->sel_type.standard_type.sensor_type;
if ( (OEM_CODE_IN_BYTE2 == (rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK)) ||
(OEM_CODE_IN_BYTE3 == (rec->sel_type.standard_type.event_data[0] & DATA_BYTE3_SPECIFIED_MASK)) )
{
- if(rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK)
- evt->data = rec->sel_type.standard_type.event_data[1];
- sfx = ipmi_get_oem_desc(intf, rec);
-
+ sfx = ipmi_get_oem_desc(intf, rec);
}
else if(SENSOR_TYPE_OEM_SEC_EVENT == rec->sel_type.standard_type.event_data[0])
{
/* 0x23 : Sensor Number.*/
if(0x23 == rec->sel_type.standard_type.sensor_num)
- {
- evt->data = rec->sel_type.standard_type.event_data[1];
sfx = ipmi_get_oem_desc(intf, rec);
- }
}
}
- } else {
- evt = generic_event_types;
- code = rec->sel_type.standard_type.event_type;
}
offset = rec->sel_type.standard_type.event_data[0] & 0xf;
- while (evt->type) {
- if ((evt->code == code && evt->offset == offset && evt->desc != NULL) &&
+ for (evt = ipmi_get_first_event_sensor_type(intf,
+ rec->sel_type.standard_type.sensor_type,
+ rec->sel_type.standard_type.event_type);
+ evt != NULL; evt = ipmi_get_next_event_sensor_type(evt)) {
+ if ((evt->offset == offset && evt->desc != NULL) &&
((evt->data == ALL_OFFSETS_SPECIFIED) ||
((rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK) &&
(evt->data == rec->sel_type.standard_type.event_data[1]))))
@@ -1326,15 +1414,14 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
sprintf(*desc, "%s", evt->desc);
}
return;
- }
- evt++;
+ }
}
/* The Above while Condition was not met beacouse the below sensor type were Newly defined OEM
Secondary Events. 0xC1, 0xC2, 0xC3. */
if((sfx) && (0x6F == rec->sel_type.standard_type.event_type))
{
uint8_t flag = 0x00;
- switch(code)
+ switch(rec->sel_type.standard_type.sensor_type)
{
case SENSOR_TYPE_FRM_PROG:
if(0x0F == offset)
@@ -1379,74 +1466,58 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
}
-const char *
-ipmi_sel_get_oem_sensor_type(IPMI_OEM iana, uint8_t code)
+const char*
+ipmi_get_generic_sensor_type(uint8_t code)
{
- struct ipmi_event_sensor_types *st = NULL;
-
- switch(iana){
- case IPMI_OEM_KONTRON:
- st = oem_kontron_event_types;
- break;
- /* add you oem sensor type lookup assignement here */
- default:
- lprintf(LOG_DEBUG, "ipmitool: missing OEM sensor type for %ul",iana);
- break;
+ if (code <= SENSOR_TYPE_MAX) {
+ return ipmi_generic_sensor_type_vals[code];
}
- if( st != NULL )
- for (; st->type != NULL; st++)
- if (st->code == code)
- return st->type;
-
- return ipmi_sel_get_sensor_type(code);
+ return NULL;
}
+
const char *
-ipmi_sel_get_oem_sensor_type_offset(IPMI_OEM iana, uint8_t code, uint8_t offset)
+ipmi_get_oem_sensor_type(struct ipmi_intf *intf, uint8_t code)
{
- struct ipmi_event_sensor_types *st = NULL;
+ const struct oemvalstr *v, *found = NULL;
+ uint32_t iana = ipmi_get_oem(intf);
- switch(iana){
- case IPMI_OEM_KONTRON:
- st = oem_kontron_event_types;
- break;
- /* add you oem sensor type lookup assignement here */
- default:
- lprintf(LOG_DEBUG,
- "ipmitool: missing OEM sensor type offset for %ul",iana);
- break;
- }
+ for (v = ipmi_oem_sensor_type_vals; v->str; v++) {
+ if (v->oem == iana && v->val == code) {
+ return v->str;
+ }
- if( st != NULL )
- for (; st->type != NULL; st++)
- {
- if (st->code == code && st->offset == (offset&0xf))
- return st->type;
+ if ((intf->picmg_avail
+ && v->oem == IPMI_OEM_PICMG
+ && v->val == code)
+ || (intf->vita_avail
+ && v->oem == IPMI_OEM_VITA
+ && v->val == code)) {
+ found = v;
}
+ }
- return ipmi_sel_get_oem_sensor_type(iana,code);
+ return found ? found->str : NULL;
}
-const char *
-ipmi_sel_get_sensor_type(uint8_t code)
-{
- struct ipmi_event_sensor_types *st;
- for (st = sensor_specific_types; st->type != NULL; st++)
- if (st->code == code)
- return st->type;
- return "Unknown";
-}
const char *
-ipmi_sel_get_sensor_type_offset(uint8_t code, uint8_t offset)
+ipmi_get_sensor_type(struct ipmi_intf *intf, uint8_t code)
{
- struct ipmi_event_sensor_types *st;
- for (st = sensor_specific_types; st->type != NULL; st++)
- if (st->code == code && st->offset == (offset&0xf))
- return st->type;
+ const char *type;
+
+ if (code >= 0xC0) {
+ type = ipmi_get_oem_sensor_type(intf, code);
+ } else {
+ type = ipmi_get_generic_sensor_type(code);
+ }
+
+ if (type == NULL) {
+ type = "Unknown";
+ }
- return ipmi_sel_get_sensor_type(code);
+ return type;
}
static int
@@ -1693,13 +1764,7 @@ ipmi_sel_print_event_file(struct ipmi_intf * intf, struct sel_event_record * evt
evt->sel_type.standard_type.event_data[0],
evt->sel_type.standard_type.event_data[1],
evt->sel_type.standard_type.event_data[2],
- (
- (evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
- ?
- ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- :
- ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- ),
+ ipmi_get_sensor_type(intf, evt->sel_type.standard_type.sensor_type),
evt->sel_type.standard_type.sensor_num,
(description != NULL) ? description : "Unknown");
@@ -1819,15 +1884,8 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt)
/* lookup SDR entry based on sensor number and type */
if (sdr != NULL) {
- printf("%s ",
- (
- (evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
- ?
- ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- :
- ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- )
- );
+ printf("%s ", ipmi_get_sensor_type(intf,
+ evt->sel_type.standard_type.sensor_type));
switch (sdr->type) {
case SDR_RECORD_TYPE_FULL_SENSOR:
printf("%s", sdr->record.full->id_string);
@@ -1852,13 +1910,8 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt)
break;
}
} else {
- printf("%s",(
- (evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
- ?
- ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- :
- ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- ));
+ printf("%s", ipmi_get_sensor_type(intf,
+ evt->sel_type.standard_type.sensor_type));
if (evt->sel_type.standard_type.sensor_num != 0)
printf(" #0x%02x", evt->sel_type.standard_type.sensor_num);
}
@@ -2025,14 +2078,8 @@ ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_recor
printf(" EvM Revision : %02x\n",
evt->sel_type.standard_type.evm_rev);
printf(" Sensor Type : %s\n",
- (
- (evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
- ?
- ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- :
- ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- )
- );
+ ipmi_get_sensor_type(intf,
+ evt->sel_type.standard_type.sensor_type));
printf(" Sensor Number : %02x\n",
evt->sel_type.standard_type.sensor_num);
printf(" Event Type : %s\n",
@@ -2096,7 +2143,7 @@ ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_
printf(" EvM Revision : %02x\n",
evt->sel_type.standard_type.evm_rev);
printf(" Sensor Type : %s\n",
- ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0]));
+ ipmi_get_sensor_type(intf, evt->sel_type.standard_type.sensor_type));
printf(" Sensor Number : %02x\n",
evt->sel_type.standard_type.sensor_num);
printf(" Event Type : %s\n",
@@ -2255,7 +2302,7 @@ __ipmi_sel_savelist_entries(struct ipmi_intf * intf, int count, const char * sav
if (count < 0) {
/** Show only the most recent 'count' records. */
- int delta;
+ int i;
uint16_t entries;
req.msg.cmd = IPMI_CMD_GET_SEL_INFO;
@@ -2273,15 +2320,20 @@ __ipmi_sel_savelist_entries(struct ipmi_intf * intf, int count, const char * sav
if (-count > entries)
count = -entries;
- /* Get first record. */
- next_id = ipmi_sel_get_std_entry(intf, 0, &evt);
-
- delta = next_id - evt.record_id;
-
- /* Get last record. */
- next_id = ipmi_sel_get_std_entry(intf, 0xffff, &evt);
-
- next_id = evt.record_id + count * delta + delta;
+ for(i = 0; i < entries + count; i++) {
+ next_id = ipmi_sel_get_std_entry(intf, next_id, &evt);
+ if (next_id == 0) {
+ /*
+ * usually next_id of zero means end but
+ * retry because some hardware has quirks
+ * and will return 0 randomly.
+ */
+ next_id = ipmi_sel_get_std_entry(intf, next_id, &evt);
+ if (next_id == 0) {
+ break;
+ }
+ }
+ }
}
if (savefile != NULL) {
@@ -2402,7 +2454,7 @@ ipmi_sel_interpret(struct ipmi_intf *intf, unsigned long iana,
evt.sel_type.standard_type.evm_rev = 4;
/* FIXME: convert*/
- evt.sel_type.standard_type.timestamp;
+ /* evt.sel_type.standard_type.timestamp; */
/* skip timestamp */
cursor = index((const char *)cursor, ';');