diff --git a/ipmitool/include/ipmitool/ipmi_sel.h b/ipmitool/include/ipmitool/ipmi_sel.h index ffa30fa..89f3cb5 100644 --- a/ipmitool/include/ipmitool/ipmi_sel.h +++ b/ipmitool/include/ipmitool/ipmi_sel.h @@ -115,6 +115,67 @@ struct ipmi_event_sensor_types { const char * desc; }; +/* The sel module uses the "iana" number to select the appropriate array at run time + This table if for iana number 15000 ( Kontron ), you can add you own OEM sensor types + using a similar constuct, look for switch(iana) in ipmi_sel.c + */ +static struct ipmi_event_sensor_types oem_kontron_event_types[] __attribute__((unused)) = { + + /* event type details uses an oem event type */ + { 0xC0 , 0xFF , 0xff, IPMI_EVENT_CLASS_DISCRETE , "OEM Firmware Info", NULL }, + { 0xC0 , 0xFF , 0xff, IPMI_EVENT_CLASS_DISCRETE , "OEM Firmware Info", NULL }, + + { 0xC1 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Push Button" }, + { 0xC1 , 0x01 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Bridge Reset" }, + { 0xC1 , 0x02 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Backplane" }, + { 0xC1 , 0x03 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Hotswap Fault" }, + { 0xC1 , 0x04 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Hotswap Healty" }, + { 0xC1 , 0x05 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Unknown" }, + { 0xC1 , 0x06 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "ITP" }, + { 0xC1 , 0x07 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Hardware Watchdog" }, + { 0xC1 , 0x08 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset(cPCI)", "Software Reset" }, + + /* Uses standard digital reading type */ + { 0xC2 , 0xFF , 0xff, IPMI_EVENT_CLASS_DIGITAL , "SDRR Init Agent", NULL }, + + /* based on PICMG IPMB-0 Link state sensor */ + { 0xC3 , 0x02 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "IPMB-L Link State", "IPMB L Disabled" }, + { 0xC3 , 0x03 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "IPMB-L Link State", "IPMB L Enabled" }, + + { 0xC4 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Push Button" }, + { 0xC4 , 0x01 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Hardware Power Failure" }, + { 0xC4 , 0x02 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Unknown" }, + { 0xC4 , 0x03 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Hardware Watchdog" }, + { 0xC4 , 0x04 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Soft Reset" }, + { 0xC4 , 0x05 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Warm Reset" }, + { 0xC4 , 0x06 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Cold Reset" }, + { 0xC4 , 0x07 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "IPMI Command" }, + { 0xC4 , 0x08 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Setup Reset (Save CMOS)" }, + { 0xC4 , 0x09 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Board Reset", "Power Up Reset" }, + + /* event type details uses a standard */ + { 0xC5 , 0xFF , 0xff, IPMI_EVENT_CLASS_DISCRETE , "FRU Information Agent", NULL }, + + { 0xC6 , 0x0E , 0xff, IPMI_EVENT_CLASS_DISCRETE , "POST Value", "Post Error (see data2)" }, + + { 0xC7 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "FWUM Status", "First Boot After Upgrade" }, + { 0xC7 , 0x01 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "FWUM Status", "First Boot After Rollback(error)" }, + { 0xC7 , 0x02 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "FWUM Status", "First Boot After Errors (watchdog)" }, + { 0xC7 , 0x03 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "FWUM Status", "First Boot After Manual Rollback" }, + { 0xC7 , 0x08 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "FWUM Status", "Firmware Watchdog Bite, reset occured" }, + + { 0xC8 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Switch Mngt Software Status", "Not Loaded" }, + { 0xC8 , 0x01 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Switch Mngt Software Status", "Initializing" }, + { 0xC8 , 0x02 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Switch Mngt Software Status", "Ready" }, + { 0xC8 , 0x03 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Switch Mngt Software Status", "Failure (see data2)" }, + + { 0xC9 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Diagnostic Status", "Started" }, + { 0xC9 , 0x01 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Diagnostic Status", "Pass" }, + { 0xC9 , 0x02 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "Diagnostic Status", "Fail" }, + /* END */ + { 0x00, 0x00, 0xff, 0x00, NULL, NULL }, +}; + static struct ipmi_event_sensor_types generic_event_types[] __attribute__((unused)) = { /* Threshold Based States */ { 0x01, 0x00, 0xff, IPMI_EVENT_CLASS_THRESHOLD, "Threshold", "Lower Non-critical going low " }, diff --git a/ipmitool/lib/ipmi_sel.c b/ipmitool/lib/ipmi_sel.c index a141ca3..4895fe8 100644 --- a/ipmitool/lib/ipmi_sel.c +++ b/ipmitool/lib/ipmi_sel.c @@ -401,7 +401,36 @@ 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", "Reserved" }, + { 0x71 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "OEM Firmware Info 2", "Reserved" }, +}; + +char * +get_kontron_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec) +{ + char * description = NULL; + /* + * Kontron OEM events are described in the product's user manual, but are limited in favor of + * sensor specific + */ + /* 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++){ + if (st->code == rec->sel_type.standard_type.event_type ){ + size_t len =strlen(st->desc); + description = (char*)malloc( len + 1 ); + memcpy(description, st->desc , len); + description[len] = 0;; + return description; + } + } + } + + return "Unsupported event"; +} char * get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec) @@ -481,6 +510,8 @@ ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec) case IPMI_OEM_TYAN: case IPMI_OEM_SUPERMICRO: case IPMI_OEM_KONTRON: + desc = get_kontron_evt_desc(intf, rec); + break; case IPMI_OEM_UNKNOWN: default: break; @@ -494,7 +525,7 @@ 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; + struct ipmi_event_sensor_types *evt = NULL; if (desc == NULL) return; @@ -504,8 +535,29 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char *desc = ipmi_get_oem_desc(intf, rec); return; } else if (rec->sel_type.standard_type.event_type == 0x6f) { - evt = sensor_specific_types; - code = rec->sel_type.standard_type.sensor_type; + + if( rec->sel_type.standard_type.sensor_type >= 0xC0 && rec->sel_type.standard_type.sensor_type < 0xF0) { + IPMI_OEM iana = ipmi_get_oem(intf); + + switch(iana){ + 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; + /* add your oem sensor assignation here */ + } + if( evt == NULL ){ + lprintf(LOG_DEBUG, "oem sensor type %x using standard type supplied description", + rec->sel_type.standard_type.sensor_type ); + } + } + if( evt == NULL ){ + evt = sensor_specific_types; + code = rec->sel_type.standard_type.sensor_type; + } } else { evt = generic_event_types; code = rec->sel_type.standard_type.event_type; @@ -527,11 +579,54 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char memset(*desc, 0, strlen(evt->desc)+48); sprintf(*desc, "%s", evt->desc); return; - } + } evt++; } } + +const char * +ipmi_sel_get_oem_sensor_type(IPMI_OEM iana, 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 */ + } + + if( st != NULL ) + for (; st->type != NULL; st++) + if (st->code == code) + return st->type; + + return ipmi_sel_get_sensor_type(code); +} + +const char * +ipmi_sel_get_oem_sensor_type_offset(IPMI_OEM iana, uint8_t code, uint8_t offset) +{ + 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 */ + } + + if( st != NULL ) + for (; st->type != NULL; st++) + { + if (st->code == code && st->offset == (offset&0xf)) + return st->type; + } + + return ipmi_sel_get_oem_sensor_type(iana,code); +} + const char * ipmi_sel_get_sensor_type(uint8_t code) { @@ -549,6 +644,7 @@ ipmi_sel_get_sensor_type_offset(uint8_t code, uint8_t offset) for (st = sensor_specific_types; st->type != NULL; st++) if (st->code == code && st->offset == (offset&0xf)) return st->type; + return ipmi_sel_get_sensor_type(code); } @@ -785,7 +881,13 @@ 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], - ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0]), + ( + (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]) + ), evt->sel_type.standard_type.sensor_num, (description != NULL) ? description : "Unknown"); @@ -896,7 +998,15 @@ 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 ", ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])); + 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]) + ) + ); switch (sdr->type) { case SDR_RECORD_TYPE_FULL_SENSOR: printf("%s", sdr->record.full->id_string); @@ -921,7 +1031,13 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt) break; } } else { - printf("%s", ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])); + 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]) + )); if (evt->sel_type.standard_type.sensor_num != 0) printf(" #0x%02x", evt->sel_type.standard_type.sensor_num); } @@ -1072,7 +1188,14 @@ 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", - ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])); + ( + (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(" Sensor Number : %02x\n", evt->sel_type.standard_type.sensor_num); printf(" Event Type : %s\n", @@ -1242,6 +1365,11 @@ ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_ evt->sel_type.standard_type.event_data[2] & 0x0f, (evt->sel_type.standard_type.event_data[2] & 0xf0) >> 4); } + else + { + /* FIXME : Add sensor specific discrete types */ + printf(" Event Interpretation Missing\n"); + } } else if (evt->sel_type.standard_type.event_type >= 0x70 && evt->sel_type.standard_type.event_type <= 0x7f) { /* OEM */ } else {