diff -rup patch2/include/ipmitool/ipmi_delloem.h patch1/include/ipmitool/ipmi_delloem.h --- patch2/include/ipmitool/ipmi_delloem.h 2008-04-09 00:49:21.000000000 -0500 +++ patch1/include/ipmitool/ipmi_delloem.h 2008-04-09 00:47:19.000000000 -0500 @@ -24,6 +24,7 @@ /*power managment command*/ #define IPMI_CMD_GET_POWER_MANAGMENT_INFO 0x9c #define IPMI_CMD_CLEAR_POWER_MANAGMENT_INFO 0x9d + // Dell selector for LCD control - get and set unless specified #define IPMI_DELL_LCD_STRING_SELECTOR 0xC1 // RW get/set the user string #define IPMI_DELL_LCD_CONFIG_SELECTOR 0xC2 // RW set to user/default/none Only in patch2: ipmitool-1.8.9.tar.bz2 Only in patch2: ipmitool-1.8.9.tar.gz diff -rup patch2/lib/ipmi_delloem.c patch1/lib/ipmi_delloem.c --- patch2/lib/ipmi_delloem.c 2008-04-09 01:53:43.000000000 -0500 +++ patch1/lib/ipmi_delloem.c 2008-04-09 01:52:06.000000000 -0500 @@ -19,10 +19,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -95,6 +95,403 @@ typedef struct _SDRList SDRList SDR[MAX_SDR_ENTRIES]; uint16_t currentSDR; uint16_t totalSDRCount; + + +/* Dell OEM LCD command*/ +/* returns the current lcd configuration + * 0 = User defined + * 1 = Default + * 2 = None + */ +int +ipmi_lcd_get_configure_command (struct ipmi_intf * intf, uint8_t *command) +{ + struct ipmi_rs * rsp = NULL; + struct ipmi_rq req = {0}; + uint8_t data[4]; + + 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; + data[1] = IPMI_DELL_LCD_CONFIG_SELECTOR; + data[2] = 0; + data[3] = 0; + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + lprintf(LOG_ERR, " Error getting LCD configuration"); + return -1; + } else if (rsp->ccode > 0) { + lprintf(LOG_ERR, " Error getting LCD configuration: %s", + val2str(rsp->ccode, completion_code_vals)); + return -1; + } + + /* rsp->data[0] is the rev*/ + *command = rsp->data[1]; + + return 0; +} + + +/* sets the current lcd configuration + * 0 = User defined + * 1 = Default + * 2 = None + */ +int +ipmi_lcd_set_configure_command (struct ipmi_intf * intf, int command) +{ +#define LSCC_DATA_LEN 2 + + struct ipmi_rs * rsp = NULL; + struct ipmi_rq req = {0}; + uint8_t data[2]; + + req.msg.netfn = IPMI_NETFN_APP; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = 2; + req.msg.data = data; + data[0] = IPMI_DELL_LCD_CONFIG_SELECTOR; + data[1] = command; /* command - custom, default, none*/ + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + lprintf(LOG_ERR, " Error setting LCD configuration"); + return -1; + } else if (rsp->ccode > 0) { + lprintf(LOG_ERR, " Error setting LCD configuration: %s", + val2str(rsp->ccode, completion_code_vals)); + + return -1; + } + + return 0; +} + +/* Used to get the platform model name, or any other parameter which stores + * data in the same format + */ +static +ipmi_lcd_get_platform_model_name (struct ipmi_intf * intf, char* lcdstring, uint8_t max_length, uint8_t field_type) +{ + struct ipmi_rs * rsp = NULL; + struct ipmi_rq req = {0}; + uint8_t data[4]; + IPMI_DELL_LCD_STRING * lcdstringblock; + int lcdstring_len = 0; + int bytes_copied = 0; + + + int ii; + + for (ii = 0; ii < 4; 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] = field_type; + data[2] = ii; + data[3] = 0; + + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + lprintf(LOG_ERR, " Error getting platform model name"); + } else if (rsp->ccode > 0) { + lprintf(LOG_ERR, " Error getting platform model name: %s", + val2str(rsp->ccode, completion_code_vals)); + } + + lcdstringblock = (IPMI_DELL_LCD_STRING *) (void *) rsp->data; + + /* first block is different - 14 bytes*/ + if (0 == ii) { + lcdstring_len = lcdstringblock->lcd_string.selector_0_string.length; + + if (lcdstring_len < 1 || lcdstring_len > max_length) + break; + + bytes_to_copy = MIN(lcdstring_len, IPMI_DELL_LCD_STRING1_SIZE); + memcpy (lcdstring, lcdstringblock->lcd_string.selector_0_string.data, bytes_to_copy); + } else { + int string_offset; + + bytes_to_copy = MIN(lcdstring_len - bytes_copied, IPMI_DELL_LCD_STRINGN_SIZE); + if (bytes_to_copy < 1) + break; + string_offset = IPMI_DELL_LCD_STRING1_SIZE + IPMI_DELL_LCD_STRINGN_SIZE * (ii-1); + memcpy (lcdstring+string_offset, lcdstringblock->lcd_string.selector_n_data, bytes_to_copy); + } + + + bytes_copied += bytes_to_copy; + if (bytes_copied >= lcdstring_len) + break; + } + +} + +static int +ipmi_lcd_get_single_line_text (struct ipmi_intf * intf, char* lcdstring, uint8_t max_length) +{ + struct ipmi_rs * rsp = NULL; + struct ipmi_rq req = {0}; + uint8_t data[4]; + IPMI_DELL_LCD_STRING * lcdstringblock; + int lcdstring_len = 0; + int bytes_copied = 0; + int ii; + + for (ii = 0; ii < 4; 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] = IPMI_DELL_LCD_STRING_SELECTOR; + data[2] = ii; /* block selector*/ + data[3] = 00; /* set selector (n/a)*/ + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + lprintf(LOG_ERR, " Error getting text data"); + return -1; + } else if (rsp->ccode > 0) { + lprintf(LOG_ERR, " Error getting text data: %s", + val2str(rsp->ccode, completion_code_vals)); + return -1; + } + + lcdstringblock = (IPMI_DELL_LCD_STRING *) (void *) rsp->data; + + /* first block is different - 14 bytes*/ + if (0 == ii) { + lcdstring_len = lcdstringblock->lcd_string.selector_0_string.length; + + if (lcdstring_len < 1 || lcdstring_len > max_length) + break; + + bytes_to_copy = MIN(lcdstring_len, IPMI_DELL_LCD_STRING1_SIZE); + memcpy (lcdstring, lcdstringblock->lcd_string.selector_0_string.data, bytes_to_copy); + } else { + int string_offset; + + bytes_to_copy = MIN(lcdstring_len - bytes_copied, IPMI_DELL_LCD_STRINGN_SIZE); + if (bytes_to_copy < 1) + break; + string_offset = IPMI_DELL_LCD_STRING1_SIZE + IPMI_DELL_LCD_STRINGN_SIZE * (ii-1); + memcpy (lcdstring+string_offset, lcdstringblock->lcd_string.selector_n_data, bytes_to_copy); + } + + bytes_copied += bytes_to_copy; + if (bytes_copied >= lcdstring_len) + break; + } + return 0; +} + +static int +ipmi_lcd_get_info(struct ipmi_intf * intf) + +{ + struct ipmi_rs * rsp = NULL; + struct ipmi_rq req = {0}; + uint8_t data[4]; + IPMI_DELL_LCD_CAPS * lcd_caps; + uint8_t command = 0; + + printf("LCD info\n"); + + if (ipmi_lcd_get_configure_command (intf, &command) != 0) { + return -1; + } else { + if (command == IPMI_DELL_LCD_CONFIG_DEFAULT) { + char text[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0}; + + ipmi_lcd_get_platform_model_name(intf, text, IPMI_DELL_LCD_STRING_LENGTH_MAX, + IPMI_DELL_PLATFORM_MODEL_NAME_SELECTOR); + + if (text == NULL) + return -1; + printf(" Setting: default\n"); + printf(" Line 1: %s\n", text); + } else if (command == IPMI_DELL_LCD_CONFIG_NONE) { + printf(" Setting: none\n"); + } else if (command == IPMI_DELL_LCD_CONFIG_USER_DEFINED) { + 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] = IPMI_DELL_LCD_GET_CAPS_SELECTOR; + data[2] = 0; /* set selector (n/a)*/ + data[3] = 0; /* block selector (n/a)*/ + + printf(" Setting: custom\n"); + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + lprintf(LOG_ERR, " Error getting LCD capabilities."); + return -1; + } else if (rsp->ccode > 0) { + lprintf(LOG_ERR, " Error getting LCD capabilities: %s", + val2str(rsp->ccode, completion_code_vals)); + return -1; + } + + lcd_caps = (IPMI_DELL_LCD_CAPS *)rsp->data; + if (lcd_caps->number_lines > 0) { + char *text; + char lcdstring[IPMI_DELL_LCD_STRING_LENGTH_MAX+1] = {0}; + text = lcdstring; + int rc; + + rc = ipmi_lcd_get_single_line_text (intf, text, lcd_caps->max_chars[0]); + if (text == NULL) + return -1; + printf(" Text: %s\n", text); + } else { + printf(" No lines to show\n"); + } + } + } + + return 0; +} + +static int +ipmi_lcd_set_single_line_text (struct ipmi_intf * intf, char * text) +{ + struct ipmi_rs * rsp = NULL; + struct ipmi_rq req = {0}; + uint8_t data[18]; + int bytes_to_store = strlen(text); + int bytes_stored = 0; + int ii; + int rc = 0; + + 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*/ + if (0 == ii) { + int size_of_copy = + MIN((bytes_to_store - bytes_stored), IPMI_DELL_LCD_STRING1_SIZE); + if (size_of_copy < 0) /* allow 0 string length*/ + break; + req.msg.netfn = IPMI_NETFN_APP; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = size_of_copy + 4; /* chars, selectors and sizes*/ + 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[3] = bytes_to_store; /* total string length*/ + memcpy (data+4, text+bytes_stored, size_of_copy); + bytes_stored += size_of_copy; + } else { + int size_of_copy = + MIN((bytes_to_store - bytes_stored), IPMI_DELL_LCD_STRINGN_SIZE); + if (size_of_copy <= 0) + break; + req.msg.netfn = IPMI_NETFN_APP; + req.msg.cmd = IPMI_SET_SYS_INFO; + req.msg.data_len = size_of_copy + 2; + req.msg.data = data; + data[0] = IPMI_DELL_LCD_STRING_SELECTOR; + data[1] = ii; /* block number to use (1,2,3)*/ + memcpy (data+2, text+bytes_stored, size_of_copy); + bytes_stored += size_of_copy; + } + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + lprintf(LOG_ERR, " Error setting text data"); + rc = -1; + } else if (rsp->ccode > 0) { + lprintf(LOG_ERR, " Error setting text data: %s", + val2str(rsp->ccode, completion_code_vals)); + rc = -1; + } + } + + return rc; +} + +static int +ipmi_lcd_set_text(struct ipmi_intf * intf, char * text, int line_number) +{ + int rc = 0; + + struct ipmi_rs * rsp = NULL; + struct ipmi_rq req = {0}; + uint8_t data[4]; + IPMI_DELL_LCD_CAPS * lcd_caps; + + 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] = IPMI_DELL_LCD_GET_CAPS_SELECTOR; + data[2] = 0; /* set selector (n/a)*/ + data[3] = 0; /* block selector (n/a)*/ + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) + { + lprintf(LOG_ERR, " Error getting LCD capabilities"); + return -1; + } + else if (rsp->ccode > 0) + { + lprintf(LOG_ERR, " Error getting LCD capabilities: %s", + val2str(rsp->ccode, completion_code_vals)); + + return -1; + } + + lcd_caps = (IPMI_DELL_LCD_CAPS *)(void *)rsp->data; + + if (lcd_caps->number_lines > 0) { + rc = ipmi_lcd_set_single_line_text (intf, text); + } else { + lprintf(LOG_ERR, "LCD does not have any lines that can be set"); + rc = -1; + } + + + return rc; +} + +int +ipmi_lcd_configure (struct ipmi_intf * intf, int command, int8_t line_number, char * text) +{ + int rc = 0; + + + if (IPMI_DELL_LCD_CONFIG_USER_DEFINED == command) + /* Any error was reported earlier. */ + rc = ipmi_lcd_set_text(intf, text, line_number); + + if (rc == 0) + rc = ipmi_lcd_set_configure_command (intf, command); + + return rc; +} + + + + +/* 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) { uint16_t bib_offset, bib_info_area, bib_length, bib_end, length; @@ -192,16 +589,14 @@ int ipmi_sel_print(struct ipmi_intf * in 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) - { + if (count <= totalEntries){ start_id = totalEntries - count; start = start_id+1; /*added here Meghna DF:170716*/ @@ -289,6 +684,7 @@ static int make_int(const char *str, int return 0; } + static char * ipmi_sel_timestamp(uint32_t stamp) { @@ -912,7 +1308,8 @@ ipmi_sensor_get_sensor_reading(unsigned intf = ((struct ipmi_intf*) x); - rsp = ipmi_sdr_get_sensor_reading(intf, sensorNumber); + + rsp = ipmi_sdr_get_sensor_reading(intf, sensorNumber); if (rsp == NULL) { return 1; } else if (rsp->ccode > 0) { @@ -1196,12 +1593,25 @@ ipmi_powermonitor_usage(void) static void +ipmi_lcd_usage(void) +{ + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd set {none}|{default}|{custom }"); + lprintf(LOG_NOTICE, " Set LCD text displayed during non-fault conditions"); + lprintf(LOG_NOTICE, ""); + lprintf(LOG_NOTICE, " lcd info"); + lprintf(LOG_NOTICE, " Show LCD text that is displayed during non-fault conditions"); + 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, " lcd"); lprintf(LOG_NOTICE, " sel"); lprintf(LOG_NOTICE, " sensor"); lprintf(LOG_NOTICE, " powermonitor"); @@ -1221,8 +1631,59 @@ ipmi_delloem_main(struct ipmi_intf * int usage(); return 0; } + + /* ---------------------------------------- + ipmitool delloem lcd command begins here*/ + if (strncmp(argv[current_arg], "lcd\0", 4) == 0) { + current_arg++; + if (argc < current_arg) {usage();return -1;} + + /* ipmitool delloem lcd info*/ + if (argc == 1) { + rc = ipmi_lcd_get_info(intf); + } + else if (strncmp(argv[current_arg], "info\0", 5) == 0) { + rc = ipmi_lcd_get_info(intf); + } + + /* ipmitool delloem lcd set*/ + else if (strncmp(argv[current_arg], "set\0", 4) == 0) { + uint8_t line_number = 0; + + current_arg++; + if (argc <= current_arg) {ipmi_lcd_usage();return -1;} + + if (strncmp(argv[current_arg], "line\0", 5) == 0) { + current_arg++; + if (argc <= current_arg) {usage();return -1;} + line_number = (uint8_t)strtoul(argv[current_arg], NULL, 0); + current_arg++; + if (argc <= current_arg) {usage();return -1;} + } + + if (strncmp(argv[current_arg], "none\0", 5) == 0) { + rc = ipmi_lcd_configure (intf, IPMI_DELL_LCD_CONFIG_NONE, 0, NULL); + } + else if (strncmp(argv[current_arg], "default\0", 8) == 0) { + rc = ipmi_lcd_configure (intf, IPMI_DELL_LCD_CONFIG_DEFAULT, 0, NULL); + + } else if (strncmp(argv[current_arg], "custom\0", 7) == 0) { + current_arg++; + if (argc <= current_arg) {ipmi_lcd_usage();return -1;} + rc = ipmi_lcd_configure (intf, IPMI_DELL_LCD_CONFIG_USER_DEFINED, line_number, argv[current_arg]); + } else if (strncmp(argv[current_arg], "help\0", 5) == 0) { + ipmi_lcd_usage(); + } + else { + ipmi_lcd_usage(); + return -1; + } + } else { + ipmi_lcd_usage(); + return -1; + } /* start sel processing*/ - else if (strncmp(argv[current_arg], "sel\0", 4) == 0) { + } else if (strncmp(argv[current_arg], "sel\0", 4) == 0) { current_arg++; if (argc == 1) { Only in patch2/lib: .nfs00000000011f80aa0002cc84