diff -rup base_code/lib/ipmi_delloem.c Cmds_sel_minus_powermonitoring/lib/ipmi_delloem.c --- base_code/lib/ipmi_delloem.c 2008-02-21 04:10:00.000000000 -0600 +++ Cmds_sel_minus_powermonitoring/lib/ipmi_delloem.c 2008-04-09 01:54:18.000000000 -0500 @@ -0,0 +1,808 @@ +/* + Copyright (c) 2007 Dell Inc +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /*( _MIN and _MAX*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/*------------ipmi headers------------------*/ +#include +#include +#include +#include +#include +#include +/*--------------time header-----------------*/ +#include + + +extern int read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, + uint8_t id,uint32_t offset, uint32_t length, uint8_t *frubuf); +extern char *get_fru_area_str(uint8_t * data, uint32_t * offset); +uint16_t ipmi_sel_get_record(struct ipmi_intf * intf, uint16_t curr_id, uint8_t* sel_entry); +int +ipmi_sdr_reserve(struct ipmi_intf *intf, uint16_t * reserve_id); +int ipmi_sdr_get(struct ipmi_intf *intf, uint16_t reserveId, uint8_t* datapt, uint16_t recordId); +SDRType * ipmi_sdr_get_first(void* x); +SDRType * ipmi_sdr_get_next(SDRType *w, void *x); +int ipmi_sel_sysinfo(struct ipmi_intf *intf, DECODING_METHOD *method); +int ipmi_sel_print(struct ipmi_intf * intf, uint16_t count, int printOption); +static uint16_t +ipmi_sel_reserve(struct ipmi_intf * intf); +SDRType* ipmi_sdr_get_test(struct ipmi_intf *intf, uint16_t reserveId, uint8_t* datapt, uint16_t recordId); +SDRType* ipmi_sdr_get_test2(struct ipmi_intf *intf, uint16_t reserveId, uint8_t* datapt, uint16_t recordId); +SDRType* ipmi_sdr_get_test3(struct ipmi_intf *intf, uint16_t reserveId, uint8_t* datapt, uint16_t recordId); +static void +ipmi_time_to_str(time_t rawTime, char* strTime); +static char * +ipmi_sel_timestamp(uint32_t stamp); +static int make_int(const char *str, int *value); +static int ipmi_build_sdr_first(struct ipmi_intf *intf, uint8_t *data); +int ipmi_build_sdr_next(struct ipmi_intf *intf, uint8_t *sdr_in, uint8_t *data); +static int ipmi_sdr_build_table(struct ipmi_intf *intf); +SDRType* sdr_get_first(); +SDRType* sdr_get_next(SDRType* pPreviousSDR); + + +uint8_t data[64]; + +static const struct valstr threshold_vals[] = { + {UPPER_NON_RECOV_SPECIFIED, "Upper Non-Recoverable"}, + {UPPER_CRIT_SPECIFIED, "Upper Critical"}, + {UPPER_NON_CRIT_SPECIFIED, "Upper Non-Critical"}, + {LOWER_NON_RECOV_SPECIFIED, "Lower Non-Recoverable"}, + {LOWER_CRIT_SPECIFIED, "Lower Critical"}, + {LOWER_NON_CRIT_SPECIFIED, "Lower Non-Critical"}, + {0x00, NULL}, +}; + +typedef struct _SDRList +{ + uint8_t data[MAX_SDR_SIZE]; + uint8_t bIsLast; +} SDRList; + + +SDRList SDR[MAX_SDR_ENTRIES]; +uint16_t currentSDR; +uint16_t totalSDRCount; +static char* ipmi_get_bib_info(uint8_t * fru_data, uint8_t bib_type) +{ + uint16_t bib_offset, bib_info_area, bib_length, bib_end, length; + uint32_t offset; + char * bib_data; + + /* get BIB fields */ + if (fru_data[0x66] == 0xc3) { + bib_offset = (fru_data[0x68] << 8) | fru_data[0x67]; + } else if (fru_data[0x69] == 0xc3) { + bib_offset = (fru_data[0x6B] << 8) | fru_data[0x6A]; + } + + + bib_info_area = bib_offset + 6; + bib_length = (fru_data[bib_info_area+2]<<8) | fru_data[bib_info_area+1]; + bib_end = bib_info_area + bib_length; + + /* find BIB field */ + offset = bib_info_area; + while ((fru_data[offset] != bib_type) && (offset <= bib_end)) { + offset += fru_data[offset+1]+3; + } + if (fru_data[offset] == bib_type) { /* bib info found */ + if (bib_type == BIB_TYPE_PDRODUCT_MODEL) { + length = fru_data[offset+1]-6; + } else { + length = fru_data[offset+1]; + } + + bib_data = malloc(length+1); + memset(bib_data, 0, length+1); + if (bib_type == BIB_TYPE_PDRODUCT_MODEL) { + memcpy(bib_data, &fru_data[offset+8], length); + } else { + memcpy(bib_data, &fru_data[offset+2], length); + } + bib_data[length] = '\0'; + /*printf("BIOS version: %s\n", bib_data);*/ + } else { + bib_data = NULL; + } + return bib_data; +} + + +int ipmi_sel_print(struct ipmi_intf * intf, uint16_t count, int printOption) +{ + CSLFUSERAPI pfnApiList; + DECODING_METHOD method; + unsigned char severity; + uint8_t index = 1; + int status = COMMON_STATUS_BAD_PARAMETER; + unsigned short TimeStrSize = LOG_DATE_STR_SIZE; + unsigned short DescriptionStrSize = EVENT_DESC_STR_SIZE; + uint16_t curr_id = 0; + uint16_t next_id; + uint8_t sel_entry[0xff]; + uint8_t test; + uint16_t last = 0; + uint16_t totalEntries = 0; + uint16_t start_id = 0; + uint16_t start = 1; + int rc; + int error_count; + + + char LogTimeString[LOG_DATE_STR_SIZE]; + char DateString[LOG_DATE_STR_SIZE]; + char DescriptionString[EVENT_DESC_STR_SIZE]; + + rc = ipmi_sdr_build_table(intf); + if (rc == -1) { + return rc; + } + + struct ipmi_rs * rsp; + struct ipmi_rq req; + + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.cmd = IPMI_CMD_GET_SEL_INFO; + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + lprintf(LOG_ERR, " Error getting sel info"); + return -1; + } else if (rsp->ccode > 0) { + lprintf(LOG_ERR, " Error getting sel info: %s", + val2str(rsp->ccode, completion_code_vals)); + return -1; + } + + totalEntries = ((rsp->data[2] << 8) | rsp->data[1]); + + if (printOption == SEL_PRINT_FIRST) { + + if(count > totalEntries) + last = totalEntries; + else + last = count; + } + if (printOption == SEL_PRINT_LAST){ + + if (count <= totalEntries) + { + start_id = totalEntries - count; + start = start_id+1; + /*added here Meghna DF:170716*/ + index = start; + last = totalEntries; + } + } + if(printOption == SEL_PRINT_ALL){ + + last = totalEntries; + } + + + /* set decoding method */ + rc = ipmi_sel_sysinfo(intf, &method); + if (rc == -1) { + return -1; + } + + status = CSLFSetDecodingMethod(&method); + if (COMMON_STATUS_SUCCESS == status) { + /* clear API structure */ + memset((void*) &pfnApiList, 0, sizeof(CSLFUSERAPI)); + pfnApiList.GetFirstSDR = sdr_get_first; + pfnApiList.GetNextSDR = sdr_get_next; + + CSLFAttach(&pfnApiList); + while (start <= last) { + + error_count = 0; + do { + next_id = ipmi_sel_get_record(intf, start, sel_entry); + error_count ++; + if (next_id == NULL) { + printf("SDR is NULL and error_count is %d\n", error_count); + } + } while ( (next_id == NULL) && (error_count < 3) ); + + if (next_id == NULL) { + /*error message handled in ipmi_sel_get_record*/ + return -1; + } + start = next_id; + { + + LogTimeString[0] = 0; + DateString[0] = 0; + DescriptionString[0] = 0; + + + status = CSLFSELEntryToStr( + (void*)sel_entry, + 0, + LogTimeString, + &TimeStrSize, + DescriptionString, + &DescriptionStrSize, + &severity, + (void*)intf); + + + /*Convert date string*/ + status = CSLFSELUnixToCTime(LogTimeString, DateString); + + + printf("Severity : %s\n", g_StatusTable[severity]); + printf("Date and Time : %s\n", DateString); + printf("Description : %s\n\n", DescriptionString); + + } + } + CSLFDetach(); + } + return 0; +} + +static int make_int(const char *str, int *value) +{ + char *tmp=NULL; + *value = strtol(str,&tmp,0); + if ( tmp-str != strlen(str) ) + { + return -1; + } + return 0; +} + +static char * +ipmi_sel_timestamp(uint32_t stamp) +{ + static char tbuf[40]; + time_t s = (time_t)stamp; + memset(tbuf, 0, 40); + strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", gmtime(&s)); /* edited here*/ + return tbuf; +} + +uint16_t ipmi_sel_get_record(struct ipmi_intf * intf, uint16_t curr_id, uint8_t* sel_entry) +{ + struct ipmi_rq req; + struct ipmi_rs * rsp; + uint8_t msg_data[6]; + uint16_t next; + int data_count; + + memset(msg_data, 0, 6); + msg_data[0] = 0x00; /* no reserve id, not partial get */ + msg_data[1] = 0x00; + msg_data[2] = curr_id & 0xff; + msg_data[3] = (curr_id >> 8) & 0xff; + msg_data[4] = 0x00; /* offset */ + msg_data[5] = 0xff; /* length */ + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.cmd = IPMI_CMD_GET_SEL_ENTRY; + req.msg.data = msg_data; + req.msg.data_len = 6; + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + lprintf(LOG_ERR, " Error getting sel record"); + return NULL; + } else if (rsp->ccode > 0) { + lprintf(LOG_ERR, " Error getting sel record: %s", + val2str(rsp->ccode, completion_code_vals)); + return NULL; + } + + /* save next entry id */ + next = (rsp->data[1] << 8) | rsp->data[0]; + + memcpy((void*)sel_entry, (void*)&rsp->data[2], 16); + + + + + + return next; +} + +int ipmi_sel_sysinfo(struct ipmi_intf *intf, DECODING_METHOD *method) +{ + struct ipmi_rs *rsp; + struct ipmi_rq req; + uint8_t data_in[16]; + struct ipm_devid_rsp * dev_id; + + memset(&req, 0, sizeof (req)); + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.cmd = BMC_GET_DEVICE_ID; + req.msg.data = NULL; + req.msg.data_len = 0; + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + lprintf(LOG_ERR, " Error getting system info"); + return -1; + } else if (rsp->ccode > 0) { + lprintf(LOG_ERR, " Error getting system info: %s", + val2str(rsp->ccode, completion_code_vals)); + return -1; + } + + method->completionCode = rsp->ccode; + method->deviceID = rsp->data[0]; + method->deviceRevision = rsp->data[1]; + method->firmwareMajor = rsp->data[2]; + method->firmwareMinor = rsp->data[3]; + method->ipmiVersion = rsp->data[4]; + method->supportFlags = rsp->data[5]; + method->manufactureID[0]= rsp->data[6]; + method->manufactureID[1]= rsp->data[7]; + method->manufactureID[2]= rsp->data[8]; + method->productID[0] = rsp->data[9]; + method->productID[1] = rsp->data[10]; + method->auxiliary[0] = rsp->data[11]; + method->auxiliary[1] = rsp->data[12]; + method->auxiliary[2] = rsp->data[13]; + method->auxiliary[3] = rsp->data[14]; + + return 1; + + +} + +/* ipmi_sdr_get_reservation - Obtain SDR reservation ID + * + * @intf: ipmi interface + * @reserve_id: pointer to short int for storing the id + * + * returns 0 on success + * returns -1 on error + */ +int +ipmi_sdr_reserve(struct ipmi_intf *intf, uint16_t * reserve_id) +{ + struct ipmi_rs *rsp; + struct ipmi_rq req; + + /* obtain reservation ID */ + memset(&req, 0, sizeof (req)); + + req.msg.netfn = IPMI_NETFN_STORAGE; + + req.msg.cmd = GET_SDR_RESERVE_REPO; + rsp = intf->sendrecv(intf, &req); + /* be slient for errors, they are handled by calling function */ + if (rsp == NULL) + return -1; + if (rsp->ccode > 0) + return -1; + + + *reserve_id = ((struct sdr_reserve_repo_rs *) &(rsp->data))->reserve_id; + lprintf(LOG_DEBUG, "SDR reservation ID %04x", *reserve_id); + + return 0; +} + +/* Read all SDR data into memory */ +static int ipmi_sdr_build_table(struct ipmi_intf *intf) +{ + SDRType* sdr_cur; + SDRType* sdr_next; + IPMISDR current; + IPMISDR next; + IPMISDR sdr_out; + sdr_cur = ¤t; + sdr_next = &next; + int rc; + int i = 0; + int j; + uint8_t* test; + int count; + + count = 0; + do { + rc = ipmi_build_sdr_first(intf, SDR[0].data); + count ++; + } while ( (rc == -1) && (count < 3) ); + if (rc == -1) { + printf("Cannot access SDR info:rc %x\n", rc); + return rc; + } + + i = 0; + + do { + + count = 0; + do { + rc = ipmi_build_sdr_next(intf, SDR[i].data, SDR[i+1].data); + count++; + } while ( (rc == -1) && (count < 3) ); + if (rc == -1) { + return rc; + } + + i++; + }while ((rc != 1) && (i= MAX_SDR_ENTRIES) { + printf("Error: SDR number limit exceeded.\n"); + return -1; + } + + totalSDRCount = i; + +} + +static int ipmi_build_sdr_first(struct ipmi_intf *intf, uint8_t *data) +{ + uint16_t reserve_id; + int rc; + SDRType* sdr_out; + uint8_t* test; + + rc = ipmi_sdr_reserve(intf, &reserve_id); + if (rc == -1) { + return rc; + } + + rc = ipmi_sdr_get(intf, reserve_id, data, 0x00); + + + + return rc; + +} + +int ipmi_build_sdr_next(struct ipmi_intf *intf, uint8_t *sdr_in, uint8_t *data) +{ + uint16_t reserve_id, record_id; + uint8_t rc; + SDRType *sdr_out; + struct ipmi_rs *rsp; + struct ipmi_rq req; + uint8_t msg_data[6]; + + + + + memset(&req, 0, sizeof (req)); + + + + /* Get next record ID */ + memset(msg_data, 0, 6); + msg_data[0] = 0x00; + msg_data[1] = 0x00; + msg_data[2] = sdr_in[0]; /* record id */ + msg_data[3] = sdr_in[1]; /* record id */ + msg_data[4] = 0x00; /* offset */ + msg_data[5] = 0x0f; /* length */ + + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.cmd = GET_SDR; + req.msg.data = msg_data; + req.msg.data_len = 6; + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + return -1; + } else if (rsp->ccode > 0) { + return -1; + } + + record_id = (rsp->data[1] << 8) | rsp->data[0]; + + if (record_id != 0xFFFF) { + + rc = ipmi_sdr_reserve(intf, &reserve_id); + if (rc == -1) { + return rc; + } + + rc = ipmi_sdr_get(intf, reserve_id, data, record_id); + if (rc == -1) { + return rc; + } + + return 0; + } else { + return 1; + } + + +} + + +int ipmi_sdr_get(struct ipmi_intf *intf, uint16_t reserveId, uint8_t* datapt, uint16_t recordId) +{ + #define MAX_BUF_SIZE 16 + + struct ipmi_rs *rsp; + struct ipmi_rq req; + uint8_t msg_data[6]; + uint16_t curr_id = 0; + uint8_t orgremain; + uint8_t length; + uint8_t offset; + uint8_t remain; + int i; + int rc; + + memset(&req, 0, sizeof (req)); + + + /* Get header info */ + memset(msg_data, 0, 6); + msg_data[0] = reserveId & 0xff; + msg_data[1] = (reserveId >> 8) & 0xff; + msg_data[2] = recordId & 0xff; + msg_data[3] = (recordId >> 8) & 0xff; + msg_data[4] = 0x00; /* offset */ + msg_data[5] = 0x05; /* length */ + + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.cmd = GET_SDR; + req.msg.data = msg_data; + req.msg.data_len = 6; + + + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + return -1; + } else if (rsp->ccode > 0) { + return -1; + } + + memcpy((uint8_t*)datapt, (uint8_t*)rsp->data + 2, 5); + + + + orgremain = datapt[4]; + remain = datapt[4]; + offset = 5; + while (remain > 0) { + if (remain < MAX_BUF_SIZE) { + length = remain; + } else { + length = MAX_BUF_SIZE; + } + memset(msg_data, 0, 6); + msg_data[0] = reserveId & 0xff; + msg_data[1] = (reserveId >> 8) & 0xff; + msg_data[2] = recordId & 0xff; + msg_data[3] = (recordId >> 8) & 0xff; + msg_data[4] = offset; /* offset */ + msg_data[5] = length; /* length */ + + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.cmd = GET_SDR; + req.msg.data = msg_data; + req.msg.data_len = 6; + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + return -1; + } else if (rsp->ccode > 0) { + return -1; + } + + memcpy(datapt+offset, rsp->data + 2, length); + + offset += length; + remain -= length; + + + } + + + + + rc = 0; + return rc; + +} + +SDRType* sdr_get_first() +{ + currentSDR = 0; + return ((SDRType*)(SDR[0].data)); +} + +SDRType* sdr_get_next(SDRType* pPreviousSDR) +{ + if ((currentSDR + 1) < totalSDRCount) { + currentSDR++; + return ((SDRType*)(SDR[currentSDR].data)); + } else { + return NULL; + } +} + + + + + +static uint16_t +ipmi_sel_reserve(struct ipmi_intf * intf) +{ + struct ipmi_rs * rsp; + struct ipmi_rq req; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.cmd = IPMI_CMD_RESERVE_SEL; + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + lprintf(LOG_WARN, "Unable to reserve SEL"); + return 0; + } + if (rsp->ccode > 0) { + printf("Unable to reserve SEL: %s", + val2str(rsp->ccode, completion_code_vals)); + return 0; + } + + return (rsp->data[0] | (rsp->data[1] << 8)); +} + + + +static void +ipmi_time_to_str(time_t rawTime, char* strTime) +{ + struct tm* tm; + char *temp; + + tm = gmtime(&rawTime); + temp = asctime(tm); + + strcpy(strTime,temp); + + +} + + + +static void +ipmi_sel_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " sel list"); + lprintf(LOG_NOTICE, " When used without any arguments, entire contents of SEL are displayed"); + lprintf(LOG_NOTICE, " first "); + lprintf(LOG_NOTICE, " Displays first (least recent) count entries in SEL. Count of 0 will display all entries"); + lprintf(LOG_NOTICE, " last "); + lprintf(LOG_NOTICE, " Displays last (most recent) count entries in SEL. Count of 0 will display all entries"); + lprintf(LOG_NOTICE, ""); +} + + + +static void +usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "usage: delloem [option...]"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "commands:"); + lprintf(LOG_NOTICE, " sel"); + lprintf(LOG_NOTICE, " sensor"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, "For help on individual commands type:"); + lprintf(LOG_NOTICE, "delloem help"); + +} +int +ipmi_delloem_main(struct ipmi_intf * intf, int argc, char ** argv) +{ + int rc = 0; + int current_arg = 0; + + if (argc == 0 || strncmp(argv[0], "help\0", 5) == 0) + { + usage(); + return 0; + } + /* start sel processing*/ + else if (strncmp(argv[current_arg], "sel\0", 4) == 0) { + current_arg++; + if (argc == 1) { + + rc = ipmi_sel_print(intf, 0xFFFF,0); + } + else if (strncmp(argv[current_arg], "list\0", 5) == 0) { + current_arg++; + int count = 0; + char *countstr = NULL; + if (argv[current_arg] == NULL) { + rc = ipmi_sel_print(intf, 0xFFFF,0); + } + else if ((strncmp(argv[current_arg], "first\0", 6) == 0) || + (argc == 3)) { + current_arg++; + countstr = argv[current_arg]; + if(argc == 3){ + countstr = argv[2]; + } + if (countstr) { + if (make_int(countstr,&count) < 0) { + lprintf(LOG_ERR, "Numeric argument required; got '%s'", + countstr); + return -1; + } + } + + if (count == 0) { + rc = ipmi_sel_print(intf, 0xFFFF,0); + } else { + rc = ipmi_sel_print(intf, count, 1); + } + } else if (strncmp(argv[current_arg], "last\0", 5) == 0) { + current_arg++; + countstr = argv[current_arg]; + if (countstr) { + if (make_int(countstr,&count) < 0) { + lprintf(LOG_ERR, "Numeric argument required; got '%s'", + countstr); + return -1; + } + } + if (count == 0) { + rc = ipmi_sel_print(intf, 0xFFFF,0); + } else { + rc = ipmi_sel_print(intf, count, 2); + } + + } + + }else{ + ipmi_sel_usage(); + return -1; + } + /*Powermanagement report processing*/ + + } else if (strncmp(argv[current_arg], "test\0", 5) == 0) { + rc = ipmi_sdr_build_table(intf); + } + else { + usage(); + return -1; + } + + return rc; +} + diff -rup base_code/src/ipmitool.c Cmds_sel_minus_powermonitoring/src/ipmitool.c --- base_code/src/ipmitool.c 2008-02-04 03:27:51.000000000 -0600 +++ Cmds_sel_minus_powermonitoring/src/ipmitool.c 2008-02-04 03:27:14.000000000 -0600 @@ -103,6 +103,7 @@ struct ipmi_cmd ipmitool_cmd_list[] = { { ipmi_picmg_main, "picmg", "Run a PICMG/ATCA extended cmd"}, { ipmi_fwum_main, "fwum", "Update IPMC using Kontron OEM Firmware Update Manager" }, { ipmi_firewall_main,"firewall","Configure Firmware Firewall" }, + { ipmi_delloem_main, "delloem", "OEM Commands for Dell systems" }, #ifdef HAVE_READLINE { ipmi_shell_main, "shell", "Launch interactive IPMI shell" }, #endif