Added some support for the interpretation of OEM event messages (type 2 SEL

entries with with an event type in the OEM range).  For Newisys OEM SEL
entries, textual message descriptions are retrieved through a Newisys IPMI
OEM command.
include/ipmitool/ipmi_sel.h lib/ipmi_sel.c src/ipmievd.c CVS:
----------------------------------------------------------------------
This commit is contained in:
Jeremy Ellington 2005-06-28 20:19:08 +00:00
parent 624392f798
commit 4067bafa57
3 changed files with 151 additions and 17 deletions

View File

@ -449,14 +449,26 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
{ 0x00, 0x00, 0x00, 0x00, NULL, NULL },
};
/* These values are IANA numbers */
typedef enum IPMI_OEM {
IPMI_OEM_UNKNOWN = 0,
IPMI_OEM_NEWISYS = 9237,
IPMI_OEM_INTEL,
} IPMI_OEM;
int ipmi_sel_main(struct ipmi_intf *, int, char **);
void ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt);
void ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_record * evt);
void ipmi_sel_print_extended_entry(struct ipmi_intf * intf, struct sel_event_record * evt);
void ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_record * evt);
void ipmi_get_event_desc(struct sel_event_record * rec, char ** desc);
void ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char ** desc);
const char * ipmi_sel_get_sensor_type(uint8_t code);
const char * ipmi_sel_get_sensor_type_offset(uint8_t code, uint8_t offset);
uint16_t ipmi_sel_get_std_entry(struct ipmi_intf * intf, uint16_t id, struct sel_event_record * evt);
char * get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec);
IPMI_OEM ipmi_get_oem(struct ipmi_intf * intf);
char * ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec);
#endif /* IPMI_SEL_H */

View File

@ -42,6 +42,7 @@
#include <ipmitool/helper.h>
#include <ipmitool/log.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_mc.h>
#include <ipmitool/ipmi_intf.h>
#include <ipmitool/ipmi_sel.h>
#include <ipmitool/ipmi_sdr.h>
@ -93,6 +94,9 @@ ipmi_sel_timestamp_date(uint32_t stamp)
return tbuf;
}
static char *
ipmi_sel_timestamp_time(uint32_t stamp)
{
@ -102,17 +106,136 @@ ipmi_sel_timestamp_time(uint32_t stamp)
return tbuf;
}
IPMI_OEM
ipmi_get_oem(struct ipmi_intf * intf)
{
/* Execute a Get Device ID command to determine the OEM */
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct ipm_devid_rsp *devid;
uint32_t manufacturer_id;
int i;
if (intf->fd == 0)
return IPMI_OEM_UNKNOWN;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = BMC_GET_DEVICE_ID;
req.msg.data_len = 0;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Get Device ID command failed");
return IPMI_OEM_UNKNOWN;
}
if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Get Device ID command failed: %s",
val2str(rsp->ccode, completion_code_vals));
return IPMI_OEM_UNKNOWN;
}
devid = (struct ipm_devid_rsp *) rsp->data;
return IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id);
}
char *
get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
{
/*
* Newisys OEM event descriptions can be retrieved through an
* OEM IPMI command.
*/
struct ipmi_rs * rsp;
struct ipmi_rq req;
uint8_t msg_data[6];
char * description = NULL;
memset(&req, 0, sizeof(req));
req.msg.netfn = 0x2E;
req.msg.cmd = 0x01;
req.msg.data_len = sizeof(msg_data);
msg_data[0] = 0x15; /* IANA LSB */
msg_data[1] = 0x24; /* IANA */
msg_data[2] = 0x00; /* IANA MSB */
msg_data[3] = 0x01; /* Subcommand */
msg_data[4] = rec->record_id & 0x00FF; /* SEL Record ID LSB */
msg_data[5] = (rec->record_id & 0xFF00) >> 8; /* SEL Record ID MSB */
req.msg.data = msg_data;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
if (verbose)
lprintf(LOG_ERR, "Error issuing OEM command");
return NULL;
}
if (rsp->ccode > 0) {
if (verbose)
lprintf(LOG_ERR, "OEM command returned error code: %s",
val2str(rsp->ccode, completion_code_vals));
return NULL;
}
/* Verify our response before we use it */
if (rsp->data_len < 5)
{
lprintf(LOG_ERR, "Newisys OEM response too short");
return NULL;
}
else if (rsp->data_len != (4 + rsp->data[3]))
{
lprintf(LOG_ERR, "Newisys OEM response has unexpected length");
return NULL;
}
else if (IPM_DEV_MANUFACTURER_ID(rsp->data) != IPMI_OEM_NEWISYS)
{
lprintf(LOG_ERR, "Newisys OEM response has unexpected length");
return NULL;
}
description = (char*)malloc(rsp->data[3] + 1);
memcpy(description, rsp->data + 4, rsp->data[3]);
description[rsp->data[3]] = 0;;
return description;
}
char *
ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
{
char * desc = NULL;
switch (ipmi_get_oem(intf))
{
case IPMI_OEM_NEWISYS:
desc = get_newisys_evt_desc(intf, rec);
break;
}
return desc;
}
void
ipmi_get_event_desc(struct sel_event_record * rec, char ** desc)
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;
if (desc == NULL)
return;
if (desc == NULL)
return;
*desc = NULL;
if (rec->event_type == 0x6f) {
if ((rec->event_type >= 0x70) && (rec->event_type <= 0x7F)) {
*desc = ipmi_get_oem_desc(intf, rec);
return;
} else if (rec->event_type == 0x6f) {
evt = sensor_specific_types;
code = rec->sensor_type;
} else {
@ -124,9 +247,9 @@ ipmi_get_event_desc(struct sel_event_record * rec, char ** desc)
while (evt->type) {
if ((evt->code == code && evt->offset == offset) &&
((evt->data == ALL_OFFSETS_SPECIFIED) ||
((rec->event_data[0] & DATA_BYTE2_SPECIFIED_MASK) &&
(evt->data == rec->event_data[1]))))
((evt->data == ALL_OFFSETS_SPECIFIED) ||
((rec->event_data[0] & DATA_BYTE2_SPECIFIED_MASK) &&
(evt->data == rec->event_data[1]))))
{
*desc = (char *)malloc(strlen(evt->desc) + 48);
if (*desc == NULL) {
@ -326,12 +449,12 @@ ipmi_sel_get_std_entry(struct ipmi_intf * intf, uint16_t id,
static void
ipmi_sel_print_event_file(struct ipmi_intf * intf, struct sel_event_record * evt, FILE * fp)
{
char * description;
char * description;
if (fp == NULL)
return;
ipmi_get_event_desc(evt, &description);
ipmi_get_event_desc(intf, evt, &description);
fprintf(fp, "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x # %s #0x%02x %s\n",
evt->evm_rev,
@ -360,7 +483,7 @@ ipmi_sel_print_extended_entry(struct ipmi_intf * intf, struct sel_event_record *
void
ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt)
{
char * description;
char * description;
struct sdr_record_list * sdr = NULL;
if (sel_extended)
@ -455,7 +578,7 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt)
else
printf(" | ");
ipmi_get_event_desc(evt, &description);
ipmi_get_event_desc(intf, evt, &description);
if (description) {
printf("%s", description);
free(description);
@ -564,7 +687,7 @@ ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_recor
val2str(evt->event_dir, event_dir_vals));
printf(" Event Data : %02x%02x%02x\n",
evt->event_data[0], evt->event_data[1], evt->event_data[2]);
ipmi_get_event_desc(evt, &description);
ipmi_get_event_desc(intf, evt, &description);
printf(" Description : %s\n",
description ? description : "");
free(description);
@ -572,6 +695,7 @@ ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_recor
printf("\n");
}
void
ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_record * evt)
{
@ -732,7 +856,7 @@ ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_
evt->event_data[0], evt->event_data[1], evt->event_data[2]);
}
ipmi_get_event_desc(evt, &description);
ipmi_get_event_desc(intf, evt, &description);
printf(" Description : %s\n",
description ? description : "");
free(description);
@ -889,8 +1013,6 @@ ipmi_sel_readraw(struct ipmi_intf * intf, const char * inputfile)
int ret = 0;
FILE* fp = 0;
printf("inside ipmi_sel_readraw\n");
fp = ipmi_open_file(inputfile, 0);
if (fp)
{

View File

@ -198,7 +198,7 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt)
}
type = ipmi_sel_get_sensor_type_offset(evt->sensor_type, evt->event_data[0]);
ipmi_get_event_desc(evt, &desc);
ipmi_get_event_desc(intf, evt, &desc);
sdr = ipmi_sdr_find_sdr_bynumtype(intf, evt->sensor_num, evt->sensor_type);
if (sdr == NULL) {