/* * _read_ipmi_values read the Power sensor and update last_update_watt and times */ static xcc_raw_single_data_t *_read_ipmi_values(void) { xcc_raw_single_data_t *xcc_reading; uint8_t buf_rs[IPMI_RAW_MAX_ARGS]; int rs_len = 0; if (!IPMI_NET_FN_RQ_VALID(cmd_rq[1])) { error("Invalid netfn value\n"); return NULL; } rs_len = ipmi_cmd_raw(ipmi_ctx, cmd_rq[0], // Lun (logical unit number) cmd_rq[1], // Net Function &cmd_rq[2], // Command number + request data cmd_rq_len - 2, // Length (in bytes) &buf_rs, // response buffer IPMI_RAW_MAX_ARGS // max response length ); debug3("ipmi_cmd_raw: %s", ipmi_ctx_errormsg(ipmi_ctx)); if (rs_len != XCC_EXPECTED_RSPLEN) { error("Invalid ipmi response length for XCC raw command: " "%d bytes, expected %d", rs_len, XCC_EXPECTED_RSPLEN); return NULL; } /* Due to memory alineation we must copy the data from the buffer */ xcc_reading = xmalloc(sizeof(xcc_raw_single_data_t)); if (slurm_ipmi_conf.flags & XCC_FLAG_FAKE) { static uint32_t fake_past_read = 10774496; static bool fake_inited = false; if (!fake_inited) { srand((unsigned) time(NULL)); fake_inited = true; } xcc_reading->fifo_inx = 0; // Fake metric j xcc_reading->j = fake_past_read + 550 + rand() % 200; fake_past_read = xcc_reading->j; xcc_reading->mj = 0; xcc_reading->s = time(NULL); //Fake metric timestamp xcc_reading->ms = 0; } else { memcpy(&xcc_reading->fifo_inx, buf_rs+2, 2); memcpy(&xcc_reading->j, buf_rs+4, 4); memcpy(&xcc_reading->mj, buf_rs+8, 2); memcpy(&xcc_reading->s, buf_rs+10, 4); memcpy(&xcc_reading->ms, buf_rs+14, 2); } return xcc_reading; }
int ipmi_oem_supermicro_reset_intrusion (ipmi_oem_state_data_t *state_data) { uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; int rs_len; int rv = -1; assert (state_data); assert (!state_data->prog_data->args->oem_options_count); /* Supermicro OEM * * 0x30 - OEM network function * 0x03 - OEM cmd */ bytes_rq[0] = IPMI_CMD_OEM_SUPERMICRO_RESET_INTRUSION; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_SUPERMICRO_GENERIC_RQ, /* network function */ bytes_rq, /* data */ 1, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 2, IPMI_CMD_OEM_SUPERMICRO_RESET_INTRUSION, IPMI_NET_FN_OEM_SUPERMICRO_GENERIC_RS, NULL) < 0) goto cleanup; rv = 0; cleanup: return (rv); }
int ipmi_oem_supermicro_get_bmc_services_status (ipmi_oem_state_data_t *state_data) { uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; int rs_len; int rv = -1; assert (state_data); assert (!state_data->prog_data->args->oem_options_count); /* Supermicro OEM * * Request * * 0x30 - OEM network function * 0x70 - OEM cmd * 0xF0 - Sub-command * 0x?? - action * - 0x00 - disable * - 0x01 - enable * - 0x02 - status * * Response * * 0x70 - OEM cmd * 0x?? - Completion Code * 0x?? - if action == status * - 0x00 - disabled * - 0x01 - enabled */ bytes_rq[0] = IPMI_CMD_OEM_SUPERMICRO_GENERIC_EXTENSION; bytes_rq[1] = IPMI_OEM_SUPERMICRO_SUB_COMMAND_BMC_SERVICES; bytes_rq[2] = IPMI_OEM_SUPERMICRO_BMC_SERVICES_ACTION_STATUS; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_SUPERMICRO_GENERIC_RQ, /* network function */ bytes_rq, /* data */ 3, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 3, IPMI_CMD_OEM_SUPERMICRO_GENERIC_EXTENSION, IPMI_NET_FN_OEM_SUPERMICRO_GENERIC_RS, NULL) < 0) goto cleanup; if (bytes_rs[2] == IPMI_OEM_SUPERMICRO_BMC_SERVICES_STATUS_DISABLED) pstdout_printf (state_data->pstate, "disabled\n"); else if (bytes_rs[2] == IPMI_OEM_SUPERMICRO_BMC_SERVICES_STATUS_ENABLED) pstdout_printf (state_data->pstate, "enabled\n"); else pstdout_fprintf (state_data->pstate, stderr, "Unknown Non-IPMI Ports Status\n"); rv = 0; cleanup: return (rv); }
static struct ipmi_rs * ipmi_free_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) { u_int8_t lun = 0; u_int8_t cmd = req->msg.cmd; u_int8_t netfn = req->msg.netfn; u_int8_t rq_buf[IPMI_BUF_SIZE]; u_int8_t rs_buf[IPMI_BUF_SIZE]; u_int32_t rs_buf_len = IPMI_BUF_SIZE; int32_t rs_len; static struct ipmi_rs rsp; /* achu: FreeIPMI requests have the cmd as the first byte of * the data. Responses have cmd as the first byte and * completion code as the second byte. This differs from some * other APIs, so it must be compensated for within the ipmitool * interface. */ if (!intf || !req) return NULL; if (!intf->opened && intf->open && intf->open(intf) < 0) return NULL; if (req->msg.data_len > IPMI_BUF_SIZE) return NULL; memset(rq_buf, '\0', IPMI_BUF_SIZE); memset(rs_buf, '\0', IPMI_BUF_SIZE); memcpy(rq_buf, &cmd, 1); if (req->msg.data) memcpy(rq_buf + 1, req->msg.data, req->msg.data_len); if ((rs_len = ipmi_cmd_raw(dev, lun, netfn, rq_buf, req->msg.data_len + 1, rs_buf, rs_buf_len)) < 0) { #if IPMI_INTF_FREE_0_3_0 perror("ipmi_cmd_raw"); #elif IPMI_INTF_FREE_0_4_0 || IPMI_INTF_FREE_0_5_0 fprintf(stderr, "ipmi_cmd_raw: %s\n", ipmi_device_strerror(ipmi_device_errnum(dev))); #elif IPMI_INTF_FREE_0_6_0 fprintf(stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(dev))); #endif return NULL; } memset(&rsp, 0, sizeof(struct ipmi_rs)); rsp.ccode = (unsigned char)rs_buf[1]; rsp.data_len = (int)rs_len - 2; if (!rsp.ccode && rsp.data_len) memcpy(rsp.data, rs_buf + 2, rsp.data_len); return &rsp; }
static int _get_led_sdr_callback (ipmi_sdr_ctx_t sdr_ctx, uint8_t record_type, const void *sdr_record, unsigned int sdr_record_len, void *arg) { struct ipmi_oem_ibm_get_led_sdr_callback *sdr_callback_arg; ipmi_oem_state_data_t *state_data; uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; int rs_len; uint8_t oem_data_buf[IPMI_SDR_MAX_RECORD_LENGTH]; int oem_data_buf_len; uint16_t record_id; char fmt[IPMI_OEM_FMT_BUFLEN + 1]; char led_name[IPMI_OEM_IBM_LED_NAME_BUFLEN + 1]; char led_pointer_name[IPMI_OEM_IBM_LED_NAME_BUFLEN + 1]; char id_string[IPMI_OEM_IBM_LED_ID_STRING_BUFLEN + 1]; char led_info[IPMI_OEM_IBM_LED_INFO_BUFLEN + 1]; char *led_state_str = NULL; uint8_t sensor_type; uint8_t led_id_ls; uint8_t led_id_ms; uint16_t led_id; uint8_t led_state; uint8_t led_active_type; uint16_t led_pointer_id; uint8_t sensor_number; int available_led; assert (sdr_ctx); assert (sdr_record); assert (sdr_record_len); assert (arg); sdr_callback_arg = (struct ipmi_oem_ibm_get_led_sdr_callback *)arg; state_data = sdr_callback_arg->state_data; /* IBM OEM * * From xCAT (http://xcat.sourceforge.net/) * * Get Led Request * * 0x3A - OEM network function (is IPMI_NET_FN_OEM_IBM_LED_RQ) * 0xC0 - OEM cmd * 0x?? - LED ID (MS Byte) * 0x?? - LED ID (LS Byte) * * Get Led Response * * 0xC0 - OEM cmd * 0x?? - Completion Code * 0x?? - ?? * 0x?? - LED Active vs. Inactive * - non-zero = active * - 0 = inactive * 0x?? - ?? * 0x?? - LED Pointer ID (MS Byte) * 0x?? - LED Pointer ID (LS Byte) / Sensor Number * - Pointer ID means indicating problem elsewhere * 0x?? - LED Active Type * - 1 - Indicates LED Active to indicate LED Pointer ID Active * - 2 - Indicates LED Active due to Sensor w/ Sensor Number * - 3 - User manually activated LED * - 4 - BIOS or Administrator lit LED */ if (record_type != IPMI_SDR_FORMAT_OEM_RECORD) return (0); if (ipmi_sdr_parse_record_id_and_type (state_data->sdr_ctx, sdr_record, sdr_record_len, &record_id, NULL) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sdr_parse_record_id_and_type: %s\n", ipmi_sdr_ctx_errormsg (state_data->sdr_ctx)); return (-1); } if ((oem_data_buf_len = ipmi_sdr_parse_oem_data (state_data->sdr_ctx, sdr_record, sdr_record_len, oem_data_buf, IPMI_SDR_MAX_RECORD_LENGTH)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sdr_parse_oem_data: %s\n", ipmi_sdr_ctx_errormsg (state_data->sdr_ctx)); return (-1); } /* If not enough data, skip it */ if (oem_data_buf_len < IPMI_SDR_RECORD_OEM_IBM_LED_OEM_DATA_MIN_LENGTH) return (0); sensor_type = oem_data_buf[IPMI_SDR_RECORD_OEM_IBM_SENSOR_TYPE_OEM_DATA_INDEX]; /* If not LED sensor type, skip it */ if (sensor_type != IPMI_SDR_RECORD_OEM_IBM_LED_SENSOR_TYPE) return (0); /* IBM systems use inconsistent endian, guess endian by assuming * LED IDs are numerically started at 0 */ if (oem_data_buf[IPMI_SDR_RECORD_OEM_IBM_LED_ID_LS_OEM_DATA_INDEX] > oem_data_buf[IPMI_SDR_RECORD_OEM_IBM_LED_ID_MS_OEM_DATA_INDEX]) { led_id_ls = oem_data_buf[IPMI_SDR_RECORD_OEM_IBM_LED_ID_LS_OEM_DATA_INDEX]; led_id_ms = oem_data_buf[IPMI_SDR_RECORD_OEM_IBM_LED_ID_MS_OEM_DATA_INDEX]; } else { led_id_ls = oem_data_buf[IPMI_SDR_RECORD_OEM_IBM_LED_ID_MS_OEM_DATA_INDEX]; led_id_ms = oem_data_buf[IPMI_SDR_RECORD_OEM_IBM_LED_ID_LS_OEM_DATA_INDEX]; } led_id = led_id_ls | (led_id_ms << 8); bytes_rq[0] = IPMI_CMD_OEM_IBM_GET_LED; bytes_rq[1] = led_id_ms; bytes_rq[2] = led_id_ls; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_IBM_LED_RQ, /* network function */ bytes_rq, /* data */ 3, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); return (-1); } /* If get parameter out of range, assume LED ID endian wrong and try again */ if (rs_len >= 2 && bytes_rs[1] == IPMI_COMP_CODE_PARAMETER_OUT_OF_RANGE) { bytes_rq[0] = IPMI_CMD_OEM_IBM_GET_LED; bytes_rq[1] = led_id_ls; bytes_rq[2] = led_id_ms; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_IBM_LED_RQ, /* network function */ bytes_rq, /* data */ 3, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); return (-1); } } /* achu: there are probably 1 or 2 completion codes that are * acceptable to ignore and continue on, but who knows what they * are. */ /* Assume this error code means LED not available */ if (rs_len >= 2 && bytes_rs[1] == IPMI_COMP_CODE_PARAMETER_OUT_OF_RANGE) available_led = 0; else { if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 8, IPMI_CMD_OEM_IBM_GET_LED, IPMI_NET_FN_OEM_IBM_LED_RS, NULL) < 0) return (-1); available_led = 1; } if (!sdr_callback_arg->header_output_flag) { memset (fmt, '\0', IPMI_OEM_FMT_BUFLEN + 1); snprintf (fmt, IPMI_OEM_FMT_BUFLEN, "%%-%ds | LED | State | LED Information\n", sdr_callback_arg->column_width->record_id); pstdout_printf (state_data->pstate, fmt, SENSORS_HEADER_RECORD_ID_STR); sdr_callback_arg->header_output_flag++; } memset (led_name, '\0', IPMI_OEM_IBM_LED_NAME_BUFLEN + 1); memset (led_pointer_name, '\0', IPMI_OEM_IBM_LED_NAME_BUFLEN + 1); memset (id_string, '\0', IPMI_OEM_IBM_LED_ID_STRING_BUFLEN + 1); memset (led_info, '\0', IPMI_OEM_IBM_LED_INFO_BUFLEN + 1); if (_get_led_name (state_data, sdr_callback_arg->oem_data, led_id, led_name, IPMI_OEM_IBM_LED_NAME_BUFLEN) < 0) return (-1); if (available_led) { led_state = bytes_rs[3]; led_active_type = bytes_rs[7]; led_pointer_id = (bytes_rs[5] << 8) | bytes_rs[6]; sensor_number = bytes_rs[6]; if (led_state == IPMI_OEM_IBM_LED_STATE_INACTIVE) led_state_str = "Inactive"; else led_state_str = "Active"; if (led_state != IPMI_OEM_IBM_LED_STATE_INACTIVE) { /* Location LED special case */ if (!led_id) { snprintf (led_info, IPMI_OEM_IBM_LED_INFO_BUFLEN, "System Error Condition"); } else if (led_active_type == IPMI_OEM_IBM_LED_ACTIVE_BY_LED) { if (_get_led_name (state_data, sdr_callback_arg->oem_data, led_pointer_id, led_pointer_name, IPMI_OEM_IBM_LED_NAME_BUFLEN) < 0) return (-1); snprintf (led_info, IPMI_OEM_IBM_LED_INFO_BUFLEN, "'%s' Active", led_pointer_name); } else if (led_active_type == IPMI_OEM_IBM_LED_ACTIVE_BY_SENSOR) { /* achu: sensor numbers may not be unique. I'm copying * this algorithm from xCAT so I assume it's safe for * IBM machines b/c IBM lays out their SDRs in a fashion * that this search is safe and won't result in an * incorrect output. */ if (_find_sensor (state_data, sensor_number, id_string, IPMI_OEM_IBM_LED_ID_STRING_BUFLEN) < 0) return (-1); snprintf (led_info, IPMI_OEM_IBM_LED_INFO_BUFLEN, "Sensor '%s' error", id_string); } else if (led_active_type == IPMI_OEM_IBM_LED_ACTIVE_BY_USER) { snprintf (led_info, IPMI_OEM_IBM_LED_INFO_BUFLEN, "LED Activated by User"); } else if (led_active_type == IPMI_OEM_IBM_LED_ACTIVE_BY_BIOS_OR_ADMINISTRATOR) { snprintf (led_info, IPMI_OEM_IBM_LED_INFO_BUFLEN, "LED Activated by BIOS or Administrator"); } } } else led_state_str = "N/A"; snprintf (fmt, IPMI_OEM_FMT_BUFLEN, "%%-%du | %%-%ds | %%-%ds | %s\n", sdr_callback_arg->column_width->record_id, IPMI_OEM_IBM_LED_NAME_COLUMN_SIZE, IPMI_OEM_IBM_LED_STATE_COLUMN_SIZE, led_info); pstdout_printf (state_data->pstate, fmt, record_id, led_name, led_state_str, led_info); return (0); }
static int _sun_get_led_sdr_callback (ipmi_sdr_ctx_t sdr_ctx, uint8_t record_type, const void *sdr_record, unsigned int sdr_record_len, void *arg) { struct ipmi_oem_sun_get_led_sdr_callback *sdr_callback_arg; ipmi_oem_state_data_t *state_data; uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; int rs_len; uint16_t record_id; char fmt[IPMI_OEM_FMT_BUFLEN + 1]; char device_id_string[IPMI_SDR_MAX_DEVICE_ID_STRING_LENGTH + 1]; char sensor_name_buf[IPMI_SDR_MAX_SENSOR_NAME_LENGTH + 1]; char *sensor_name = NULL; uint8_t entity_instance_type; uint8_t led_mode; char *led_mode_str = NULL; assert (sdr_ctx); assert (sdr_record); assert (sdr_record_len); assert (arg); sdr_callback_arg = (struct ipmi_oem_sun_get_led_sdr_callback *)arg; state_data = sdr_callback_arg->state_data; /* Sun OEM * * From Ipmitool (http://ipmitool.sourceforge.net/) * * Get Led Request * * 0x2E - OEM network function (is IPMI_NET_FN_OEM_GROUP_RQ) * 0x21 - OEM cmd * 0x?? - Device Slave Address (in General Device Locator Record) * - Note that the IPMI command requires the entire * byte of the slave address. * 0x?? - LED Type (see below [1]) * - 0 - ok2rm * - 1 - service * - 2 - activity * - 3 - locate * 0x?? - Controller Address / Device Access Address (in General Device Locator Record) * - 0x20 if the LED is local * - Note that the IPMI command requires the entire * byte of the access address. * 0x?? - HW Info (OEM field in General Device Locator Record) * 0x?? - Force * - 0 - Go thru controller * - 1 - Directly access device * * An alternate format is described in the ipmitool comments for Sun * Blade Moduler Systems. * * 0x2E - OEM network function (is IPMI_NET_FN_OEM_GROUP_RQ) * 0x21 - OEM cmd * 0x?? - Device Slave Address (in General Device Locator Record) * 0x?? - LED Type * 0x?? - Controller Address / Device Access Address (in General Device Locator Record) * 0x?? - HW Info (OEM field in General Device Locator Record) * 0x?? - Entity ID * 0x?? - Entity Instance * - 7 bit version * 0x?? - Force * - 0 - Go thru controller * - 1 - Directly access device * * Get Led Response * * 0x21 - OEM cmd * 0x?? - Completion Code * 0x?? - LED mode * * achu notes: * * [1] - As far as I can tell, the LED type field is useless. My * assumption is that on older Sun systems, or other motherboards I * don't have access to, one can specify an LED type, which allows * you to enable/disable a particular LED amongst many. On my Sun * Fire 4140, it appears to do nothing and affect nothing. I will * add in a new option later if it becomes necessary for the user to * specify an LED type. In the meantime, I will copy the code use * in ipmitool and set this field to the OEM field. */ if (record_type != IPMI_SDR_FORMAT_GENERIC_DEVICE_LOCATOR_RECORD) return (0); if (ipmi_sdr_parse_entity_id_instance_type (state_data->sdr_ctx, sdr_record, sdr_record_len, NULL, NULL, &entity_instance_type) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sdr_parse_entity_id_and_instance: %s\n", ipmi_sdr_ctx_errormsg (state_data->sdr_ctx)); return (-1); } /* if it isn't a physical instance, don't continue on */ if (entity_instance_type == IPMI_SDR_LOGICAL_CONTAINER_ENTITY) return (0); if (ipmi_sdr_parse_record_id_and_type (state_data->sdr_ctx, sdr_record, sdr_record_len, &record_id, NULL) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sdr_parse_record_id_and_type: %s\n", ipmi_sdr_ctx_errormsg (state_data->sdr_ctx)); return (-1); } /* achu: the sun oem commands want the full byte, not just the * sub-field, so use indexes instead of sdr-parse lib. */ bytes_rq[0] = IPMI_CMD_OEM_SUN_GET_LED; bytes_rq[1] = ((uint8_t *)sdr_record)[IPMI_SDR_RECORD_GENERIC_DEVICE_LOCATOR_DEVICE_SLAVE_ADDRESS_INDEX]; bytes_rq[2] = ((uint8_t *)sdr_record)[IPMI_SDR_RECORD_GENERIC_DEVICE_LOCATOR_OEM_INDEX]; bytes_rq[3] = ((uint8_t *)sdr_record)[IPMI_SDR_RECORD_GENERIC_DEVICE_LOCATOR_DEVICE_ACCESS_ADDRESS_INDEX]; bytes_rq[4] = ((uint8_t *)sdr_record)[IPMI_SDR_RECORD_GENERIC_DEVICE_LOCATOR_OEM_INDEX]; bytes_rq[5] = IPMI_OEM_SUN_LED_FORCE_GO_THRU_CONTROLLER; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_GROUP_RQ, /* network function */ bytes_rq, /* data */ 6, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); return (-1); } /* achu: there are probably 1 or 2 completion codes that are * acceptable to ignore and continue on, but who knows what they * are. */ if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 3, IPMI_CMD_OEM_SUN_GET_LED, IPMI_NET_FN_OEM_GROUP_RS, NULL) < 0) return (-1); if (!sdr_callback_arg->header_output_flag) { memset (fmt, '\0', IPMI_OEM_FMT_BUFLEN + 1); snprintf (fmt, IPMI_OEM_FMT_BUFLEN, "%%-%ds | %%-%ds | LED Mode\n", sdr_callback_arg->column_width->record_id, sdr_callback_arg->column_width->sensor_name); pstdout_printf (state_data->pstate, fmt, SENSORS_HEADER_RECORD_ID_STR, SENSORS_HEADER_NAME_STR); sdr_callback_arg->header_output_flag++; } led_mode = bytes_rs[2]; if (state_data->prog_data->args->verbose_count) { memset (sensor_name_buf, '\0', IPMI_SDR_MAX_SENSOR_NAME_LENGTH + 1); if (ipmi_sdr_parse_entity_sensor_name (state_data->sdr_ctx, NULL, 0, 0, /* sensor number */ IPMI_SDR_SENSOR_NAME_FLAGS_IGNORE_SHARED_SENSORS, /* flags */ sensor_name_buf, IPMI_SDR_MAX_SENSOR_NAME_LENGTH) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sdr_parse_entity_sensor_name: %s\n", ipmi_sdr_ctx_errormsg (state_data->sdr_ctx)); return (-1); } sensor_name = sensor_name_buf; } else { memset (device_id_string, '\0', IPMI_SDR_MAX_DEVICE_ID_STRING_LENGTH + 1); if (ipmi_sdr_parse_device_id_string (state_data->sdr_ctx, sdr_record, sdr_record_len, device_id_string, IPMI_SDR_MAX_DEVICE_ID_STRING_LENGTH) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sdr_parse_device_id_string: %s\n", ipmi_sdr_ctx_errormsg (state_data->sdr_ctx)); return (-1); } sensor_name = device_id_string; } switch (led_mode) { case IPMI_OEM_SUN_LED_MODE_OFF: led_mode_str = "Off"; break; case IPMI_OEM_SUN_LED_MODE_ON: led_mode_str = "On"; break; case IPMI_OEM_SUN_LED_MODE_STANDBY: led_mode_str = "Standby"; break; case IPMI_OEM_SUN_LED_MODE_SLOW: led_mode_str = "Slow"; break; case IPMI_OEM_SUN_LED_MODE_FAST: led_mode_str = "Fast"; break; default: led_mode_str = "Unknown"; } snprintf (fmt, IPMI_OEM_FMT_BUFLEN, "%%-%du | %%-%ds | %s\n", sdr_callback_arg->column_width->record_id, sdr_callback_arg->column_width->sensor_name, led_mode_str); pstdout_printf (state_data->pstate, fmt, record_id, sensor_name); return (0); }
static struct ipmi_rs * ipmi_free_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) { u_int8_t lun = req->msg.lun; u_int8_t cmd = req->msg.cmd; u_int8_t netfn = req->msg.netfn; u_int8_t rq_buf[IPMI_BUF_SIZE]; u_int8_t rs_buf[IPMI_BUF_SIZE]; u_int32_t rs_buf_len = IPMI_BUF_SIZE; int32_t rs_len; static struct ipmi_rs rsp; /* achu: FreeIPMI requests have the cmd as the first byte of * the data. Responses have cmd as the first byte and * completion code as the second byte. This differs from some * other APIs, so it must be compensated for within the ipmitool * interface. */ if (!intf || !req) return NULL; if (!intf->opened && intf->open && intf->open(intf) < 0) return NULL; if (req->msg.data_len > IPMI_BUF_SIZE) return NULL; memset(rq_buf, '\0', IPMI_BUF_SIZE); memset(rs_buf, '\0', IPMI_BUF_SIZE); memcpy(rq_buf, &cmd, 1); if (req->msg.data) memcpy(rq_buf + 1, req->msg.data, req->msg.data_len); if (intf->target_addr != 0 && intf->target_addr != IPMI_BMC_SLAVE_ADDR) { #if IPMI_INTF_FREE_BRIDGING if ((rs_len = ipmi_cmd_raw_ipmb(dev, intf->target_channel, intf->target_addr, lun, netfn, rq_buf, req->msg.data_len + 1, rs_buf, rs_buf_len)) < 0) { if (verbose > 3) fprintf(stderr, "ipmi_cmd_raw_ipmb: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(dev))); /* Compared to FreeIPMI, user is expected to input * the target channel on the command line, it is not automatically * discovered. So that is the likely cause of an error. * * Instead of returning an error, return a bad response so output * of ipmitool commands looks like other interfaces */ rs_len = 2; rs_buf[0] = 0; rs_buf[1] = 0xC1; /* invalid command */ } #else /* !IPMI_INTF_FREE_BRIDGING */ if (verbose > 3) fprintf(stderr, "sensor bridging not supported in this driver version"); /* instead of returning an error, return a bad response so output * of ipmitool commands looks like other interfaces */ rs_len = 2; rs_buf[0] = 0; rs_buf[1] = 0xC1; /* invalid command */ #endif /* !IPMI_INTF_FREE_BRIDGING */ } else { if ((rs_len = ipmi_cmd_raw(dev, lun, netfn, rq_buf, req->msg.data_len + 1, rs_buf, rs_buf_len)) < 0) { #if IPMI_INTF_FREE_0_3_0 perror("ipmi_cmd_raw"); #elif IPMI_INTF_FREE_0_4_0 || IPMI_INTF_FREE_0_5_0 fprintf(stderr, "ipmi_cmd_raw: %s\n", ipmi_device_strerror(ipmi_device_errnum(dev))); #elif IPMI_INTF_FREE_0_6_0 fprintf(stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_strerror(ipmi_ctx_errnum(dev))); #endif return NULL; } } memset(&rsp, 0, sizeof(struct ipmi_rs)); rsp.ccode = (unsigned char)rs_buf[1]; rsp.data_len = (int)rs_len - 2; if (!rsp.ccode && rsp.data_len) memcpy(rsp.data, rs_buf + 2, rsp.data_len); return &rsp; }
int ipmi_oem_supermicro_get_pmbus_power_supply_status (ipmi_oem_state_data_t *state_data) { uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; int rs_len; int rv = -1; assert (state_data); assert (state_data->prog_data->args->oem_options_count == 1); if (strcasecmp (state_data->prog_data->args->oem_options[0], "1") && strcasecmp (state_data->prog_data->args->oem_options[0], "2") && strcasecmp (state_data->prog_data->args->oem_options[0], "3")) { pstdout_fprintf (state_data->pstate, stderr, "%s:%s invalid OEM option argument '%s'\n", state_data->prog_data->args->oem_id, state_data->prog_data->args->oem_command, state_data->prog_data->args->oem_options[0]); goto cleanup; } /* Supermicro OEM * From Supermicro Engineer * * Request * * 0x06 - network function * 0x52 - cmd (master read/write) * 0x07 - (channel = 0, bus id = 3, bus type = private) * 0x?? - slave address * - 0x78 - ps 1 * - 0x7a - ps 2 * - 0x7c - ps 3 * 0x01 - read count * 0x78 - data to write ... no idea why 0x78 * * Response * * 0x52 - cmd * 0x?? - Completion Code * 0x?? - 0x01 - good * - 0x00 - bad */ bytes_rq[0] = IPMI_CMD_MASTER_WRITE_READ; bytes_rq[1] = IPMI_OEM_SUPERMICRO_GET_PMBUS_POWER_SUPPLY_STATUS_CHANNEL; if (!strcasecmp (state_data->prog_data->args->oem_options[0], "1")) bytes_rq[2] = IPMI_OEM_SUPERMICRO_GET_PMBUS_POWER_SUPPLY_STATUS_PS1; else if (!strcasecmp (state_data->prog_data->args->oem_options[0], "2")) bytes_rq[2] = IPMI_OEM_SUPERMICRO_GET_PMBUS_POWER_SUPPLY_STATUS_PS2; else /* !strcasecmp (state_data->prog_data->args->oem_options[0], "3") */ bytes_rq[2] = IPMI_OEM_SUPERMICRO_GET_PMBUS_POWER_SUPPLY_STATUS_PS3; bytes_rq[3] = 1; bytes_rq[4] = IPMI_OEM_SUPERMICRO_GET_PMBUS_POWER_SUPPLY_STATUS_MAGIC; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_APP_RQ, bytes_rq, /* data */ 5, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 3, IPMI_CMD_MASTER_WRITE_READ, IPMI_NET_FN_APP_RQ, NULL) < 0) goto cleanup; if (bytes_rs[2] == IPMI_OEM_SUPERMICRO_GET_PMBUS_POWER_SUPPLY_STATUS_GOOD) pstdout_printf (state_data->pstate, "good\n"); else if (bytes_rs[2] == IPMI_OEM_SUPERMICRO_GET_PMBUS_POWER_SUPPLY_STATUS_BAD) pstdout_printf (state_data->pstate, "bad\n"); else pstdout_printf (state_data->pstate, "unknown\n"); rv = 0; cleanup: return (rv); }
int ipmi_oem_fujitsu_get_identify_led (ipmi_oem_state_data_t *state_data) { uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; uint8_t state; int rs_len; int rv = -1; assert (state_data); assert (!state_data->prog_data->args->oem_options_count); /* Fujitsu OEM * * http://manuals.ts.fujitsu.com/file/4390/irmc_s2-en.pdf * * Request * * 0x2E - OEM network function * 0xF5 - OEM cmd * 0x?? - Fujitsu IANA (LSB first) * 0x?? - Fujitsu IANA * 0x?? - Fujitsu IANA * 0xB1 - Command Specifier * * Response * * 0xF5 - OEM cmd * 0x?? - Completion code * 0x?? - Fujitsu IANA (LSB first) * 0x?? - Fujitsu IANA * 0x?? - Fujitsu IANA * 0x?? - led on/off state (0 == off, 1 == on) */ bytes_rq[0] = IPMI_CMD_OEM_FUJITSU_SYSTEM; bytes_rq[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF); bytes_rq[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8; bytes_rq[3] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16; bytes_rq[4] = IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_IDENTIFY_LED; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_GROUP_RQ, /* network function */ bytes_rq, /* data */ 5, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 6, IPMI_CMD_OEM_FUJITSU_SYSTEM, IPMI_NET_FN_OEM_GROUP_RS, NULL) < 0) goto cleanup; state = (bytes_rs[5] & IPMI_OEM_FUJITSU_IDENTIFY_LED_BITMASK); state >>= IPMI_OEM_FUJITSU_IDENTIFY_LED_SHIFT; if (state == IPMI_OEM_FUJITSU_IDENTIFY_LED_ON) pstdout_printf (state_data->pstate, "on\n"); else pstdout_printf (state_data->pstate, "off\n"); rv = 0; cleanup: return (rv); }
int ipmi_oem_fujitsu_get_eeprom_version_info (ipmi_oem_state_data_t *state_data) { uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; int rs_len; uint8_t eeprom_number; uint8_t status; uint8_t major_firmware_revision; uint8_t minor_firmware_revision; uint8_t aux_firmware_revision_major; uint8_t aux_firmware_revision_minor; uint8_t aux_firmware_revision_res; char major_firmware_revision_char; uint8_t major_sdrr_revision; uint8_t minor_sdrr_revision; char major_sdrr_revision_char; uint16_t sdrr_id; uint8_t major_booter_revision; uint8_t minor_booter_revision; uint8_t aux_booter_revision_major; uint8_t aux_booter_revision_minor; long tmp; char *endptr; int rv = -1; assert (state_data); assert (state_data->prog_data->args->oem_options_count == 1); errno = 0; tmp = strtol (state_data->prog_data->args->oem_options[0], &endptr, 0); if (errno || endptr[0] != '\0' || tmp < 0 || tmp > UCHAR_MAX) { pstdout_fprintf (state_data->pstate, stderr, "%s:%s invalid OEM option argument '%s'\n", state_data->prog_data->args->oem_id, state_data->prog_data->args->oem_command, state_data->prog_data->args->oem_options[0]); goto cleanup; } if (!(tmp >= IPMI_OEM_FUJITSU_EEPROM_NUMBER_MIN && tmp <= IPMI_OEM_FUJITSU_EEPROM_NUMBER_MAX)) { pstdout_fprintf (state_data->pstate, stderr, "%s:%s invalid OEM option argument '%s' : out of range\n", state_data->prog_data->args->oem_id, state_data->prog_data->args->oem_command, state_data->prog_data->args->oem_options[0]); goto cleanup; } eeprom_number = tmp; /* Fujitsu OEM * * http://manuals.ts.fujitsu.com/file/4390/irmc_s2-en.pdf * * Request * * 0x2E - OEM network function * 0xF5 - OEM cmd * 0x?? - Fujitsu IANA (LSB first) * 0x?? - Fujitsu IANA * 0x?? - Fujitsu IANA * 0x12 - Command Specifier * * Response * * 0xF5 - OEM cmd * 0x?? - Completion code * 0x?? - Fujitsu IANA (LSB first) * 0x?? - Fujitsu IANA * 0x?? - Fujitsu IANA * 0x?? - status * 0x00 - checksum error * 0x01 - ok * 0x?? - major fw revision - binary coded * 0x?? - minor fw revision - binary - 2 char field coded (HLiebig: listed incorrectly as BCD in doc) * 0x?? - aux fw revision (lsb first) - binary coded, major/minor/res. * 0x?? - aux fw revision * 0x?? - aux fw revision * 0x?? - major fw char - ascii char * 0x?? - major sdrr revision - binary coded (HLiebig: listed incorrectly as BCD in doc) * 0x?? - minor sdrr revision - bcd coded * 0x?? - major sdrr char - ascii char * 0x?? - sdrr-ID (lsb) - hex coded (HLiebig: listed incorrectly as binary in doc) * 0x?? - sdrr-ID (msb) - hex coded (HLiebig: listed incorrectly as binary in doc) * 0x?? - major booter revision - binary coded * 0x?? - minor booter revision - binary - 2 char field coded (HLiebig: listed incorrectly as BCD in doc) * 0x?? - aux booter revision (lsb first) - binary coded, major/minor * 0x?? - aux booter revision */ bytes_rq[0] = IPMI_CMD_OEM_FUJITSU_SYSTEM; bytes_rq[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF); bytes_rq[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8; bytes_rq[3] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16; bytes_rq[4] = IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_EEPROM_VERSION_INFO; bytes_rq[5] = eeprom_number; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_GROUP_RQ, /* network function */ bytes_rq, /* data */ 6, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 21, IPMI_CMD_OEM_FUJITSU_SYSTEM, IPMI_NET_FN_OEM_GROUP_RS, NULL) < 0) goto cleanup; status = bytes_rs[5]; if (status != IPMI_OEM_FUJITSU_EEPROM_CHECKSUM_OK) { pstdout_fprintf (state_data->pstate, stderr, "Check Error Runtime\n"); goto cleanup; } major_firmware_revision = bytes_rs[6]; minor_firmware_revision = bytes_rs[7]; aux_firmware_revision_major = bytes_rs[8]; aux_firmware_revision_minor = bytes_rs[9]; aux_firmware_revision_res = bytes_rs[10]; major_firmware_revision_char = (char)bytes_rs[11]; major_sdrr_revision = bytes_rs[12]; minor_sdrr_revision = bytes_rs[13]; major_sdrr_revision_char = (char)bytes_rs[14]; sdrr_id = bytes_rs[15]; sdrr_id |= (bytes_rs[16] << 8); major_booter_revision = bytes_rs[17]; minor_booter_revision = bytes_rs[18]; aux_booter_revision_major = bytes_rs[19]; aux_booter_revision_minor = bytes_rs[20]; /* make sure char is atleast legit */ /* HLiebig: minor_firmware_revision listed incorrectly as BCD in doc */ if (isalnum(major_firmware_revision_char)) pstdout_printf (state_data->pstate, "Firmware Revision : %u.%02u%c (%u.%02u)\n", aux_firmware_revision_major, aux_firmware_revision_minor, major_firmware_revision_char, major_firmware_revision, minor_firmware_revision); else pstdout_printf (state_data->pstate, "Firmware Revision : %u.%02u (%u.%02u)\n", aux_firmware_revision_major, aux_firmware_revision_minor, major_firmware_revision, minor_firmware_revision); /* HLiebig: major_sdrr_revision listed incorrectly as BCD in doc */ if (isalnum (major_sdrr_revision_char)) pstdout_printf (state_data->pstate, "SDRR Revision : %u.%02X%c\n", major_sdrr_revision, minor_sdrr_revision, major_sdrr_revision_char); else pstdout_printf (state_data->pstate, "SDRR Revision : %u.%02X\n", major_sdrr_revision, minor_sdrr_revision); /* HLiebig: sdrr_id listed incorrectly as binary in doc */ pstdout_printf (state_data->pstate, "SDRR ID : %X\n", sdrr_id); /* HLiebig: minor_booter_revision listed incorrectly as BCD in doc */ pstdout_printf (state_data->pstate, "Booter Revision : %u.%02u (%u.%02u)\n", aux_booter_revision_major, aux_booter_revision_minor, major_booter_revision, minor_booter_revision); rv = 0; cleanup: return (rv); }
static int _ipmi_oem_get_power_source (ipmi_oem_state_data_t *state_data, uint8_t command_specifier, uint8_t *source) { uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; int rs_len; int rv = -1; assert (state_data); assert (command_specifier == IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_POWER_ON_SOURCE || command_specifier == IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_POWER_OFF_SOURCE); assert (source); /* Fujitsu OEM * * http://manuals.ts.fujitsu.com/file/4390/irmc_s2-en.pdf * * Request * * 0x2E - OEM network function * 0x01 - OEM cmd * 0x?? - Fujitsu IANA (LSB first) * 0x?? - Fujitsu IANA * 0x?? - Fujitsu IANA * 0x?? - Command Specifier * * Response * * 0x01 - OEM cmd * 0x?? - Completion code * 0x?? - Fujitsu IANA (LSB first) * 0x?? - Fujitsu IANA * 0x?? - Fujitsu IANA * 0x01 - data length * 0x?? - power on/off source */ bytes_rq[0] = IPMI_CMD_OEM_FUJITSU_POWER; bytes_rq[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF); bytes_rq[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8; bytes_rq[3] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16; bytes_rq[4] = command_specifier; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_GROUP_RQ, /* network function */ bytes_rq, /* data */ 5, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 7, IPMI_CMD_OEM_FUJITSU_POWER, IPMI_NET_FN_OEM_GROUP_RS, NULL) < 0) goto cleanup; (*source) = bytes_rs[6]; rv = 0; cleanup: return (rv); }
int ipmi_oem_fujitsu_get_system_status (ipmi_oem_state_data_t *state_data) { uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; uint8_t system_status; uint8_t signaling; uint8_t post_code; uint8_t system_power; uint8_t sel_entries_available; uint8_t watchdog_active; uint8_t agent_connected; uint8_t post_state; uint8_t identify_led; /* rename from "localize" */ uint8_t css_led; uint8_t global_error_led; char *css_led_str = NULL; char *global_error_led_str = NULL; struct timeval t; int rs_len; int rv = -1; assert (state_data); assert (!state_data->prog_data->args->oem_options_count); /* Fujitsu OEM * * http://manuals.ts.fujitsu.com/file/4390/irmc_s2-en.pdf * * Request * * 0x2E - OEM network function * 0xF5 - OEM cmd * 0x?? - Fujitsu IANA (LSB first) * 0x?? - Fujitsu IANA * 0x?? - Fujitsu IANA * 0x10 - Command Specifier * 0x?? - timestamp (LSB first) * 0x?? - timestamp * 0x?? - timestamp * 0x?? - timestamp * * Response * * 0xF5 - OEM cmd * 0x?? - Completion code * 0x?? - Fujitsu IANA (LSB first) * 0x?? - Fujitsu IANA * 0x?? - Fujitsu IANA * 0x?? - System Status * bit 7 - System ON * bit 6 - * bit 5 - * bit 4 - SEL entries available * bit 3 - * bit 2 - Watchdog active * bit 1 - Agent connected * bit 0 - Post State * 0x?? - Signaling * bit 7 - Identify LED (sometimes refered as "Localize") * bit 6 - * bit 5 - * bit 4 - * bit 3 - CSS LED (Customer Self Service LED) * bit 2 - CSS LED (Customer Self Service LED) * bit 1 - Global Error LED * bit 0 - Global Error LED * 0x?? - Notifications * bit 7 - SEL Modified (New SEL Entry) * bit 6 - SEL Modified (SEL Cleared) * bit 5 - SDR Modified * bit 4 - Nonvolatile IPMI Variable Modified * bit 3 - ConfigSpace Modified * bit 2 - * bit 1 - * bit 0 - New Output on LocalView display * 0x?? - Last POST Code (Port 80) (HLiebig: renamed from "Post Code" in doc) * * achu: Docs say "timestamp is only relevant for evaluating the * Notifications Byte". I assume this is because the Notifications * timestamp indicates if things have changed in the SEL/SDR. */ if (gettimeofday (&t, NULL) < 0) { pstdout_perror (state_data->pstate, "gettimeofday"); goto cleanup; } bytes_rq[0] = IPMI_CMD_OEM_FUJITSU_SYSTEM; bytes_rq[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF); bytes_rq[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8; bytes_rq[3] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16; bytes_rq[4] = IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_SYSTEM_STATUS; bytes_rq[5] = (t.tv_sec & 0x000000FF); bytes_rq[6] = (t.tv_sec & 0x0000FF00) >> 8; bytes_rq[7] = (t.tv_sec & 0x00FF0000) >> 16; bytes_rq[8] = (t.tv_sec & 0xFF000000) >> 24; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_GROUP_RQ, /* network function */ bytes_rq, /* data */ 9, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 9, IPMI_CMD_OEM_FUJITSU_SYSTEM, IPMI_NET_FN_OEM_GROUP_RS, NULL) < 0) goto cleanup; /* achu: the "Notifications" are dependent on the timestamp input, * we won't bother outputting them */ system_status = bytes_rs[5]; signaling = bytes_rs[6]; post_code = bytes_rs[8]; system_power = (system_status & IPMI_OEM_FUJITSU_SYSTEM_STATUS_SYSTEM_POWER_BITMASK); system_power >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_SYSTEM_POWER_SHIFT; sel_entries_available = (system_status & IPMI_OEM_FUJITSU_SYSTEM_STATUS_SEL_ENTRIES_AVAILABLE_BITMASK); sel_entries_available >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_SEL_ENTRIES_AVAILABLE_SHIFT; watchdog_active = (system_status & IPMI_OEM_FUJITSU_SYSTEM_STATUS_WATCHDOG_ACTIVE_BITMASK); watchdog_active >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_WATCHDOG_ACTIVE_SHIFT; agent_connected = (system_status & IPMI_OEM_FUJITSU_SYSTEM_STATUS_AGENT_CONNECTED_BITMASK); agent_connected >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_AGENT_CONNECTED_SHIFT; post_state = (system_status & IPMI_OEM_FUJITSU_SYSTEM_STATUS_POST_STATE_BITMASK); post_state >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_POST_STATE_SHIFT; identify_led = (signaling & IPMI_OEM_FUJITSU_SYSTEM_STATUS_SIGNALING_LOCAL_LED_BITMASK); identify_led >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_SIGNALING_LOCAL_LED_SHIFT; css_led = (signaling & IPMI_OEM_FUJITSU_SYSTEM_STATUS_SIGNALING_CSS_LED_BITMASK); css_led >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_SIGNALING_CSS_LED_SHIFT; global_error_led = (signaling & IPMI_OEM_FUJITSU_SYSTEM_STATUS_SIGNALING_GLOBAL_ERROR_LED_BITMASK); global_error_led >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_SIGNALING_GLOBAL_ERROR_LED_SHIFT; pstdout_printf (state_data->pstate, "System Power : %s\n", system_power ? "On" : "Off"); pstdout_printf (state_data->pstate, "SEL Entries Available : %s\n", sel_entries_available ? "Yes" : "No"); pstdout_printf (state_data->pstate, "Watchdog Active : %s\n", watchdog_active ? "Yes" : "No"); pstdout_printf (state_data->pstate, "Agent Connected : %s\n", agent_connected ? "Yes" : "No"); /* HLiebig: renamed from "Post State" in doc */ pstdout_printf (state_data->pstate, "System in POST : %s\n", post_state ? "Yes" : "No"); pstdout_printf (state_data->pstate, "Identify LED : %s\n", identify_led ? "On" : "Off"); switch (css_led) { case IPMI_OEM_FUJITSU_CSS_LED_OFF: css_led_str = "Off"; break; case IPMI_OEM_FUJITSU_CSS_LED_ON: css_led_str = "On"; break; case IPMI_OEM_FUJITSU_CSS_LED_BLINK: css_led_str = "Blink"; break; default: css_led_str = "Unknown LED State"; } pstdout_printf (state_data->pstate, "CSS LED : %s\n", css_led_str); switch (global_error_led) { case IPMI_OEM_FUJITSU_GLOBAL_ERROR_LED_OFF: global_error_led_str = "Off"; break; case IPMI_OEM_FUJITSU_GLOBAL_ERROR_LED_ON: global_error_led_str = "On"; break; case IPMI_OEM_FUJITSU_GLOBAL_ERROR_LED_BLINK: global_error_led_str = "Blink"; break; default: global_error_led_str = "Unknown LED State"; } pstdout_printf (state_data->pstate, "Global Error LED : %s\n", global_error_led_str); /* HLiebig: renamed from "Post Code" in doc */ pstdout_printf (state_data->pstate, "Last POST Code (Port 80) : %02Xh\n", post_code); rv = 0; cleanup: return (rv); }
int ipmi_oem_fujitsu_get_remote_storage_status (ipmi_oem_state_data_t *state_data) { uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; int rs_len; uint8_t connection; uint8_t storage_status; uint8_t storage_type; char *storage_status_str; char *storage_type_str; long tmp; char *endptr; int rv = -1; assert (state_data); assert (state_data->prog_data->args->oem_options_count == 1); errno = 0; tmp = strtol (state_data->prog_data->args->oem_options[0], &endptr, 0); if (errno || endptr[0] != '\0' || tmp < 0 || tmp > UCHAR_MAX) { pstdout_fprintf (state_data->pstate, stderr, "%s:%s invalid OEM option argument '%s'\n", state_data->prog_data->args->oem_id, state_data->prog_data->args->oem_command, state_data->prog_data->args->oem_options[0]); goto cleanup; } if (!(tmp >= IPMI_OEM_FUJITSU_REMOTE_STORAGE_CONNECTION_MIN && tmp <= IPMI_OEM_FUJITSU_REMOTE_STORAGE_CONNECTION_MAX)) { pstdout_fprintf (state_data->pstate, stderr, "%s:%s invalid OEM option argument '%s' : out of range\n", state_data->prog_data->args->oem_id, state_data->prog_data->args->oem_command, state_data->prog_data->args->oem_options[0]); goto cleanup; } connection = tmp; /* Fujitsu OEM * * http://manuals.ts.fujitsu.com/file/4390/irmc_s2-en.pdf * * Request * * 0x30 - OEM network function * 0x19 - OEM cmd * 0x?? - "Command Specifier" * - 0x01 - determine if storage media are connected * - 0x02 - get remote storage status * 0x?? - no apparent use * 0x?? - if command specifier == 0x01 * - 0x00 * if command specifier == 0x02 * - 0x00 - connection 0 * - 0x01 - connection 2 ("2" - is this a typo in the document??) * * Response * * 0x19 - OEM cmd * 0x?? - Completion code * 0x?? - "Command Specifier" * 0x?? - if command specifier == 0x01 * - connection status * - 0x00 = no, 0x01 = yes * - if command specifier == 0x02 * - 0x00 * 0x?? - if command specifier == 0x01 * - 0x00 * - if command specifier == 0x02 * - 0x00 * 0x?? - if command specifier == 0x01 * - 0x00 * - if command specifier == 0x02 * - remote storage status * 0x?? - if command specifier == 0x01 * - N/A - not returned?? * - if command specifier == 0x02 * - remote storage type */ /* achu: we won't bother checking if there are any remote * connections, just check the connection indicated by the user */ bytes_rq[0] = IPMI_CMD_OEM_FUJITSU_GET_REMOTE_STORAGE_CONNECTION_OR_STATUS; bytes_rq[1] = IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_REMOTE_STORAGE_STATUS; bytes_rq[2] = 0x00; bytes_rq[3] = connection; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_FUJITSU_GENERIC_RQ, /* network function */ bytes_rq, /* data */ 4, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 6, IPMI_CMD_OEM_FUJITSU_GET_REMOTE_STORAGE_CONNECTION_OR_STATUS, IPMI_NET_FN_OEM_FUJITSU_GENERIC_RS, NULL) < 0) goto cleanup; storage_status = bytes_rs[4]; storage_type = bytes_rs[5]; switch (storage_status) { case IPMI_OEM_FUJITSU_REMOTE_STORAGE_STATUS_INVALID_UNKNOWN: storage_status_str = "Invalid / unknown"; break; case IPMI_OEM_FUJITSU_REMOTE_STORAGE_STATUS_IDLE: storage_status_str = "idle"; break; case IPMI_OEM_FUJITSU_REMOTE_STORAGE_STATUS_CONNECTION_ATTEMPT_PENDING: storage_status_str = "Connection Attempt pending"; break; case IPMI_OEM_FUJITSU_REMOTE_STORAGE_STATUS_CONNECTED: storage_status_str = "Connected"; break; case IPMI_OEM_FUJITSU_REMOTE_STORAGE_STATUS_CONNECTION_ATTEMPTS_RETRIES_EXHAUSTED_FAILED: storage_status_str = "Connection Attempts retries exhausted / failed"; break; case IPMI_OEM_FUJITSU_REMOTE_STORAGE_STATUS_CONNECTION_LOST: storage_status_str = "Connection lost"; break; case IPMI_OEM_FUJITSU_REMOTE_STORAGE_STATUS_DISCONNECT_PENDING: storage_status_str = "Disconnect pending"; break; default: storage_status_str = "Unknown Storage Status"; } pstdout_printf (state_data->pstate, "Storage Status : %s\n", storage_status_str); switch (storage_type) { case IPMI_OEM_FUJITSU_REMOTE_STORAGE_TYPE_INVALID_UNKNOWN: storage_type_str = "Invalid / unknown"; break; case IPMI_OEM_FUJITSU_REMOTE_STORAGE_TYPE_STORAGE_SERVER_IPMI: storage_type_str = "Storage Server / IPMI"; break; case IPMI_OEM_FUJITSU_REMOTE_STORAGE_TYPE_APPLET: storage_type_str = "Applet"; break; case IPMI_OEM_FUJITSU_REMOTE_STORAGE_TYPE_NONE_NOT_CONNECTED: storage_type_str = "None / Not connected"; break; default: storage_type_str = "Unknown Storage Type"; } pstdout_printf (state_data->pstate, "Storage Type : %s\n", storage_type_str); rv = 0; cleanup: return (rv); }
int ipmi_oem_fujitsu_get_sel_entry_long_text (ipmi_oem_state_data_t *state_data) { uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; int rs_len; long value; uint16_t sel_record_id; uint16_t actual_record_id = 0; uint32_t timestamp = 0; uint8_t css = 0; uint8_t severity = 0; char time_buf[IPMI_OEM_TIME_BUFLEN + 1]; char data_buf[IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_MAX_DATA_LENGTH + 1]; uint8_t data_length; uint8_t offset = 0; uint8_t component_length = 0; char *css_str = NULL; char *severity_str = NULL; char *endptr = NULL; int rv = -1; uint8_t max_read_length; struct ipmi_oem_data oem_data; assert (state_data); assert (state_data->prog_data->args->oem_options_count == 1); errno = 0; value = strtol (state_data->prog_data->args->oem_options[0], &endptr, 0); if (errno || endptr[0] != '\0' || value < IPMI_SEL_GET_RECORD_ID_FIRST_ENTRY || value > IPMI_SEL_GET_RECORD_ID_LAST_ENTRY) { pstdout_fprintf (state_data->pstate, stderr, "%s:%s invalid OEM option argument '%s'\n", state_data->prog_data->args->oem_id, state_data->prog_data->args->oem_command, state_data->prog_data->args->oem_options[0]); goto cleanup; } sel_record_id = value; memset (data_buf, '\0', IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_MAX_DATA_LENGTH + 1); /* HLiebig: Note: Documentation is for iRMC S2 version */ if ((ipmi_get_oem_data (state_data->pstate, state_data->ipmi_ctx, &oem_data) <= 0) || (IPMI_FUJITSU_PRODUCT_ID_IS_IRMC_S1 (oem_data.product_id))) { max_read_length = IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_IRMC_S1_MAX_READ_LENGTH; data_length = IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_IRMC_S1_MAX_DATA_LENGTH; } else { max_read_length = IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_IRMC_S2_MAX_READ_LENGTH; data_length = IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_IRMC_S2_MAX_DATA_LENGTH; } /* 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) * * Response * * 0xF5 - OEM cmd * 0x?? - Completion code * 0x?? - Fujitsu IANA (LSB first) * 0x?? - Fujitsu IANA * 0x?? - Fujitsu IANA * 0x?? - Next Record ID (LSB) * 0x?? - Next Record ID (MSB) * 0x?? - Actual Record ID (LSB) * 0x?? - Actual Record ID (MSB) * 0x?? - Record type * 0x?? - timestamp (LSB first) * 0x?? - timestamp * 0x?? - timestamp * 0x?? - timestamp * 0x?? - severity * bit 7 - CSS component * - 0 - No CSS component * - 1 - CSS component * bit 6-4 - 000 = INFORMATIONAL * 001 = MINOR * 010 = MAJOR * 011 = CRITICAL * 1xx = unknown * bit 3-0 - reserved * 0x?? - data length (of the whole text) * 0x?? - converted SEL data * - requested number of bytes starting at requested offset (MaxResponseDataSize-1 bytes of data) * 0x00 - trailing '\0' character */ bytes_rq[0] = IPMI_CMD_OEM_FUJITSU_SYSTEM; bytes_rq[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF); bytes_rq[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8; bytes_rq[3] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16; bytes_rq[4] = IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_SEL_ENTRY_LONG_TEXT; bytes_rq[5] = (sel_record_id & 0x00FF); bytes_rq[6] = (sel_record_id & 0xFF00) >> 8; /* * From Holger Liebig <holger.liebig at ts.fujitsu.com> * * "Unfortunately due to memory constrains in the previous BMC * generation the maximum length of a single response is limited to * 64bytes, while on the current product line you should be able to * get the full 100bytes translated SEL text with a single request * at least over LAN. Maximum (non standard) KCS transfer size is * also different between current (255) and previous (64) * generation, so the code should compare the data received with the * total length reported in the response." */ /* Request partial or complete string, depending on product */ bytes_rq[8] = max_read_length; while (offset < data_length) { bytes_rq[7] = offset; /* BMC checks for boundaries, offset + len has to be <= 80 (iRMC S1) <= 100 (iRMC S2) */ if (offset + bytes_rq[8] > data_length) bytes_rq[8] = data_length - offset; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_GROUP_RQ, /* network function */ bytes_rq, /* data */ 9, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 17, IPMI_CMD_OEM_FUJITSU_SYSTEM, IPMI_NET_FN_OEM_GROUP_RS, NULL) < 0) goto cleanup; /* achu: assume a lot of this will be the same not matter how many times we loop */ if (!offset) { actual_record_id = bytes_rs[7]; actual_record_id |= (bytes_rs[8] << 8); /* use actual_record_id for subsequent requests to obtain consistent results */ bytes_rq[5] = bytes_rs[7]; bytes_rq[6] = bytes_rs[8]; timestamp = bytes_rs[10]; timestamp |= (bytes_rs[11] << 8); timestamp |= (bytes_rs[12] << 16); timestamp |= (bytes_rs[13] << 24); css = (bytes_rs[14] & IPMI_OEM_FUJITSU_CSS_BITMASK); css >>= IPMI_OEM_FUJITSU_CSS_SHIFT; severity = (bytes_rs[14] & IPMI_OEM_FUJITSU_SEVERITY_BITMASK); severity >>= IPMI_OEM_FUJITSU_SEVERITY_SHIFT; } data_length = bytes_rs[15]; /* Every response should be NUL terminated, not just the last * component. */ bytes_rs[rs_len - 1] = '\0'; /* just to be sure it's terminated */ component_length = strlen ((char *)bytes_rs + 16); /* achu: truncate if there is overflow */ if (offset + component_length > data_length) { memcpy (data_buf + offset, &bytes_rs[16], IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_MAX_DATA_LENGTH - offset); offset = data_length; } else { memcpy (data_buf + offset, &bytes_rs[16], component_length); offset += component_length; } }
int ipmi_oem_fujitsu_get_error_led (ipmi_oem_state_data_t *state_data) { uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; uint8_t state; int rs_len; int rv = -1; assert (state_data); assert (!state_data->prog_data->args->oem_options_count); /* Fujitsu OEM * * http://manuals.ts.fujitsu.com/file/4390/irmc_s2-en.pdf * * Request * * 0x2E - OEM network function * 0xF5 - OEM cmd * 0x?? - Fujitsu IANA (LSB first) * 0x?? - Fujitsu IANA * 0x?? - Fujitsu IANA * 0xB3 - Command Specifier * * Response * * 0xF5 - OEM cmd * 0x?? - Completion code * 0x?? - Fujitsu IANA (LSB first) * 0x?? - Fujitsu IANA * 0x?? - Fujitsu IANA * 0x?? - error led state * * GEL - Global Error LED * CSS - Customer Self Service LED * * 0 - CSS off / GEL off * 1 - CSS off / GEL on * 2 - CSS off / GEL blink * 3 - CSS on / GEL off * 4 - CSS on / GEL on * 5 - CSS on / GEL blink * 6 - CSS blink / GEL off * 7 - CSS blink / GEL on * 8 - CSS blink / GEL blink */ bytes_rq[0] = IPMI_CMD_OEM_FUJITSU_SYSTEM; bytes_rq[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF); bytes_rq[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8; bytes_rq[3] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16; bytes_rq[4] = IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_ERROR_LED; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_GROUP_RQ, /* network function */ bytes_rq, /* data */ 5, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 6, IPMI_CMD_OEM_FUJITSU_SYSTEM, IPMI_NET_FN_OEM_GROUP_RS, NULL) < 0) goto cleanup; state = bytes_rs[5]; switch (state) { case IPMI_OEM_FUJITSU_ERROR_LED_CSS_OFF_GEL_OFF: case IPMI_OEM_FUJITSU_ERROR_LED_CSS_OFF_GEL_ON: case IPMI_OEM_FUJITSU_ERROR_LED_CSS_OFF_GEL_BLINK: pstdout_printf (state_data->pstate, "CSS LED: off\n"); break; case IPMI_OEM_FUJITSU_ERROR_LED_CSS_ON_GEL_OFF: case IPMI_OEM_FUJITSU_ERROR_LED_CSS_ON_GEL_ON: case IPMI_OEM_FUJITSU_ERROR_LED_CSS_ON_GEL_BLINK: pstdout_printf (state_data->pstate, "CSS LED: on\n"); break; case IPMI_OEM_FUJITSU_ERROR_LED_CSS_BLINK_GEL_OFF: case IPMI_OEM_FUJITSU_ERROR_LED_CSS_BLINK_GEL_ON: case IPMI_OEM_FUJITSU_ERROR_LED_CSS_BLINK_GEL_BLINK: pstdout_printf (state_data->pstate, "CSS LED: blink\n"); break; default: pstdout_printf (state_data->pstate, "Unrecognized LED state: %02Xh\n", state); goto cleanup; } switch (state) { case IPMI_OEM_FUJITSU_ERROR_LED_CSS_OFF_GEL_OFF: case IPMI_OEM_FUJITSU_ERROR_LED_CSS_ON_GEL_OFF: case IPMI_OEM_FUJITSU_ERROR_LED_CSS_BLINK_GEL_OFF: pstdout_printf (state_data->pstate, "GEL LED: off\n"); break; case IPMI_OEM_FUJITSU_ERROR_LED_CSS_OFF_GEL_ON: case IPMI_OEM_FUJITSU_ERROR_LED_CSS_ON_GEL_ON: case IPMI_OEM_FUJITSU_ERROR_LED_CSS_BLINK_GEL_ON: pstdout_printf (state_data->pstate, "GEL LED: on\n"); break; case IPMI_OEM_FUJITSU_ERROR_LED_CSS_OFF_GEL_BLINK: case IPMI_OEM_FUJITSU_ERROR_LED_CSS_ON_GEL_BLINK: case IPMI_OEM_FUJITSU_ERROR_LED_CSS_BLINK_GEL_BLINK: pstdout_printf (state_data->pstate, "GEL LED: blink\n"); break; default: pstdout_printf (state_data->pstate, "Unrecognized LED state: %02Xh\n", state); goto cleanup; } rv = 0; cleanup: return (rv); }
int ipmi_oem_supermicro_set_bmc_services_status (ipmi_oem_state_data_t *state_data) { uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; int rs_len; int rv = -1; assert (state_data); assert (state_data->prog_data->args->oem_options_count == 1); if (strcasecmp (state_data->prog_data->args->oem_options[0], "enable") && strcasecmp (state_data->prog_data->args->oem_options[0], "disable")) { pstdout_fprintf (state_data->pstate, stderr, "%s:%s invalid OEM option argument '%s'\n", state_data->prog_data->args->oem_id, state_data->prog_data->args->oem_command, state_data->prog_data->args->oem_options[0]); goto cleanup; } /* Supermicro OEM * * Request * * 0x30 - OEM network function * 0x70 - OEM cmd * 0xF0 - Sub-command * 0x?? - action * - 0x00 - disable * - 0x01 - enable * - 0x02 - status * * Response * * 0x70 - OEM cmd * 0x?? - Completion Code * 0x?? - if action == status * - 0x00 - disabled * - 0x01 - enabled */ bytes_rq[0] = IPMI_CMD_OEM_SUPERMICRO_GENERIC_EXTENSION; bytes_rq[1] = IPMI_OEM_SUPERMICRO_SUB_COMMAND_BMC_SERVICES; if (!strcasecmp (state_data->prog_data->args->oem_options[0], "enable")) bytes_rq[2] = IPMI_OEM_SUPERMICRO_BMC_SERVICES_ACTION_ENABLE; else /* !strcasecmp (state_data->prog_data->args->oem_options[0], "disable") */ bytes_rq[2] = IPMI_OEM_SUPERMICRO_BMC_SERVICES_ACTION_DISABLE; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_SUPERMICRO_GENERIC_RQ, /* network function */ bytes_rq, /* data */ 3, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 2, IPMI_CMD_OEM_SUPERMICRO_GENERIC_EXTENSION, IPMI_NET_FN_OEM_SUPERMICRO_GENERIC_RS, NULL) < 0) goto cleanup; rv = 0; cleanup: return (rv); }
int ipmi_oem_supermicro_extra_firmware_info (ipmi_oem_state_data_t *state_data) { uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; uint32_t firmware_major_version; uint32_t firmware_minor_version; uint32_t firmware_sub_version; uint32_t firmware_build_number; uint8_t firmware_hardware_id; char firmware_tag[IPMI_OEM_SUPERMICRO_STRING_MAX+1]; int rs_len; int rv = -1; assert (state_data); assert (!state_data->prog_data->args->oem_options_count); memset (firmware_tag, '\0', IPMI_OEM_SUPERMICRO_STRING_MAX + 1); /* Supermicro OEM * * From post by ipmitool developer. * * http://sourceforge.net/mailarchive/message.php?msg_name=49ABCCC3.4040004%40cern.ch * * Request * * 0x3C - OEM network function * 0x20 - OEM cmd * * Response * 0x20 - OEM cmd * 0x?? - Completion Code * 4 bytes - firmware major version (LSB first) * 4 bytes - firmware minor version (LSB first) * 4 bytes - firmware sub version (LSB first) * 4 bytes - firmware build number (LSB first) * 1 byte - hardware ID * ? bytes - firmware tag, null terminated string */ bytes_rq[0] = IPMI_CMD_OEM_SUPERMICRO_EXTRA_FIRMWARE_INFO; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_SUPERMICRO_PEPPERCON_RQ, /* network function */ bytes_rq, /* data */ 1, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 19, IPMI_CMD_OEM_SUPERMICRO_EXTRA_FIRMWARE_INFO, IPMI_NET_FN_OEM_SUPERMICRO_PEPPERCON_RS, NULL) < 0) goto cleanup; firmware_major_version = bytes_rs[2]; firmware_major_version |= (bytes_rs[3] << 8); firmware_major_version |= (bytes_rs[4] << 16); firmware_major_version |= (bytes_rs[5] << 24); firmware_minor_version = bytes_rs[6]; firmware_minor_version |= (bytes_rs[7] << 8); firmware_minor_version |= (bytes_rs[8] << 16); firmware_minor_version |= (bytes_rs[9] << 24); firmware_sub_version = bytes_rs[10]; firmware_sub_version |= (bytes_rs[11] << 8); firmware_sub_version |= (bytes_rs[12] << 16); firmware_sub_version |= (bytes_rs[13] << 24); firmware_build_number = bytes_rs[14]; firmware_build_number |= (bytes_rs[15] << 8); firmware_build_number |= (bytes_rs[16] << 16); firmware_build_number |= (bytes_rs[17] << 24); firmware_hardware_id = bytes_rs[18]; if (rs_len > 19) memcpy (firmware_tag, &bytes_rs[19], rs_len - 19); /* assume minor version is BCD, just like in Get Device ID command */ /* assume sub version is also BCD */ pstdout_printf (state_data->pstate, "Firmware Version : %u.%02x.%02x\n", firmware_major_version, firmware_minor_version, firmware_sub_version); pstdout_printf (state_data->pstate, "Firmware Build Number : %u\n", firmware_build_number); pstdout_printf (state_data->pstate, "Firmware Hardware ID : %u\n", firmware_hardware_id); pstdout_printf (state_data->pstate, "Firmware Tag : %s\n", firmware_tag); rv = 0; cleanup: return (rv); }
int ipmi_oem_fujitsu_set_identify_led (ipmi_oem_state_data_t *state_data) { uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; int rs_len; int rv = -1; assert (state_data); assert (state_data->prog_data->args->oem_options_count == 1); if (strcasecmp (state_data->prog_data->args->oem_options[0], "on") && strcasecmp (state_data->prog_data->args->oem_options[0], "off")) { pstdout_fprintf (state_data->pstate, stderr, "%s:%s invalid OEM option argument '%s'\n", state_data->prog_data->args->oem_id, state_data->prog_data->args->oem_command, state_data->prog_data->args->oem_options[0]); goto cleanup; } /* Fujitsu OEM * * http://manuals.ts.fujitsu.com/file/4390/irmc_s2-en.pdf * * Request * * 0x2E - OEM network function * 0xF5 - OEM cmd * 0x?? - Fujitsu IANA (LSB first) * 0x?? - Fujitsu IANA * 0x?? - Fujitsu IANA * 0xB0 - Command Specifier * 0x?? - led on/off (0 == off, 1 == on) * * Response * * 0xF5 - OEM cmd * 0x?? - Completion code * 0x?? - Fujitsu IANA (LSB first) * 0x?? - Fujitsu IANA * 0x?? - Fujitsu IANA */ bytes_rq[0] = IPMI_CMD_OEM_FUJITSU_SYSTEM; bytes_rq[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF); bytes_rq[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8; bytes_rq[3] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16; bytes_rq[4] = IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_SET_IDENTIFY_LED; if (!strcasecmp (state_data->prog_data->args->oem_options[0], "on")) bytes_rq[5] = IPMI_OEM_FUJITSU_IDENTIFY_LED_ON; else bytes_rq[5] = IPMI_OEM_FUJITSU_IDENTIFY_LED_OFF; if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_GROUP_RQ, /* network function */ bytes_rq, /* data */ 6, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 5, IPMI_CMD_OEM_FUJITSU_SYSTEM, IPMI_NET_FN_OEM_GROUP_RS, NULL) < 0) goto cleanup; rv = 0; cleanup: return (rv); }
int ipmi_oem_sun_set_led (ipmi_oem_state_data_t *state_data) { uint8_t bytes_rq[IPMI_OEM_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_MAX_BYTES]; int rs_len; uint16_t record_id; uint8_t led_mode; long value; char *ptr; uint8_t sdr_record[IPMI_SDR_MAX_RECORD_LENGTH]; int sdr_record_len = 0; uint8_t record_type; uint8_t entity_instance_type; int rv = -1; assert (state_data); assert (state_data->prog_data->args->oem_options_count == 2); errno = 0; value = strtol (state_data->prog_data->args->oem_options[0], &ptr, 10); if (errno || ptr[0] != '\0' || value < 0 || value < IPMI_SDR_RECORD_ID_FIRST || value > IPMI_SDR_RECORD_ID_LAST) { pstdout_fprintf (state_data->pstate, stderr, "%s:%s invalid record_id\n", state_data->prog_data->args->oem_id, state_data->prog_data->args->oem_command); goto cleanup; } record_id = value; if (strcasecmp (state_data->prog_data->args->oem_options[1], "off") && strcasecmp (state_data->prog_data->args->oem_options[1], "on") && strcasecmp (state_data->prog_data->args->oem_options[1], "standby") && strcasecmp (state_data->prog_data->args->oem_options[1], "slow") && strcasecmp (state_data->prog_data->args->oem_options[1], "fast")) { pstdout_fprintf (state_data->pstate, stderr, "%s:%s invalid OEM option argument '%s'\n", state_data->prog_data->args->oem_id, state_data->prog_data->args->oem_command, state_data->prog_data->args->oem_options[1]); goto cleanup; } if (!strcasecmp (state_data->prog_data->args->oem_options[1], "off")) led_mode = IPMI_OEM_SUN_LED_MODE_OFF; else if (!strcasecmp (state_data->prog_data->args->oem_options[1], "on")) led_mode = IPMI_OEM_SUN_LED_MODE_ON; else if (!strcasecmp (state_data->prog_data->args->oem_options[1], "standby")) led_mode = IPMI_OEM_SUN_LED_MODE_STANDBY; else if (!strcasecmp (state_data->prog_data->args->oem_options[1], "slow")) led_mode = IPMI_OEM_SUN_LED_MODE_SLOW; else /* !strcasecmp (state_data->prog_data->args->oem_options[1], "fast") */ led_mode = IPMI_OEM_SUN_LED_MODE_FAST; if (sdr_cache_create_and_load (state_data->sdr_ctx, state_data->pstate, state_data->ipmi_ctx, state_data->hostname, &state_data->prog_data->args->common_args) < 0) goto cleanup; /* Sun OEM * * From Ipmitool (http://ipmitool.sourceforge.net/) * * Set Led Request * * 0x2E - OEM network function (is IPMI_NET_FN_OEM_GROUP_RQ) * 0x22 - OEM cmd * 0x?? - Device Slave Address (in General Device Locator Record) * - Note that the IPMI command requires the entire * byte of the slave address. * 0x?? - LED Type (see below [1]) * - 0 - ok2rm * - 1 - service * - 2 - activity * - 3 - locate * 0x?? - Controller Address / Device Access Address (in General Device Locator Record) * - 0x20 if the LED is local * - Note that the IPMI command requires the entire * byte of the access address. * 0x?? - HW Info (OEM field in General Device Locator Record) * 0x?? - LED Mode * 0x?? - Force * - 0 - Go thru controller * - 1 - Directly access device * 0x?? - Role * - Ipmitool comments state "Used by BMC for authorization purposes" * - achu: I have no idea what this is for, set to 0 like in code * * An alternate format is described in the ipmitool comments for Sun * Blade Moduler Systems. * * 0x2E - OEM network function (is IPMI_NET_FN_OEM_GROUP_RQ) * 0x22 - OEM cmd * 0x?? - Device Slave Address (in General Device Locator Record) * 0x?? - LED Type * 0x?? - Controller Address / Device Access Address (in General Device Locator Record) * 0x?? - HW Info (OEM field in General Device Locator Record) * 0x?? - LED Mode * 0x?? - Entity ID * 0x?? - Entity Instance * - 7 bit version * 0x?? - Force * - 0 - Go thru controller * - 1 - Directly access device * 0x?? - Role * - Ipmitool comments state "Used by BMC for authorization purposes" * - achu: I have no idea what this is for, set to 0 like in code * * Set Led Response * * 0x22 - OEM cmd * 0x?? - Completion Code * * achu notes: * * [1] - As far as I can tell, the LED type field is useless. My * assumption is that on older Sun systems, or other motherboards I * don't have access to, one can specify an LED type, which allows * you to enable/disable a particular LED amongst many. On my Sun * Fire 4140, it appears to do nothing and affect nothing. I will * add in a new option later if it becomes necessary for the user to * specify an LED type. In the meantime, I will copy the code use * in ipmitool and set this field to the OEM field. */ if (ipmi_sdr_cache_search_record_id (state_data->sdr_ctx, record_id) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sdr_cache_search_record_id: %s\n", ipmi_sdr_ctx_errormsg (state_data->sdr_ctx)); goto cleanup; } if ((sdr_record_len = ipmi_sdr_cache_record_read (state_data->sdr_ctx, sdr_record, IPMI_SDR_MAX_RECORD_LENGTH)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sdr_cache_record_read: %s\n", ipmi_sdr_ctx_errormsg (state_data->sdr_ctx)); goto cleanup; } if (ipmi_sdr_parse_record_id_and_type (state_data->sdr_ctx, sdr_record, sdr_record_len, NULL, &record_type) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sdr_parse_record_id_and_type: %s\n", ipmi_sdr_ctx_errormsg (state_data->sdr_ctx)); goto cleanup; } if (record_type != IPMI_SDR_FORMAT_GENERIC_DEVICE_LOCATOR_RECORD) { pstdout_fprintf (state_data->pstate, stderr, "Record ID points to invalid record type: %Xh\n", record_type); goto cleanup; } if (ipmi_sdr_parse_entity_id_instance_type (state_data->sdr_ctx, sdr_record, sdr_record_len, NULL, NULL, &entity_instance_type) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_sdr_parse_entity_id_and_instance: %s\n", ipmi_sdr_ctx_errormsg (state_data->sdr_ctx)); goto cleanup; } if (entity_instance_type != IPMI_SDR_PHYSICAL_ENTITY) { pstdout_fprintf (state_data->pstate, stderr, "Record ID points to non physical entity\n"); goto cleanup; } /* achu: the sun oem commands want the full byte, not just the * sub-field, so use indexes instead of sdr-parse lib. */ bytes_rq[0] = IPMI_CMD_OEM_SUN_SET_LED; bytes_rq[1] = sdr_record[IPMI_SDR_RECORD_GENERIC_DEVICE_LOCATOR_DEVICE_SLAVE_ADDRESS_INDEX]; bytes_rq[2] = sdr_record[IPMI_SDR_RECORD_GENERIC_DEVICE_LOCATOR_OEM_INDEX]; bytes_rq[3] = sdr_record[IPMI_SDR_RECORD_GENERIC_DEVICE_LOCATOR_DEVICE_ACCESS_ADDRESS_INDEX]; bytes_rq[4] = sdr_record[IPMI_SDR_RECORD_GENERIC_DEVICE_LOCATOR_OEM_INDEX]; bytes_rq[5] = led_mode; bytes_rq[6] = IPMI_OEM_SUN_LED_FORCE_GO_THRU_CONTROLLER; bytes_rq[7] = 0; /* see comments above, just set to 0 */ if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_GROUP_RQ, /* network function */ bytes_rq, /* data */ 8, /* num bytes */ bytes_rs, IPMI_OEM_MAX_BYTES)) < 0) { pstdout_fprintf (state_data->pstate, stderr, "ipmi_cmd_raw: %s\n", ipmi_ctx_errormsg (state_data->ipmi_ctx)); goto cleanup; } if (ipmi_oem_check_response_and_completion_code (state_data, bytes_rs, rs_len, 2, IPMI_CMD_OEM_SUN_SET_LED, IPMI_NET_FN_OEM_GROUP_RS, NULL) < 0) goto cleanup; rv = 0; cleanup: return (rv); }
/* * HLiebig: This is a stripped down version of ipmi_oem_fujitsu_get_sel_entry_long_text() * in ipmi-oem/src/ipmi-oem-fujitsu.c * tested against * TX200S3 (iRMC S1) * TX120S2/TX300S6 (iRMC S2) */ static int _ipmi_sel_oem_fujitsu_get_sel_entry_long_text (ipmi_sel_ctx_t ctx, struct ipmi_sel_entry *sel_entry, char *buf, unsigned int buflen, int include_severity) { uint8_t bytes_rq[IPMI_OEM_FUJITSU_MAX_BYTES]; uint8_t bytes_rs[IPMI_OEM_FUJITSU_MAX_BYTES]; int rs_len; uint16_t sel_record_id = 0xFFFF; uint8_t css = 0; uint8_t severity = 0; char data_buf[IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_MAX_DATA_LENGTH + 1]; char string_buf[IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_MAX_STRING_LENGTH + 1]; uint8_t data_length; uint8_t max_read_length; uint8_t offset = 0; uint8_t component_length = 0; const char *css_str = NULL; const char *severity_str = NULL; int rv = -1; assert (ctx); assert (ctx->magic == IPMI_SEL_CTX_MAGIC); assert (ctx->manufacturer_id == IPMI_IANA_ENTERPRISE_ID_FUJITSU); assert (sel_entry); assert (buf); assert (buflen); /* Get current SEL record ID we are working on */ if (sel_get_record_header_info (ctx, sel_entry, &sel_record_id, NULL) < 0) goto cleanup; memset (data_buf, '\0', IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_MAX_DATA_LENGTH + 1); memset (string_buf, '\0', IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_MAX_STRING_LENGTH + 1); /* Note: Referenced documentation is for iRMC S2 version */ if (IPMI_FUJITSU_PRODUCT_ID_IS_IRMC_S1 (ctx->product_id)) { /* iRMC S1 has limits */ max_read_length = IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_IRMC_S1_MAX_READ_LENGTH; data_length = IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_IRMC_S1_MAX_DATA_LENGTH; } else { max_read_length = IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_IRMC_S2_MAX_READ_LENGTH; data_length = IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_IRMC_S2_MAX_DATA_LENGTH; } /* Fujitsu OEM Command * * http://manuals.ts.fujitsu.com/file/4390/irmc_s2-ug-en.pdf * * Request * * 0x2E - OEM network function * 0xF5 - OEM cmd * 0x80 - Fujitsu IANA (LSB first) * 0x28 - Fujitsu IANA * 0x00 - 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) * * Response * * 0xF5 - OEM cmd * 0x?? - Completion code * 0x80 - Fujitsu IANA (LSB first) * 0x28 - Fujitsu IANA * 0x00 - Fujitsu IANA * 0x?? - Next Record ID (LSB) * 0x?? - Next Record ID (MSB) * 0x?? - Actual Record ID (LSB) * 0x?? - Actual Record ID (MSB) * 0x?? - Record type * 0x?? - timestamp (LSB first) * 0x?? - timestamp * 0x?? - timestamp * 0x?? - timestamp * 0x?? - severity * bit 7 - CSS component * - 0 - No CSS component * - 1 - CSS component * bit 6-4 - 000 = INFORMATIONAL * 001 = MINOR * 010 = MAJOR * 011 = CRITICAL * 1xx = unknown * bit 3-0 - reserved * 0x?? - data length (of the whole text) * 0x?? - converted SEL data * - requested number of bytes starting at requested offset (MaxResponseDataSize-1 bytes of data) * 0x00 - trailing '\0' character */ bytes_rq[0] = IPMI_CMD_OEM_FUJITSU_SYSTEM; bytes_rq[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF); bytes_rq[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8; bytes_rq[3] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16; bytes_rq[4] = IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_SEL_ENTRY_LONG_TEXT; bytes_rq[5] = (sel_record_id & 0x00FF); bytes_rq[6] = (sel_record_id & 0xFF00) >> 8; /* Request partial or complete string, depending on product */ bytes_rq[8] = max_read_length; while (offset < data_length) { bytes_rq[7] = offset; /* BMC checks for boundaries, offset + len has to be <= 80 (iRMC S1) <= 100 (iRMC S2) */ if (offset + bytes_rq[8] > data_length) bytes_rq[8] = data_length - offset; if ((rs_len = ipmi_cmd_raw (ctx->ipmi_ctx, 0, /* lun */ IPMI_NET_FN_OEM_GROUP_RQ, /* network function */ bytes_rq, /* data */ 9, /* num bytes */ bytes_rs, IPMI_OEM_FUJITSU_MAX_BYTES)) < 0) { SEL_SET_ERRNUM (ctx, IPMI_SEL_ERR_IPMI_ERROR); goto cleanup; } if (rs_len < 17) { if (rs_len >= 2 && bytes_rs[1] != IPMI_COMP_CODE_COMMAND_SUCCESS) { if (bytes_rs[1] == IPMI_COMP_CODE_INSUFFICIENT_PRIVILEGE_LEVEL) { snprintf (string_buf, IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_MAX_STRING_LENGTH, "[Fujitsu OEM decoding requires administrator privilege]"); goto out; } goto cleanup; } } /* Get severity and CSS flag only once */ if (!offset) { css = (bytes_rs[14] & IPMI_OEM_FUJITSU_CSS_BITMASK); css >>= IPMI_OEM_FUJITSU_CSS_SHIFT; severity = (bytes_rs[14] & IPMI_OEM_FUJITSU_SEVERITY_BITMASK); severity >>= IPMI_OEM_FUJITSU_SEVERITY_SHIFT; } data_length = bytes_rs[15]; bytes_rs[rs_len-1] = '\0'; /* just to be sure it's terminated */ component_length = strlen ((char *)bytes_rs + 16); /* achu: truncate if there is overflow */ if (offset + component_length > data_length) { memcpy (data_buf + offset, &bytes_rs[16], IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_MAX_DATA_LENGTH - offset); offset = data_length; } else { memcpy (data_buf + offset, &bytes_rs[16], component_length); offset += component_length; } }