summaryrefslogtreecommitdiff
path: root/util/ievents.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/ievents.c')
-rw-r--r--util/ievents.c200
1 files changed, 69 insertions, 131 deletions
diff --git a/util/ievents.c b/util/ievents.c
index b244b68..d37d5fd 100644
--- a/util/ievents.c
+++ b/util/ievents.c
@@ -76,8 +76,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define SELprintf printf
#define SMS_SA 0x41
#define SMI_SA 0x21
+#ifdef METACOMMAND
+extern char *progver; /*from ipmiutil.c*/
+static char * progname = "ipmiutil events";
+#else
static char *progver = "3.08";
static char *progname = "ievents";
+#endif
static char fsensdesc = 0; /* 1= get extended sensor descriptions*/
static char fcanonical = 0; /* 1= show canonical, delimited output*/
static char fgetdevid = 0; /* 1= get device ID */
@@ -86,6 +91,7 @@ static char futc = 0; /* 1= raw UTC time */
static uchar thr_sa = SMS_SA; /* 0x41 (Sms) used by ipmitool PlarformEvents */
static void *sdrcache = NULL;
static int pet_guid = 8; /*bytes in the input data for the GUID*/
+static int iopt = -1; /*iana option*/
static char bcomma = ',';
static char bdelim = BDELIM; /* '|' */
#ifdef ALONE
@@ -593,7 +599,6 @@ uchar entity2sensor_type(uchar ent)
return(stype);
}
-
static char *mem_str(int off)
{
char *pstr;
@@ -604,121 +609,15 @@ static char *mem_str(int off)
case 0x03: pstr = "Memory Scrub Failed"; break;
case 0x04: pstr = "Memory Device Disabled"; break;
case 0x05: pstr = "ECC limit reached" ; break;
- case 0x07: pstr = "SMI Link Lane Fail Over"; break; /*Quanta QSSC_S4R*/
+ case 0x07: pstr = "ConfigError: SMI Link Lane FailOver"; break; /*Quanta QSSC_S4R*/
+ case 0x08: pstr = "Spare"; break; /*uses data3 */
+ case 0x09: pstr = "Memory Automatically Throttled"; break;
+ case 0x0A: pstr = "Critical Overtemperature"; break;
default: pstr = "Other Memory Error"; break;
}
return(pstr);
}
-#ifdef NEW
-#define OEM_CODE_IN_BYTE2 0x80
-#define OEM_CODE_IN_BYTE3 0x20
-static int decode_mem_default(uchar data1, uchar data2, uchar data3,
- char *desc, int *psz)
-{
- char tmpdesc[80];
- int tmpsz = sizeof(tmpdesc);
- int dsz, incr;
- if ((psz == NULL) || (desc == NULL)) return -1;
- dsz = *psz;
- /*
- * Based on the above error, we need to find whcih memory slot or
- * Card has got the Errors/Sel Generated.
- */
- if(data1 & OEM_CODE_IN_BYTE2 ) {
- /* Find the Card Type */
- if((0x0F != (data2 >> 4)) && ((data2 >> 4) < 0x08))
- {
- tmpData = ('A'+ (data2 >> 4));
- if( (sensor_type == SENSOR_TYPE_MEMORY ) && (0x0B == rec->sel_type.standard_type.event_type) )
- {
- snprintf(tmpdesc, tmpsz, "Bad Card %c", tmpData);
- } else {
- snprintf(tmpdesc, tmpsz, "Card %c", tmpData);
- }
- strcat(desc, tmpdesc);
- } /* Find the Bank Number of the DIMM */
- if (0x0F != (data2 & MASK_LOWER_NIBBLE))
- {
- if(0x51 == version)
- {
- snprintf(tmpdesc, tmpsz, "Bank %d", ((data2 & 0x0F)+1));
- strcat(desc, tmpdesc);
- } else {
- incr = (data2 & 0x0f) << 3;
- }
- }
-
- }
- /* Find the DIMM Number of the Memory which has Generated the Fault or Sel */
- if(data1 & OEM_CODE_IN_BYTE3 )
- {
- // Based on the IPMI Spec Need Identify the DIMM Details.
- // For the SPEC 1.5 Only the DIMM Number is Valid.
- if(0x51 == version)
- {
- snprintf(tmpdesc, tmpsz, "DIMM %c", ('A'+ data3));
- strcat(desc, tmpdesc);
- }
- /* For the SPEC 2.0 Decode the DIMM Number as it supports more*/
- else if( ((data2 >> 4) > 0x07) && (0x0F != (data2 >> 4) ))
- {
- strcpy(dimmStr, " DIMM");
- str = desc+strlen(desc);
- dimmsPerNode = 4;
- if(0x09 == (data2 >> 4)) dimmsPerNode = 6;
- else if(0x0A == (data2 >> 4)) dimmsPerNode = 8;
- else if(0x0B == (data2 >> 4)) dimmsPerNode = 9;
- else if(0x0C == (data2 >> 4)) dimmsPerNode = 12;
- else if(0x0D == (data2 >> 4)) dimmsPerNode = 24;
- else if(0x0E == (data2 >> 4)) dimmsPerNode = 3;
- count = 0;
- for (i = 0; i < 8; i++)
- {
- if (BIT(i) & data3)
- {
- if(count)
- {
- strcat(str,",");
- count = 0x00;
- }
- node = (incr + i)/dimmsPerNode;
- dimmNum = ((incr + i)%dimmsPerNode)+1;
- dimmStr[5] = node + 'A';
- sprintf(tmpdesc,"%d",dimmNum);
- for(j = 0; j < strlen(tmpdesc);j++)
- dimmStr[6+j] = tmpdesc[j];
- dimmStr[6+j] = '\0';
- strcat(str,dimmStr); // final DIMM Details.
- count++;
- }
- }
- } else {
- strcpy(dimmStr, " DIMM");
- str = desc+strlen(desc);
- count = 0;
- for (i = 0; i < 8; i++)
- {
- if (BIT(i) & data3)
- {
- // check if more than one DIMM, if so add a comma to the string.
- sprintf(tmpdesc,"%d",(i + incr + 1));
- if(count)
- {
- strcat(str,",");
- count = 0x00;
- }
- for(j = 0; j < strlen(tmpdesc);j++)
- dimmStr[5+j] = tmpdesc[j];
- dimmStr[5+j] = '\0';
- strcat(str, dimmStr);
- count++;
- }
- }
- }
- }
-}
-#endif
#if defined(METACOMMAND)
/* METACOMMAND is defined for ipmiutil meta-command build. */
@@ -751,7 +650,8 @@ static int default_mem_desc(uchar b2, uchar b3, char *desc, int *psz)
else bdata = b3; /* normal case */
array = (bdata & 0xc0) >> 6;
dimm = bdata & 0x3f;
- n = sprintf(desc,"DIMM[%d]",dimm);
+ if (bdata == 0xFF) n = sprintf(desc,DIMM_UNKNOWN);
+ else n = sprintf(desc,DIMM_NUM,dimm);
*psz = n;
return(0);
}
@@ -803,10 +703,13 @@ static int GetSensorType(int snum, uchar *stype, uchar *rtype)
* SMBIOS type 17, and the descriptions vary for each baseboard.
* We'll just show the index here by default.
* Do the SMBIOS lookup if not standalone build. */
+int g_vend_id = VENDOR_INTEL; /*assume a default of Intel*/
int strlen_(const char *s) { return((int)strlen(s)); }
-// char * get_iana_str(int vend) { return(""); } *from subs.c*/
-void set_iana(int vend) { return; }
+char *get_iana_str(int vend) { return(""); } /*from subs.c*/
+void set_iana(int vend) { g_vend_id = vend; return; }
+char is_remote(void) { return(1); } /* act as if remote with standalone */
+
int get_MemDesc(int array, int idimm, char *desc, int *psz)
{
/* standalone, so use the default method for the DIMM index */
@@ -816,11 +719,9 @@ int get_MemDesc(int array, int idimm, char *desc, int *psz)
void get_mfgid(int *vend, int *prod)
{
if ((vend == NULL) || (prod == NULL)) return;
- *vend = VENDOR_INTEL; /*assume a default of Intel*/
+ *vend = g_vend_id; /*assume a default of Intel*/
*prod = 0;
}
-char is_remote(void)
-{ return(1); /* act as if remote with standalone utility */ }
char * decode_rv(int rv)
{
static char mystr[30];
@@ -887,6 +788,38 @@ extern char * decode_rv(int rv); /*from ipmilan.c*/
extern void dump_buf(char *tag, uchar *pbuf, int sz, char fshowascii);
#endif
+static int decode_mem_default(uchar b1, uchar b2, uchar b3, uchar etype, char *desc, int *psz)
+{
+ int cpu, dimm, n;
+ int rv = -1;
+ int offset = 0;
+ uchar bdata;
+
+ if ((desc == NULL) || (psz == NULL)) return -1;
+ offset = (b1 & 0x0F);
+ if ((b1 & 0x20) != 0) { bdata = b3; } /*dimm data in byte 3*/
+ else if (b2 == 0xff) { bdata = b3; } /*ff is reserved*/
+ else { bdata = b2; } /*if here, should also have (b1 & 0x80)*/
+
+ if (bdata == 0xFF) n = sprintf(desc,DIMM_UNKNOWN);
+ else {
+ cpu = (bdata & 0xc0) >> 6;
+ dimm = (bdata & 0x3F);
+ n = sprintf(desc,DIMM_NUM,dimm);
+ /* Use DMI if we get confirmation about cpu/dimm indices. */
+ if (! is_remote()) {
+ fsm_debug = fdebug;
+ rv = get_MemDesc(cpu,dimm,desc,psz);
+ if (rv != 0) n = sprintf(desc,DIMM_NUM,dimm);
+ }
+ }
+ *psz = n;
+ if (fdebug)
+ printf("decode_mem_default: bdata=%02x(%d) %d dimm=%d\n",bdata,bdata,offset,dimm);
+ rv = 0;
+ return(rv);
+} /*end decode_mem_default*/
+
int new_event(uchar *buf, int len)
{
int rlen, rv;
@@ -1335,6 +1268,7 @@ int get_sensor_tag(int isdr, int genid, uchar snum, char *tag,
rv = ERR_NOT_FOUND; /*got tag, but did not get SDR*/
}
}
+ if (rv != 0) strcpy(tag,"na");
if (fdebug) printf("get_sensor_tag(%d): find_sdr(%x,%x) rv=%d tag=/%s/\n",
fsensdesc,snum,genid,rv,tag);
return(rv);
@@ -1537,7 +1471,7 @@ void format_event(ushort id, time_t timestamp, int sevid, ushort genid,
gstr, bdelim, ptype, bdelim,
psens, bdelim, pstr, more );
} else {
- snprintf(outbuf,outsz,"%04x %s %s %s %s #%02x %s%s %s\n",
+ snprintf(outbuf,outsz,"%04x %s %s %s %s #%02x %s %s %s\n",
id, timestr, get_sev_str(sevid),
gstr, ptype, snum, psens, pstr, more);
}
@@ -1589,6 +1523,7 @@ int decode_sel_entry( uchar *pevt, char *outbuf, int szbuf)
uchar *pc;
SEL_RECORD *psel;
uchar fdeassert = 0;
+ uchar etype;
uchar sev = SEV_INFO;
uchar sdr[MAX_BUFFER_SIZE]; /*sdr usu <= 65 bytes*/
int isdr = 0;
@@ -1607,6 +1542,7 @@ int decode_sel_entry( uchar *pevt, char *outbuf, int szbuf)
}
get_mfgid(&vend,&prod); /*saved from ipmi_getdeviceid */
psel = (SEL_RECORD *)pevt;
+ etype = psel->event_trigger;
j = decode_sel_oem(vend,pevt,outbuf,szbuf,fsensdesc,fdebug);
if (j == 0) return(0); /*successful, have the description*/
@@ -1903,6 +1839,7 @@ int decode_sel_entry( uchar *pevt, char *outbuf, int szbuf)
if (i == 0) sev = SEV_MIN; /*correctable ECC*/
else sev = SEV_MAJ;
if (fdebug) printf("DIMM(%d) vend=%x prod=%x\n",j,vend,prod);
+ msz = sizeof(mdesc);
/* For Intel S5500/S2600 see decode_mem_intel */
if (vend == VENDOR_INTEL) {
decode_mem_intel(prod,b2,b3,mdesc,&msz);
@@ -1911,8 +1848,10 @@ int decode_sel_entry( uchar *pevt, char *outbuf, int szbuf)
(vend == VENDOR_SUPERMICROX)) {
decode_mem_supermicro(prod,b2,b3,mdesc,&msz);
sprintf(mystr,"%s%c %s",mem_str(i),bcomma,mdesc);
- } else {
- sprintf(mystr,"%s%c DIMM[%d]",mem_str(i),bcomma,j);
+ } else { /*decode_mem_raw*/
+ decode_mem_default(psel->event_data1,b2,b3,etype,mdesc,&msz);
+ sprintf(mystr,"%s%c %s",mem_str(i),bcomma,mdesc);
+ //old: sprintf(mystr,"%s%c DIMM[%d]",mem_str(i),bcomma,j);
/* DIMM[2] = 3rd one (zero-based index) */
}
}
@@ -1920,7 +1859,7 @@ int decode_sel_entry( uchar *pevt, char *outbuf, int szbuf)
break;
case 0x0F: /*System Firmware events, incl POST Errs*/
sev = SEV_MAJ; /*usu major, but platform-specific*/
- switch (psel->event_data1)
+ switch (psel->event_data1 & 0x0f)
{
case 0x00: /* System firmware errors */
i = psel->event_data2;
@@ -1960,7 +1899,7 @@ int decode_sel_entry( uchar *pevt, char *outbuf, int szbuf)
psel->event_data2,
psel->event_data3, &sev);
if (pstr == NULL)
- pstr = "POST Error"; /*default string*/
+ pstr = "POST Event"; /*default string*/
} /*end switch(data1)*/
break;
case 0x13: /*Crit Int*/
@@ -2400,19 +2339,18 @@ int i_events(int argc, char **argv)
fPET = 1; /*incoming data is in PET format*/
break;
case 'u': futc = 1; break; /*use raw UTC time*/
-#ifndef ALONE
+ case 'M': /* Set manufacturer IANA */
case 'o': /*specify OEM IANA manufacturer id */
if (argc > 1) { /*next argv is IANA number */
- i = atoi(argv[1]);
- printf("setting IANA to %d (%s)\n",i,get_iana_str(i));
- set_iana(i);
+ iopt = atoi(argv[1]);
+ printf("setting IANA to %d (%s)\n",iopt,get_iana_str(iopt));
+ set_iana(iopt);
argc--; argv++;
} else {
- printf("option -%c requires an argument\n",c);
- rv = ERR_BAD_PARAM;
- }
+ printf("option -%c requires an argument\n",c);
+ rv = ERR_BAD_PARAM;
+ }
break;
-#endif
case 't': /*PET format Trap, use all data*/
/* This may be helpful if all bytes are available, or if
* the GUID is relevant. */
@@ -2497,7 +2435,7 @@ int i_events(int argc, char **argv)
default: /*unknown option*/
printf("Unknown option -%c\n",c);
show_usage();
- rv = ERR_USAGE;
+ rv = ERR_USAGE;
goto do_exit;
break;
}