diff options
Diffstat (limited to 'util/oem_fujitsu.c')
-rw-r--r-- | util/oem_fujitsu.c | 773 |
1 files changed, 773 insertions, 0 deletions
diff --git a/util/oem_fujitsu.c b/util/oem_fujitsu.c new file mode 100644 index 0000000..362df96 --- /dev/null +++ b/util/oem_fujitsu.c @@ -0,0 +1,773 @@ +/* + * oem_fujitsu.c + * + * This module handles OEM-specific functions for Fujitsu-Siemens firmware. + * + * References: + * http://manuals.ts.fujitsu.com/file/4390/irmc_s2-ug-en.pdf + * + * Authors: Andy Cress arcress at users.sourceforge.net, and + * Dan Lukes dan at obluda.cz + * + * Copyright (c) 2010 Kontron America, Inc. + * + * 08/17/10 Andy Cress v1.0 new, with source input from Dan Lukes + */ +/*M* +Copyright (c) 2010 Kontron America, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + a.. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + b.. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + c.. Neither the name of Kontron nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *M*/ +#ifdef WIN32 +#include <windows.h> +#endif +#include <stdio.h> +#include <string.h> +#include <time.h> +#include "ipmicmd.h" +#include "ievents.h" +#include "oem_fujitsu.h" + +/* extern void get_mfgid(int *vend, int *prod); * from ipmicmd.h*/ +/* extern int get_lan_options(); * from ipmicmd.h */ +static char fdebug = 0; +static char freadok = 1; +#define ERRLED 0 /*GEL - red Global Error LED*/ +#define WARNLED 1 /*CSS - yellow warning LED*/ +#define IDLED 2 /*ID - blue Identify LED*/ + +#define NETFN_FUJITSU_IRMCS2 0xB8 +#define CMD_FUJITSU_IRMCS2 0xF5 +#define CMD_SPEC_FUJITSU_SET_ID_LED 0xB0 +#define CMD_SPEC_FUJITSU_GET_ID_LED 0xB1 +#define CMD_SPEC_FUJITSU_GET_ERR_LED 0xB3 +#define LED_OFF 0 +#define LED_ON 1 +#define LED_BLINK 2 + +/* + * get_alarmss_fujitsu + * returns an array of 3 bytes: + * offset 0 = ID blue LED state (0=off, 1=on, 2=blink) + * offset 1 = CSS yellow LED state (0=off, 1=on, 2=blink) + * offset 2 = GEL red LED state (0=off, 1=on, 2=blink) + */ +int get_alarms_fujitsu(uchar *rgalarms ) +{ + int rv = -1; + uchar idata[16]; + uchar rdata[16]; + int rlen; + ushort icmd; + uchar cc; + int vend_id, prod_id; + + if (rgalarms == NULL) return(ERR_BAD_PARAM); + memset(rgalarms,0,3); + /* check if iRMC s2 */ + get_mfgid(&vend_id,&prod_id); + if (vend_id != VENDOR_FUJITSU) return(LAN_ERR_NOTSUPPORT); + if (FUJITSU_PRODUCT_IS_iRMC_S1(prod_id)) return(LAN_ERR_NOTSUPPORT); + + /* get error, warning, id led statuses */ + icmd = CMD_FUJITSU_IRMCS2 | (IPMI_NET_FN_OEM_GROUP_RQ << 8); + idata[0] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF); + idata[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8; + idata[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16; + idata[3] = CMD_SPEC_FUJITSU_GET_ID_LED; + rlen = sizeof(rdata); + rv = ipmi_cmd_mc(icmd, idata, 4, rdata, &rlen, &cc, fdebug); + if ((rv == 0) && (cc != 0)) rv = cc; + if (rv != 0) return(rv); + rgalarms[0] = (rdata[3] & 0x03); /*id led, after the IANA response */ + icmd = CMD_FUJITSU_IRMCS2 | (IPMI_NET_FN_OEM_GROUP_RQ << 8); + idata[0] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF); + idata[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8; + idata[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16; + idata[3] = CMD_SPEC_FUJITSU_GET_ERR_LED; + rlen = sizeof(rdata); + rv = ipmi_cmd_mc(icmd, idata, 4, rdata, &rlen, &cc, fdebug); + if ((rv == 0) && (cc != 0)) rv = cc; + switch(rdata[3]) { + case 1: rgalarms[1] = LED_OFF; rgalarms[2] = LED_ON; break; + case 2: rgalarms[1] = LED_OFF; rgalarms[2] = LED_BLINK; break; + case 3: rgalarms[1] = LED_ON; rgalarms[2] = LED_OFF; break; + case 4: rgalarms[1] = LED_ON; rgalarms[2] = LED_ON; break; + case 5: rgalarms[1] = LED_ON; rgalarms[2] = LED_BLINK; break; + case 6: rgalarms[1] = LED_BLINK; rgalarms[2] = LED_OFF; break; + case 7: rgalarms[1] = LED_BLINK; rgalarms[2] = LED_ON; break; + case 8: rgalarms[1] = LED_BLINK; rgalarms[2] = LED_BLINK; break; + case 0: + default: rgalarms[1] = LED_OFF; rgalarms[2] = LED_OFF; break; + } + + return(rv); +} + +static char *led_str(uchar b) +{ + char *pstr; + switch(b) { + case LED_ON: pstr = "ON"; break; + case LED_BLINK: pstr = "Blink"; break; + case LED_OFF: + default: pstr = "off"; break; + } + return(pstr); +} + +/* + * show_alarms_fujitsu + * offset 0 = ID blue LED state (0=off, 1=on, 2=blink) + * offset 1 = CSS yellow LED state (0=off, 1=on, 2=blink) + * offset 2 = GEL red LED state (0=off, 1=on, 2=blink) + */ +int show_alarms_fujitsu(uchar *rgalarms) +{ + if (rgalarms == NULL) return(ERR_BAD_PARAM); + /* show error, warning, id led statuses */ + printf("iRMC S2 ID LED (blue) = %s\n",led_str(rgalarms[0])); + printf("iRMC S2 CSS LED (yellow) = %s\n",led_str(rgalarms[1])); + printf("iRMC S2 GEL LED (red) = %s\n",led_str(rgalarms[2])); + return(0); +} + +/* + * set_alarms_fujitsu + * num: only the ID LED can be set, so num==0 + * val: 0=LED_OFF, 1=LED_ON + */ +int set_alarms_fujitsu(uchar num, uchar val) +{ + int rv = -1; + uchar idata[16]; + uchar rdata[16]; + int rlen; + ushort icmd; + uchar cc; + int vend_id, prod_id; + + get_mfgid(&vend_id,&prod_id); + if (vend_id != VENDOR_FUJITSU) return(LAN_ERR_NOTSUPPORT); + if (FUJITSU_PRODUCT_IS_iRMC_S1(prod_id)) return(LAN_ERR_NOTSUPPORT); + + /* set the specified LED number to val */ + icmd = CMD_FUJITSU_IRMCS2 | (IPMI_NET_FN_OEM_GROUP_RQ << 8); + idata[0] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF); + idata[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8; + idata[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16; + idata[3] = CMD_SPEC_FUJITSU_SET_ID_LED; + if (val == 0xFF) idata[4] = LED_ON; + else if (val == 0) idata[4] = LED_OFF; + else idata[4] = LED_BLINK; + rlen = sizeof(rdata); + rv = ipmi_cmd_mc(icmd, idata, 5, rdata, &rlen, &cc, fdebug); + if ((rv == 0) && (cc != 0)) rv = cc; + + return(rv); +} + +/* + * read_sel_fujitsu + * + * Fujitsu OEM + * http://manuals.ts.fujitsu.com/file/4390/irmc_s2-ug-en.pdf + * + * Request + * 0x2E - OEM network function + * 0xF5 - OEM cmd + * 0x?? - Fujitsu IANA (LSB first) + * 0x?? - Fujitsu IANA + * 0x?? - Fujitsu IANA + * 0x43 - Command Specifier + * 0x?? - Record ID (LSB first) + * 0x?? - Record ID ; 0x0000 = "first record", 0xFFFF = "last record" + * 0x?? - Offset (in response SEL text) + * 0x?? - MaxResponseDataSize (size of converted SEL data 16:n in response, + * maximum is 100, some only handle 64) + * + * Response + * 0xF5 - OEM cmd + * 0x?? - Completion code + * 0 0x?? - Fujitsu IANA (LSB first) + * 1 0x?? - Fujitsu IANA + * 2 0x?? - Fujitsu IANA + * 3 0x?? - Next Record ID (LSB) + * 4 0x?? - Next Record ID (MSB) + * 5 0x?? - Actual Record ID (LSB) + * 6 0x?? - Actual Record ID (MSB) + * 7 0x?? - Record type + * 8 0x?? - timestamp (LSB first) + * 9 0x?? - timestamp + * 10 0x?? - timestamp + * 11 0x?? - timestamp + * 12 0x?? - severity + * bit 7 - CSS component + * bit 6-4 - 000 = INFORMATIONAL + * 001 = MINOR + * 010 = MAJOR + * 011 = CRITICAL + * 1xx = unknown + * bit 3-0 - reserved + * 13 0x?? - data length (of the whole text) + * 14 0x?? - converted SEL data + * requested number of bytes starting at requested offset + * (MaxResponseDataSize-1 bytes of data) ..... + * 0x00 - trailing '\0' character + */ +int read_sel_fujitsu(uint16_t id, char *buf, int sz, char fdbg) +{ + int rv = -1; + uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; + uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; + char textbuf[IPMI_OEM_MAX_BYTES]; + int rs_len, text_len, data_len, chunk_len; + int max_read_length; + uint16_t actual_record_id = id; + uint32_t timestamp = 0; + // uint16_t next_record_id; + // uint8_t record_type; + uint8_t severity = 0; + uint8_t ccode; + char timestr[40]; + char *severity_text = NULL; + uint8_t offset = 0; + int vend_id, prod_id; + + fdebug = fdbg; + if (buf == NULL) return(rv); + max_read_length = IPMI_OEM_MAX_BYTES; + data_len = IPMI_OEM_MAX_BYTES; + /* This command requires admin privilege, so check and + print a warning if Fujitsu and not admin. */ + get_mfgid(&vend_id,&prod_id); + if (vend_id == VENDOR_FUJITSU) { /* connected to Fujitsu MC */ + int auth, priv; + if (FUJITSU_PRODUCT_IS_iRMC_S1(prod_id)) { + max_read_length = 32; + data_len = 80; + } + rv = get_lan_options(NULL,NULL,NULL,&auth,&priv,NULL,NULL,NULL); + if ((rv == 0) && (priv < 4)) { /*remote and not admin priv*/ + printf("*** Admin privilege (-V 4) required for full OEM decoding.\n"); + } + } + + memset(textbuf,0,sizeof(textbuf)); + bytes_rq[0] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF); + bytes_rq[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8; + bytes_rq[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16; + bytes_rq[3] = IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_SEL_ENTRY_LONG_TEXT; + bytes_rq[4] = (id & 0x00FF); + bytes_rq[5] = (id & 0xFF00) >> 8; + bytes_rq[7] = (uchar)max_read_length; + + while (offset < data_len) + { + bytes_rq[6] = offset; + /* Do not ask BMC for data beyond data_len, request partial if so. */ + if (offset + max_read_length > data_len) + bytes_rq[7] = data_len - offset; + rs_len = sizeof(bytes_rs); + rv = ipmi_cmdraw(IPMI_CMD_OEM_FUJITSU_SYSTEM, IPMI_NET_FN_OEM_GROUP_RQ, + BMC_SA, PUBLIC_BUS, BMC_LUN, + bytes_rq, 9, bytes_rs, &rs_len, &ccode, fdebug); + if (fdebug) printf("read_sel_fujitsu rv = %d, cc = %x\n", rv, ccode); + if (rv == 0 && ccode != 0) rv = ccode; + if (rv != 0) return(rv); + if (fdebug) dump_buf("read_sel_fujitsu data",bytes_rs,rs_len,1); + + if (offset == 0) { /* only need to set these on the first pass */ + actual_record_id = bytes_rs[5] + (bytes_rs[6] << 8); + timestamp = bytes_rs[8] + (bytes_rs[9] << 8) + + (bytes_rs[10] << 16) + (bytes_rs[11] << 24); + severity = (bytes_rs[12] >> 3); + data_len = bytes_rs[13]; + if (data_len > IPMI_OEM_MAX_BYTES) data_len = IPMI_OEM_MAX_BYTES; + } + chunk_len = rs_len - 14; + if ((offset + chunk_len) > IPMI_OEM_MAX_BYTES) + chunk_len = IPMI_OEM_MAX_BYTES - offset; + memcpy(&textbuf[offset],&bytes_rs[14],chunk_len); + offset += (uint8_t)chunk_len; + } + textbuf[IPMI_OEM_MAX_BYTES-1]='\0'; /*stringify*/ + text_len = strlen_(textbuf); + + switch (severity) { + case 0: severity_text = "INFORMATIONAL:"; break; + case 1: severity_text = "MINOR:"; break; + case 2: severity_text = "MAJOR:"; break; + case 3: severity_text = "CRITICAL:"; break; + case 4: + case 5: + case 6: + case 7: severity_text = ""; break; + case 8: severity_text = "INFORMATIONAL/CSS:"; break; + case 9: severity_text = "MINOR/CSS:"; break; + case 10: severity_text = "MAJOR/CSS:"; break; + case 11: severity_text = "CRITICAL/CSS:"; break; + case 12: + case 13: + case 14: + case 15: severity_text = "unknown/CSS:"; break; + } + + fmt_time(timestamp, timestr, sizeof(timestr)); + snprintf(buf, sz, "%u | %s | %s %s\n", (int)actual_record_id, + timestr, severity_text, textbuf); + return rv; +} + +/* + * decode_sel_fujitsu + * inputs: + * evt = the 16-byte IPMI SEL event + * outbuf = points to the output string buffer + * outsz = size of the output buffer + * outputs: + * rv = 0 if this event was successfully interpreted here, + * non-zero otherwise, to use default interpretations. + * outbuf = will contain the interpreted event text string (if rv==0) + */ +int decode_sel_fujitsu(uint8_t *evt, char *outbuf, int outsz, char fdesc, + char fdbg) +{ + int rv = -1; + uint16_t id; + uint8_t rectype; + int oemid; + uint32_t timestamp; + char mybuf[64]; + char *type_str = NULL; + char *gstr = NULL; + char *pstr = NULL; + ushort genid; + int sevid; + + fdebug = fdbg; + id = evt[0] + (evt[1] << 8); + if (freadok) { + rv = read_sel_fujitsu(id, outbuf, outsz, fdbg); + if (rv == 0) return(rv); /*success, done*/ + } + freadok = 0; /*not fujitsu or not local, so do not retry */ + + sevid = SEV_INFO; + /* instead try to decode some events manually */ + rectype = evt[2]; + timestamp = evt[3] + (evt[4] << 8) + (evt[5] << 16) + (evt[6] << 24); + genid = evt[7] | (evt[8] << 8); + if (rectype == 0xc1) { /* OEM type C1 */ + oemid = evt[7] + (evt[8] << 8) + (evt[9] << 16); + if (oemid == VENDOR_FUJITSU) { + type_str = "Fujitsu"; + gstr = "BMC "; + switch(evt[10]) { + case 0x09: + sprintf(mybuf,"iRMC S2 CLI/Telnet user %d login from %d.%d.%d.%d", + evt[11], evt[12], evt[13], evt[14], evt[15]); + break; + case 0x0a: + sprintf(mybuf,"iRMC S2 CLI/Telnet user %d logout from %d.%d.%d.%d", + evt[11], evt[12], evt[13], evt[14], evt[15]); + break; + default: + sprintf(mybuf,"iRMC S2 Event %02x %02x %02x %02x %02x %02x", + evt[10], evt[11], evt[12], evt[13], evt[14], evt[15]); + break; + } + format_event(id,timestamp, sevid, genid, type_str, + evt[10],NULL,mybuf,NULL,outbuf,outsz); + rv = 0; + } /*endif fujitsu oem */ + } else if (rectype == 0x02) { + type_str = "iRMC S2"; + gstr = "BMC "; + sprintf(mybuf,"%02x [%02x %02x %02x]", evt[12],evt[13],evt[14],evt[15]); + switch(evt[10]) { /*sensor type*/ + case 0xc8: + switch(evt[13]) { + case 0x29: + sprintf(mybuf,"CLI/Telnet user %d login", evt[15]); + break; + case 0x2a: + sprintf(mybuf,"CLI/Telnet user %d logout", evt[15]); + break; + case 0x21: + sprintf(mybuf,"Browser user %d login", evt[15]); + break; + case 0x22: + sprintf(mybuf,"Browser user %d logout", evt[15]); + break; + case 0x23: + sprintf(mybuf,"Browser user %d auto-logout", evt[15]); + break; + default: /*mybuf has the raw bytes*/ + break; + } + pstr = mybuf; + rv = 0; + break; + case 0xca: + if (evt[13] == 0x26) pstr = "Paging: Email - notification failed"; + else if (evt[13] == 0xa6) pstr = "Paging: Email - DNS failed"; + else pstr = mybuf; + rv = 0; + break; + case 0xe1: + sevid = SEV_MAJ; + if (evt[13] == 0x0f) pstr = "MC access degraded"; + else pstr = mybuf; + rv = 0; + break; + case 0xec: + if (evt[13] == 0xa0) { + sprintf(mybuf,"Firmware flash version %d.%d", + (evt[14] & 0x0f),evt[15]); + } + pstr = mybuf; + rv = 0; + break; + case 0xee: + type_str = "iRMC S2"; + if (evt[12] == 0x0a && evt[13] == 0x80) + pstr = "Automatic restart after power fail"; + else pstr = mybuf; + rv = 0; + break; + default: break; + } + if (rv == 0) { + format_event(id,timestamp, sevid, genid, type_str, + evt[11],NULL,pstr,NULL,outbuf,outsz); + /*evt[11] = sensor number */ + } + } + return rv; +} + + +/* + * Fujitsu iRMC S1 / iRMC S2 OEM Sensor logic + */ + +/* 0xDD */ +const char * const ipmi_sensor_type_oem_fujitsu_system_power_consumption[] = + { + /* EN 0x00 */ "System Power Consumption within Limit", + /* EN 0x01 */ "System Power Consumption above Warning Level", + /* EN 0x02 */ "System Power Consumption above Critical Level", + /* EN 0x03 */ "System Power Consumption limiting disabled", + NULL + }; +unsigned int ipmi_sensor_type_oem_fujitsu_system_power_consumption_max_index = 0x03; + + +/* 0xDE */ +const char * const ipmi_sensor_type_oem_fujitsu_memory_status[] = + { + /* EN 0x00 */ "Empty slot", + /* EN 0x01 */ "OK", + /* EN 0x02 */ "Reserved", + /* EN 0x03 */ "Error", + /* EN 0x04 */ "Fail", + /* EN 0x05 */ "Prefailure", + /* EN 0x06 */ "Reserved", + /* EN 0x07 */ "Unknown", + NULL + }; +unsigned int ipmi_sensor_type_oem_fujitsu_memory_status_max_index = 0x07; + +/* 0xDF */ +const char * const ipmi_sensor_type_oem_fujitsu_memory_config[] = + { + /* EN 0x00 */ "Normal", + /* EN 0x01 */ "Disabled", + /* EN 0x02 */ "Spare module", + /* EN 0x03 */ "Mirrored module", + /* EN 0x04 */ "RAID module", + /* EN 0x05 */ "Not Usable", + /* EN 0x06 */ "Unspecified state(6)", + /* EN 0x07 */ "Unspecified state(7)", + NULL + }; +unsigned int ipmi_sensor_type_oem_fujitsu_memory_config_max_index = 0x07; + +/* 0xE1 */ +const char * const ipmi_sensor_type_oem_fujitsu_memory[] = + { + /* EN 0x00 */ "Non Fujitsu memory module detected", + /* EN 0x01 */ "Memory module replaced", + /* EN 0x02 */ "Fatal general memory error", + /* EN 0x03 */ "Recoverable general memory error", + /* EN 0x04 */ "Recoverable ECC memory error", + /* EN 0x05 */ "Recoverable CRC memory error", + /* EN 0x06 */ "Fatal CRC memory error", + /* EN 0x07 */ "Recoverable thermal memory event", + /* EN 0x08 */ "Fatal thermal memory error", + /* EN 0x09 */ "Too many correctable memory errors", + /* EN 0x0A */ "Uncorrectable Parity memory error", + /* EN 0x0B */ "Memory Modules swapped", + /* EN 0x0C */ "Memory Module moved", + /* EN 0x0D */ "Memory removed", + /* EN 0x0E */ "Memory Re-inserted", + /* EN 0x0F */ "Memory module(s) changed", + NULL + }; +unsigned int ipmi_sensor_type_oem_fujitsu_memory_max_index = 0x0F; + +/* 0xE3 */ +const char * const ipmi_sensor_type_oem_fujitsu_hw_error[] = + { + /* EN 0x00 */ "TPM Error", + /* EN 0x01 */ "Reserved", + /* EN 0x02 */ "No usable CPU", + NULL + }; +unsigned int ipmi_sensor_type_oem_fujitsu_hw_error_max_index = 0x02; + +/* 0xE4 */ +const char * const ipmi_sensor_type_oem_fujitsu_sys_error[] = + { + /* EN 0x00 */ "System configuration Data error", + /* EN 0x01 */ "Resource Conflict", /* Slot in EventData3 */ + /* EN 0x02 */ "IRQ not configured", /* Slot in EventData3 */ + /* EN 0x03 */ "Device node allocation error", /* Device in EventData3 */ + /* EN 0x04 */ "Expansion ROM Slot not initialized", /* Slot in EventData3 */ + NULL + }; +unsigned int ipmi_sensor_type_oem_fujitsu_sys_error_max_index = 0x04; + +/* 0xE6 */ +const char * const ipmi_sensor_type_oem_fujitsu_fan_status[] = + { + /* EN 0x00 */ "FAN on, running", + /* EN 0x01 */ "FAN failed", + /* EN 0x02 */ "FAN prefailure", + /* EN 0x03 */ "Redundant FAN failed", + /* EN 0x04 */ "FAN not manageable", + /* EN 0x05 */ "FAN not installed", + /* EN 0x06 */ "FAN unspecified state(6)", + /* EN 0x07 */ "FAN in init phase", + NULL + }; +unsigned int ipmi_sensor_type_oem_fujitsu_fan_status_max_index = 0x07; + +/* 0xE8 */ +const char * const ipmi_sensor_type_oem_fujitsu_psu_status[] = + { + /* EN 0x00 */ "Power supply - Not present", + /* EN 0x01 */ "Power supply - OK", + /* EN 0x02 */ "Power supply - Failed", + /* EN 0x03 */ "Redundant power supply - AC failed", + /* EN 0x04 */ "Redundant power supply - DC failed", + /* EN 0x05 */ "Power supply - Critical Temperature", + /* EN 0x06 */ "Power supply - Not manageable", + /* EN 0x07 */ "Power supply - Fan failure predicted", + /* EN 0x08 */ "Power supply - Fan failed", + /* EN 0x09 */ "Power supply - Power Save Mode", + NULL + }; +unsigned int ipmi_sensor_type_oem_fujitsu_psu_status_max_index = 0x09; + +/* 0xE9 */ +const char * const ipmi_sensor_type_oem_fujitsu_psu_redundancy[] = + { + /* EN 0x00 */ "Power Supply - redundancy present", + NULL + }; +unsigned int ipmi_sensor_type_oem_fujitsu_psu_redundancy_max_index = 0x00; + +/* 0xEC */ +const char * const ipmi_sensor_type_oem_fujitsu_flash[] = + { + /* EN 0x00 */ "Online firmware flash", + /* EN 0x01 */ "Online firmware flash: reboot", + /* EN 0x02 */ "BIOS TFTP Flash: OK", + /* EN 0x03 */ "BIOS TFTP Flash: failed", + /* EN 0x04 */ "iRMC TFTP Flash: OK", + /* EN 0x05 */ "iRMC TFTP Flash: failed", + NULL + }; +unsigned int ipmi_sensor_type_oem_fujitsu_flash_max_index = 0x05; + +/* 0xEF */ +const char * const ipmi_sensor_type_oem_fujitsu_config_backup[] = + { + /* EN 0x00 */ "Chassis IDPROM: Motherboard Exchange detected", + /* EN 0x01 */ "Chassis IDPROM: Read or Write error", + /* EN 0x02 */ "Chassis IDPROM: Restore successful", + /* EN 0x03 */ "Chassis IDPROM: Restore failed", + /* EN 0x04 */ "Chassis IDPROM: Backup successful", + /* EN 0x05 */ "Chassis IDPROM: Backup failed", + /* EN 0x06 */ "Chassis IDPROM: Feature disabled", + /* EN 0x07 */ "Chassis IDPROM: Function Not Available", + /* EN 0x08 */ "Reserved", + /* EN 0x09 */ "Reserved", + /* EN 0x0A */ "Reserved", + /* EN 0x0B */ "Reserved", + /* EN 0x0C */ "Reserved", + /* EN 0x0D */ "Reserved", + /* EN 0x0E */ "Reserved", + /* EN 0x0F */ "NVRAM defaults loaded", + NULL + }; +unsigned int ipmi_sensor_type_oem_fujitsu_config_backup_max_index = 0x0F; + +/* 0xEF */ +const char * const ipmi_sensor_type_oem_fujitsu_i2c_bus[] = + { + /* EN 0x00 */ "I2C Bus Error", + /* EN 0x01 */ "I2C Bus OK", + /* EN 0x02 */ "I2C Bus Disabled", + /* EN 0x03 */ "I2C Bus Failed", + NULL + }; +unsigned int ipmi_sensor_type_oem_fujitsu_i2c_bus_max_index = 0x03; + +static char * get_array_message (unsigned int offset, + unsigned int offset_max, + const char * const string_array[]) +{ + if (offset > offset_max) return("unknown"); + return((char *)string_array[offset]); +} + + +static char *get_oem_reading_string(uchar sensor_type, uchar offset) +{ + char * pstr = ""; + /* + * OEM Interpretation + * Fujitsu iRMC S1 / iRMC S2 + */ + switch (sensor_type) + { + case IPMI_SENSOR_TYPE_OEM_FUJITSU_I2C_BUS: + return (get_array_message (offset, + ipmi_sensor_type_oem_fujitsu_i2c_bus_max_index, + ipmi_sensor_type_oem_fujitsu_i2c_bus)); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_SYSTEM_POWER_CONSUMPTION: + return (get_array_message (offset, + ipmi_sensor_type_oem_fujitsu_system_power_consumption_max_index, + ipmi_sensor_type_oem_fujitsu_system_power_consumption)); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_MEMORY_STATUS: + return (get_array_message (offset, + ipmi_sensor_type_oem_fujitsu_memory_status_max_index, + ipmi_sensor_type_oem_fujitsu_memory_status)); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_MEMORY_CONFIG: + return (get_array_message (offset, + ipmi_sensor_type_oem_fujitsu_memory_config_max_index, + ipmi_sensor_type_oem_fujitsu_memory_config)); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_MEMORY: + return (get_array_message (offset, + ipmi_sensor_type_oem_fujitsu_memory_max_index, + ipmi_sensor_type_oem_fujitsu_memory)); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_HW_ERROR: + return (get_array_message (offset, + ipmi_sensor_type_oem_fujitsu_hw_error_max_index, + ipmi_sensor_type_oem_fujitsu_hw_error)); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_SYS_ERROR: + return (get_array_message (offset, + ipmi_sensor_type_oem_fujitsu_sys_error_max_index, + ipmi_sensor_type_oem_fujitsu_sys_error)); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_FAN_STATUS: + return (get_array_message (offset, + ipmi_sensor_type_oem_fujitsu_fan_status_max_index, + ipmi_sensor_type_oem_fujitsu_fan_status)); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_PSU_STATUS: + return (get_array_message (offset, + ipmi_sensor_type_oem_fujitsu_psu_status_max_index, + ipmi_sensor_type_oem_fujitsu_psu_status)); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_PSU_REDUNDANCY: + return (get_array_message (offset, + ipmi_sensor_type_oem_fujitsu_psu_redundancy_max_index, + ipmi_sensor_type_oem_fujitsu_psu_redundancy)); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_FLASH: + return (get_array_message (offset, + ipmi_sensor_type_oem_fujitsu_flash_max_index, + ipmi_sensor_type_oem_fujitsu_flash)); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_CONFIG_BACKUP: + return (get_array_message (offset, + ipmi_sensor_type_oem_fujitsu_config_backup_max_index, + ipmi_sensor_type_oem_fujitsu_config_backup)); + /* These are reserved */ + case IPMI_SENSOR_TYPE_OEM_FUJITSU_COMMUNICATION: + case IPMI_SENSOR_TYPE_OEM_FUJITSU_EVENT: + default: + break; + } + return(pstr); +} + + +static char *get_oem_sensor_type_string (uint8_t sensor_type) +{ + switch (sensor_type) { + case IPMI_SENSOR_TYPE_OEM_FUJITSU_I2C_BUS : return ("OEM I2C Bus"); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_SYSTEM_POWER_CONSUMPTION: return ("OEM Power Consumption"); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_MEMORY_STATUS : return ("OEM Memory Status"); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_MEMORY_CONFIG : return ("OEM Memory Config"); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_MEMORY : return ("OEM Memory"); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_FAN_STATUS : return ("OEM Fan Status"); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_PSU_STATUS : return ("OEM PSU Status"); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_PSU_REDUNDANCY: return ("OEM PSU Redundancy"); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_COMMUNICATION : return ("OEM Communication"); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_FLASH : return ("OEM Flash"); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_EVENT : return ("OEM Event"); + case IPMI_SENSOR_TYPE_OEM_FUJITSU_CONFIG_BACKUP : return ("OEM Config Backup"); + default : break; /* fall into generic case below */ + } + return (""); +} + + +int decode_sensor_fujitsu(uchar *sdr,uchar *reading,char *pstring, int slen) +{ + int rv = -1; + char *typestr = NULL; + char *readstr = NULL; + uchar stype; + int vend_id, prod_id; + + /* Only get here if vend_id == VENDOR_FUJITSU */ + if (sdr == NULL || reading == NULL) return(rv); + if (pstring == NULL || slen == 0) return(rv); + stype = sdr[12]; + typestr = get_oem_sensor_type_string(stype); + + get_mfgid(&vend_id,&prod_id); + if (vend_id == IPMI_IANA_ENTERPRISE_ID_FUJITSU + && (prod_id >= IPMI_FUJITSU_PRODUCT_ID_MIN + && prod_id <= IPMI_FUJITSU_PRODUCT_ID_MAX)) { + readstr = get_oem_reading_string(stype,reading[2]); + if (readstr != NULL && (readstr[0] != 0)) rv = 0; + } else readstr = ""; + snprintf (pstring, slen, "%s = %s",typestr,readstr); + return(rv); +} + +/* end oem_fujitsu.c */ |