diff options
Diffstat (limited to 'util/ievents.c')
-rw-r--r-- | util/ievents.c | 200 |
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; } |