diff -rup patch1/lib/ipmi_delloem.c ../ipmitool-1.8.9-baseline-13-upstream1/lib/ipmi_delloem.c --- patch1/lib/ipmi_delloem.c 2008-02-21 02:32:07.000000000 -0600 +++ ../ipmitool-1.8.9-baseline-13-upstream1/lib/ipmi_delloem.c 2008-02-21 04:20:52.000000000 -0600 @@ -19,9 +19,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -42,6 +39,15 @@ 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); + +static void +ipmi_sysinfo_print_board(struct ipmi_intf * intf, struct fru_info * fru, + uint8_t id, uint32_t offset, uint8_t ipmi_version); +static int ipmi_sysinfo_get_tag(struct ipmi_intf * intf, char* tagstring, uint8_t tag_type, uint8_t length); +extern int ipmi_sel_get(struct ipmi_intf * intf, uint16_t id); +static int +ipmi_sysinfo_fru(struct ipmi_intf * intf, uint8_t id, uint8_t ipmi_version); +static char* ipmi_get_bib_info(uint8_t * fru_data, uint8_t bib_type); 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); @@ -381,7 +387,7 @@ ipmi_lcd_set_single_line_text (struct ip bytes_to_store = MIN(bytes_to_store, IPMI_DELL_LCD_STRING_LENGTH_MAX); for (ii = 0; ii < 4; ii++) { - /* first block, 2 bytes parms and 14 bytes data*/ + /*first block, 2 bytes parms and 14 bytes data*/ if (0 == ii) { int size_of_copy = MIN((bytes_to_store - bytes_stored), IPMI_DELL_LCD_STRING1_SIZE); @@ -393,7 +399,7 @@ ipmi_lcd_set_single_line_text (struct ip req.msg.data = data; data[0] = IPMI_DELL_LCD_STRING_SELECTOR; data[1] = ii; /* block number to use (0)*/ - data[2] = 0; /* string encoding*/ + data[2] = 0; /*string encoding*/ data[3] = bytes_to_store; /* total string length*/ memcpy (data+4, text+bytes_stored, size_of_copy); bytes_stored += size_of_copy; @@ -442,7 +448,7 @@ ipmi_lcd_set_text(struct ipmi_intf * int req.msg.data = data; data[0] = 0; /* get parameter*/ data[1] = IPMI_DELL_LCD_GET_CAPS_SELECTOR; - data[2] = 0; /* set selector (n/a)*/ + data[2] = 0; /* set selector (n/a)*/ data[3] = 0; /* block selector (n/a)*/ rsp = intf->sendrecv(intf, &req); @@ -490,6 +496,422 @@ ipmi_lcd_configure (struct ipmi_intf * i +/* prints the 'id' portion of the sysinfo command + */ +static int +ipmi_sysinfo_id(struct ipmi_intf * intf, int type) +{ + struct ipmi_rs * rsp = NULL; + struct ipmi_rq req = {0}; + int rc = 0; + struct ipm_devid_rsp * dev_id; + struct sdr_repo_info_rs * repo_info; + uint8_t ipmi_version; + // ipmi get system info APP fn=06 cmd=01 + /* 20 80 01 52 51 9f a2 02 00 00 00 00 00 00 00 <- raw data*/ + 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) { + printf(" Error getting device ID (No Response)\n"); + return -1; + } + if (rsp->ccode > 0) { + printf(" Error getting device ID (%s)\n", + val2str(rsp->ccode, completion_code_vals)); + return -1; + } + + dev_id = (struct ipm_devid_rsp *)(void *)rsp->data; + + printf("Device ID : %0.2d\n", dev_id->device_id); + printf("Device Revision : %0.2d\n", dev_id->device_revision & 0x7F); + printf("Firmware Version : %d.%0.2x\n", dev_id->fw_rev1 & 0x7F, + dev_id->fw_rev2); /* BCD value. byte->hex conversion used.*/ + printf("IPMI Version : %d.%d\n", dev_id->ipmi_version & 0x0F, dev_id->ipmi_version >> 4); + ipmi_version = dev_id->ipmi_version; + + + printf("Manufacturer ID : %lu\n", + (uint32_t)(dev_id->manufacturer_id[2] & 0x0f) * 65536 + + (uint32_t)(dev_id->manufacturer_id[1] * 256) + + (uint32_t)dev_id->manufacturer_id[0]); + printf("Product ID : %d\n", dev_id->product_id[1]*256 + dev_id->product_id[0]); + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_APP; + req.msg.cmd = BMC_GET_SELF_TEST; + req.msg.data = NULL; + req.msg.data_len = 0; + rsp = intf->sendrecv(intf, &req); + + if (rsp->data[0] == 0x55) { + printf("Status : No error\n",-1); + }else if (rsp->data[0] == 0x56) { + printf("Status : Self Test Function not implemented in this controller\n"); + }else if (rsp->data[0] == 0x58) + { printf("Status : Fatal Hardware Error (BMC is inoperative)\n"); + }else if (rsp->data[0] == 0x57) { + printf("Status : "); + if (rsp->data[1] & 0x01) {printf("Controller operational firmware corrupte "); } + if (rsp->data[1] & 0x02) {printf("Controller update 'boot block' firmware corrupte "); } + if (rsp->data[1] & 0x04) {printf("Internal Use Area of BMC FRU corrupted "); } + if (rsp->data[1] & 0x08) {printf("SDR Repository Empty "); } + if (rsp->data[1] & 0x10) {printf("IPMB signal lines do not respond "); } + if (rsp->data[1] & 0x20) {printf("Cannot access BMC FRU device "); } + if (rsp->data[1] & 0x40) {printf("Cannot access SDR Repository "); } + if (rsp->data[1] & 0x80) {printf("Cannot access SEL device"); } + printf("\n"); + } + else if (rsp->data[0] != 0xFF) { printf("Status : Internal Failure. Refer to particular device's specification for definition\n"); } + else { printf("Status : \n"); } + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.cmd = GET_SDR_REPO_INFO; + req.msg.data = NULL; + req.msg.data_len = 0; + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + printf(" Error getting SDR version (No Response)\n"); + return -1; + } + if (rsp->ccode > 0) { + printf(" Error getting SDR version (%s)\n", + val2str(rsp->ccode, completion_code_vals)); + return -1; + } + + repo_info = (struct sdr_repo_info_rs *)(void *)rsp->data; + printf("SDR Version : %d.%d\n", repo_info->version & 0x0F, repo_info->version >> 4); + + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_APP; + req.msg.cmd = BMC_GET_GUID; + req.msg.data = NULL; + req.msg.data_len = 0; + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + printf(" Error getting device GUID (No Response)\n"); + return -1; + } + if (rsp->ccode > 0) { + printf(" Error getting device GUID (%s)\n", + val2str(rsp->ccode, completion_code_vals)); + return -1; + } + printf("GUID : %.2X%.2X%.2X%.2X-%.2X%.2X-%.2X%.2X-%.2X%.2X-%.2X%.2X%.2X%.2X%.2X%.2X\n", + rsp->data[15], rsp->data[14], rsp->data[13], rsp->data[12], + rsp->data[11], rsp->data[10], rsp->data[9], rsp->data[8], + rsp->data[7], rsp->data[6], rsp->data[5], rsp->data[4], + rsp->data[3], rsp->data[2], rsp->data[1], rsp->data[0]); + + + rc = ipmi_sysinfo_fru(intf, 0, ipmi_version); + return rc; +} + +/* prints the 'fru' portion of the sysinfo command + */ +static int +ipmi_sysinfo_fru(struct ipmi_intf * intf, uint8_t id, uint8_t ipmi_version) +{ + struct ipmi_rs * rsp; + struct ipmi_rq req; + struct fru_info fru; + struct fru_header header; + uint8_t msg_data[4]; + + + + memset(&fru, 0, sizeof(struct fru_info)); + memset(&header, 0, sizeof(struct fru_header)); + + /* + * get info about this FRU + */ + memset(msg_data, 0, 4); + msg_data[0] = id; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.cmd = GET_FRU_INFO; + req.msg.data = msg_data; + req.msg.data_len = 1; + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + printf(" Device not present (No Response)\n"); + return -1; + } + if (rsp->ccode > 0) { + printf(" Device not present (%s)\n", + val2str(rsp->ccode, completion_code_vals)); + return -1; + } + + fru.size = (rsp->data[1] << 8) | rsp->data[0]; + fru.access = rsp->data[2] & 0x1; + + lprintf(LOG_DEBUG, "fru.size = %d bytes (accessed by %s)", + fru.size, fru.access ? "words" : "bytes"); + + if (fru.size < 1) { + lprintf(LOG_ERR, " Invalid FRU size %d", fru.size); + return -1; + } + + /* + * retrieve the FRU header + */ + msg_data[0] = id; + msg_data[1] = 0; + msg_data[2] = 0; + msg_data[3] = 8; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_STORAGE; + req.msg.cmd = GET_FRU_DATA; + req.msg.data = msg_data; + req.msg.data_len = 4; + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + printf(" Device not present (No Response)\n"); + return 1; + } + if (rsp->ccode > 0) { + printf(" Device not present (%s)\n", + val2str(rsp->ccode, completion_code_vals)); + return 1; + } + + if (verbose > 1) + printbuf(rsp->data, rsp->data_len, "FRU DATA"); + + memcpy(&header, rsp->data + 1, 8); + + if (header.version != 1) { + lprintf(LOG_ERR, " Unknown FRU header version 0x%02x", + header.version); + return -1; + } + + /* offsets need converted to bytes + * but that conversion is not done to the structure + * because we may end up with offset > 255 + * which would overflow our 1-byte offset field */ + + + + char assettag[IPMI_DELL_SYSINFO_ASSET_TAG_LENGTH]; + char servicetag[IPMI_DELL_SYSINFO_SERVICE_TAG_LENGTH] = {0}; + char hostname[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0}; + char productModel[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0}; + char osName[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0}; + char biosversion[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0}; + + /* Print board area */ + if ((header.offset.board*8) >= sizeof(struct fru_header)) + ipmi_sysinfo_print_board(intf, &fru, id, header.offset.board*8, ipmi_version); + + /* Print the rest of the sysinfo command */ + if (ipmi_version == 0x51) { + +/* all the remaining info for ipmi 1.5 systems is printed in the ipmi_sysinfo_print_board + function call above. */ + } else { + /* for IPMI 2.0 we get the remaining info from the "get system info" IPMI command rather + * than from the 'get fru data' command */ + + + ipmi_lcd_get_platform_model_name(intf, hostname, IPMI_DELL_LCD_STRING_LENGTH_MAX, + IPMI_DELL_SYSINFO_HOST_NAME); + printf("Host Name : %s\n", hostname); + + + ipmi_lcd_get_platform_model_name(intf, productModel, IPMI_DELL_LCD_STRING_LENGTH_MAX, + IPMI_DELL_PLATFORM_MODEL_NAME_SELECTOR); + printf("Product Model : %s\n", productModel); + + ipmi_sysinfo_get_tag(intf, assettag, IPMI_DELL_SYSINFO_ASSET_TAG, + IPMI_DELL_SYSINFO_ASSET_TAG_LENGTH); + printf("Asset Tag : %s\n", assettag); + + ipmi_sysinfo_get_tag(intf, servicetag, IPMI_DELL_SYSINFO_SERVICE_TAG, + IPMI_DELL_SYSINFO_SERVICE_TAG_LENGTH); + printf("Service Tag : %s\n", servicetag); + + ipmi_lcd_get_platform_model_name(intf, biosversion, IPMI_DELL_LCD_STRING_LENGTH_MAX, + IPMI_DELL_SYSINFO_BIOS_VERSION); + printf("BIOS Version : %s\n", biosversion); + + ipmi_lcd_get_platform_model_name(intf, osName, IPMI_DELL_LCD_STRING_LENGTH_MAX, + IPMI_DELL_SYSINFO_OS_NAME); + printf("System OS Name : %s\n", osName); + + } + + + return 0; +} + +/* fru_area_print_board - Print FRU Board Area + * + * @intf: ipmi interface + * @fru: fru info + * @id: fru id + * @offset: offset pointer + */ +static void +ipmi_sysinfo_print_board(struct ipmi_intf * intf, struct fru_info * fru, + uint8_t id, uint32_t offset, uint8_t ipmi_version) +{ + char * fru_area; + char * bios_version; + char * prod_model; + char * service_tag; + char * asset_tag; + uint8_t * fru_data; + uint8_t language; + uint32_t fru_len, area_len, i, j; + uint16_t length; + uint16_t bib_offset, bib_info_area, bib_length, bib_end; + + j = 0; + + i = offset; + fru_len = 0; + + + fru_data = malloc(fru->size + 1); + if (fru_data == NULL) { + lprintf(LOG_ERR, " Out of memory!"); + return; + } + memset(fru_data, 0, fru->size + 1); + + /* read enough to check length field */ + if (read_fru_area(intf, fru, id, i, 2, fru_data) == 0) + fru_len = 8 * fru_data[i + 1]; + if (fru_len <= 0) { + free(fru_data); + return; + } + + fru_len = 0x200; + i = 0; + /* read in the full fru */ + if (read_fru_area(intf, fru, id, i, fru_len, fru_data) < 0) { + free(fru_data); + return; + } + + + language = fru_data[10]; + if (language == 0x00) { + printf("Board Language Code : English\n"); + } else { + printf("Board Language Code : Unknown\n"); + } + + + i = 8; + + i++; /* skip fru area version */ + area_len = fru_data[i++] * 8; /* fru area length */ + i++; /* skip fru board language */ + i += 3; /* skip mfg. date time */ + + + fru_area = get_fru_area_str(fru_data, &i); + if (fru_area != NULL && strlen(fru_area) > 0) { +/* printf(" Board Mfg : %s\n", fru_area);*/ + free(fru_area); + } + + fru_area = get_fru_area_str(fru_data, &i); + if (fru_area != NULL && strlen(fru_area) > 0) { + printf("Board Product Name : %s\n", fru_area); + free(fru_area); + } + + fru_area = get_fru_area_str(fru_data, &i); + if (fru_area != NULL && strlen(fru_area) > 0) { + printf("Board Serial Number : %s\n", fru_area); + free(fru_area); + } + + fru_area = get_fru_area_str(fru_data, &i); + if (fru_area != NULL && strlen(fru_area) > 0) { + printf("Board Part Number : %s\n", fru_area); + free(fru_area); + } + + fru_area = get_fru_area_str(fru_data, &i); + if (fru_area != NULL && strlen(fru_area) > 0) { +/* if (verbose > 0)*/ + printf("Board FRU File ID : %s\n", fru_area); + free(fru_area); + } + + /* read any extra fields */ + while ((fru_data[i] != 0xc1) && (i < offset + area_len)) + { + int j = i; + fru_area = get_fru_area_str(fru_data, &i); + if (fru_area != NULL && strlen(fru_area) > 0) { + printf(" Board Extra : %s\n", fru_area); + free(fru_area); + } + if (i == j) + break; + } + + if (ipmi_version == 0x51) { + + + /* get host name */ + length = (fru_data[0x72] << 8) | (fru_data[0x71]); + fru_area = malloc(length+1); + memset(fru_area, 0, length+1); + memcpy(fru_area, &fru_data[0x75], length); + fru_area[length] = '\0'; + printf("Host Name : %s\n", fru_area); + free(fru_area); + + fru_area = ipmi_get_bib_info(fru_data, BIB_TYPE_PDRODUCT_MODEL); + if (fru_area != NULL && strlen(fru_area) > 0) { + printf("Product Model : %s\n", fru_area); + free(fru_area); + } + fru_area = ipmi_get_bib_info(fru_data, BIB_TYPE_ASSET_TAG); + if (fru_area != NULL && strlen(fru_area) > 0) { + printf("Asset Tag : %s\n", fru_area); + free(fru_area); + } + fru_area = ipmi_get_bib_info(fru_data, BIB_TYPE_SERVICE_TAG); + if (fru_area != NULL && strlen(fru_area) > 0) { + printf("Service Tag : %s\n", fru_area); + free(fru_area); + } + fru_area = ipmi_get_bib_info(fru_data, BIB_TYPE_BIOS_VERSION); + if (fru_area != NULL && strlen(fru_area) > 0) { + printf("BIOS version : %s\n", fru_area); + free(fru_area); + } + } + + + free(fru_data); +} /* get info from the BIB (BIOS information block) section of the FRU */ static char* ipmi_get_bib_info(uint8_t * fru_data, uint8_t bib_type) @@ -530,13 +952,55 @@ static char* ipmi_get_bib_info(uint8_t memcpy(bib_data, &fru_data[offset+2], length); } bib_data[length] = '\0'; - /*printf("BIOS version: %s\n", bib_data);*/ +/* printf("BIOS version: %s\n", bib_data);*/ } else { bib_data = NULL; } return bib_data; } +static int ipmi_sysinfo_get_tag(struct ipmi_intf * intf, char* tagstring, uint8_t tag_type, uint8_t length) +{ + struct ipmi_rs * rsp = NULL; + struct ipmi_rq req = {0}; + uint8_t data[4]; + IPMI_DELL_TAG * tagblock; + int lcdstring_len = 0; + int bytes_copied = 0; +/* char tagstring[11] = {0};*/ + int ii; + + int bytes_to_copy; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.cmd = IPMI_GET_SYS_INFO; + req.msg.data_len = 4; + req.msg.data = data; + data[0] = 0; /* get parameter*/ + data[1] = tag_type;/*to get asset tag*/ + data[2] = 0; + data[3] = 0; + + rsp = intf->sendrecv(intf, &req); + + if (rsp == NULL) { + lprintf(LOG_ERR, " Error getting asset tag"); + return -1; + } else if (rsp->ccode > 0) { + lprintf(LOG_ERR, " Error getting asset tag: %s", + val2str(rsp->ccode, completion_code_vals)); + return -1; + } + + tagblock = (IPMI_DELL_TAG *) (void *) rsp->data; + memset(tagstring, 0,11); + memcpy (tagstring, &tagblock->tag, length); + + return 0; + +} + + int ipmi_sel_print(struct ipmi_intf * intf, uint16_t count, int printOption) { @@ -588,15 +1052,17 @@ int ipmi_sel_print(struct ipmi_intf * in totalEntries = ((rsp->data[2] << 8) | rsp->data[1]); - if (printOption == SEL_PRINT_FIRST){ - + if (printOption == SEL_PRINT_FIRST) { + if(count > totalEntries) last = totalEntries; else last = count; } if (printOption == SEL_PRINT_LAST){ - if (count <= totalEntries){ + + if (count <= totalEntries) + { start_id = totalEntries - count; start = start_id+1; /*added here Meghna DF:170716*/ @@ -720,7 +1186,7 @@ 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*/ + strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", gmtime(&s)); // edited here return tbuf; } @@ -1256,7 +1722,6 @@ static int ipmi_sensor(struct ipmi_intf* rc = ipmi_sdr_build_table(intf); if (rc == -1) { - /*printf("sniff1 rc = %x\n", rc);*/ return rc; } @@ -1449,7 +1914,7 @@ static int ipmi_powermgmt(struct ipmi_in memset(msg_data, 0, 2); - /*printf("##########netfn = %x\n", req.msg.netfn);*/ +/* printf("##########netfn = %x\n", req.msg.netfn);*/ msg_data[0] = 0x07; msg_data[1] = 0x01; @@ -1626,6 +2091,13 @@ ipmi_powermonitor_usage(void) lprintf(LOG_NOTICE, ""); } +static void +ipmi_sysinfo_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " sysinfo"); + lprintf(LOG_NOTICE, " Show system information"); +} static void ipmi_lcd_usage(void) @@ -1646,6 +2118,7 @@ usage(void) lprintf(LOG_NOTICE, "usage: delloem [option...]"); lprintf(LOG_NOTICE, ""); lprintf(LOG_NOTICE, "commands:"); + lprintf(LOG_NOTICE, " sysinfo"); lprintf(LOG_NOTICE, " lcd"); lprintf(LOG_NOTICE, " sel"); lprintf(LOG_NOTICE, " sensor"); @@ -1717,6 +2190,16 @@ ipmi_delloem_main(struct ipmi_intf * int ipmi_lcd_usage(); return -1; } + /* start sysinfo*/ + } else if (strncmp(argv[current_arg], "sysinfo\0", 8) == 0) { + current_arg++; + + if (argc <= current_arg) { + rc = ipmi_sysinfo_id(intf, 0); + + } else { + ipmi_sysinfo_usage(); + } /* start sel processing*/ } else if (strncmp(argv[current_arg], "sel\0", 4) == 0) { current_arg++; @@ -1795,7 +2278,7 @@ ipmi_delloem_main(struct ipmi_intf * int } else { ipmi_sensor_usage(); } - /* Powermanagement report processing*/ + /*Powermanagement report processing*/ } else if (strncmp(argv[current_arg], "powermonitor\0", 13) == 0) { current_arg++; if (argc == 1) {