int 
ipmi_sensors_output_verbose_sensor_reading (ipmi_sensors_state_data_t *state_data,
                                            uint8_t *sdr_record,
                                            unsigned int sdr_record_len,
                                            double *reading)
{
  uint8_t sensor_unit;

  assert(state_data);
  assert(sdr_record);
  assert(sdr_record_len);

  if (sdr_cache_get_sensor_unit (state_data->pstate,
                                 sdr_record,
                                 sdr_record_len,
                                 &sensor_unit) < 0)
    return -1;

  if (reading)
    pstdout_printf (state_data->pstate,
                    "Sensor Reading: %f %s\n",
                    *reading,
                    ipmi_sensor_units[sensor_unit]);
  else
    pstdout_printf (state_data->pstate,
                    "Sensor Reading: %s\n",
                    "NA");

  return 0;
}
Ejemplo n.º 2
0
ipmi_config_err_t
ipmi_config_diff (ipmi_config_state_data_t *state_data)
{
  struct ipmi_config_section *s;
  ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
  ipmi_config_err_t ret = IPMI_CONFIG_ERR_SUCCESS;
  ipmi_config_err_t this_ret;

  assert (state_data);

  s = state_data->sections;
  while (s)
    {
      struct ipmi_config_keyvalue *kv = s->keyvalues;
      while (kv)
        {
          assert (kv->value_input);

          if ((this_ret = kv->key->checkout (state_data,
                                             s->section_name,
                                             kv)) == IPMI_CONFIG_ERR_FATAL_ERROR)
            goto cleanup;

          if (this_ret == IPMI_CONFIG_ERR_SUCCESS)
            {
              if (!same (kv->value_input, kv->value_output))
                pstdout_printf (state_data->pstate,
                                "%s:%s - input=`%s':actual=`%s'\n",
                                s->section_name,
                                kv->key->key_name,
                                kv->value_input,
                                kv->value_output);
            }
          else
            {
              pstdout_printf (state_data->pstate,
                              "\t## ERROR: Unable to checkout %s:%s\n",
                              s->section_name,
                              kv->key->key_name);
              ret = this_ret;
            }
          kv = kv->next;
        }

      s = s->next;
    }

  rv = ret;
 cleanup:
  return (rv);
}
static int
_ipmimonitoring_legacy_simple_output_compact_record (ipmi_sensors_state_data_t *state_data,
                                                     uint16_t record_id,
                                                     int event_message_output_type,
                                                     uint16_t sensor_event_bitmask,
                                                     char **event_message_list,
                                                     unsigned int event_message_list_len)
{
  assert (state_data);
  assert (IPMI_SENSORS_EVENT_VALID (event_message_output_type));

  if (_ipmimonitoring_legacy_simple_output_header (state_data, record_id) < 0)
    return (-1);

  if (state_data->prog_data->args->output_sensor_state)
    {
      char *sensor_state_str = NULL;
      
      if (ipmi_sensors_get_sensor_state (state_data,
                                         event_message_output_type,
                                         sensor_event_bitmask,
                                         &sensor_state_str) < 0)
        return (-1);
      
      pstdout_printf (state_data->pstate,
                      " | %s",
                      sensor_state_str);
    }
  
  if (state_data->prog_data->args->quiet_readings)
    return (0);

  pstdout_printf (state_data->pstate,
                  " | %s | ",
                  IPMIMONITORING_NA_STRING_LEGACY);

  if (ipmi_sensors_output_event_message_list (state_data,
                                              event_message_output_type,
                                              sensor_event_bitmask,
                                              event_message_list,
                                              event_message_list_len,
                                              NULL,
                                              0) < 0)
    return (-1);

  return (0);
}
Ejemplo n.º 4
0
int
ipmi_oem_fujitsu_get_power_off_source (ipmi_oem_state_data_t *state_data)
{
  uint8_t source = 0;
  char str[IPMI_OEM_STR_BUFLEN];
  int rv = -1;

  assert (state_data);
  assert (!state_data->prog_data->args->oem_options_count);

  if (_ipmi_oem_get_power_source (state_data,
                                  IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_POWER_OFF_SOURCE,
                                  &source) < 0)
    goto cleanup;

  memset (str, '\0', IPMI_OEM_STR_BUFLEN);

  switch (source)
    {
    case IPMI_OEM_FUJITSU_POWER_OFF_SOURCE_SOFTWARE:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Software or command");
      break;
    case IPMI_OEM_FUJITSU_POWER_OFF_SOURCE_POWER_SWITCH:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Power switch");
      break;
    case IPMI_OEM_FUJITSU_POWER_OFF_SOURCE_AC_POWER_FAIL:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "AC power fail");
      break;
    case IPMI_OEM_FUJITSU_POWER_OFF_SOURCE_CLOCK_OR_TIMER:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Clock or timer");
      break;
    case IPMI_OEM_FUJITSU_POWER_OFF_SOURCE_FAN_FAILURE:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Fan failure");
      break;
    case IPMI_OEM_FUJITSU_POWER_OFF_SOURCE_CRITICAL_TEMPERATURE:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Critical temperature");
      break;
    case IPMI_OEM_FUJITSU_POWER_OFF_SOURCE_FINAL_POWER_OFF_AFTER_REPEATED_WATCHDOG_TIMEOUTS:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Final power-off after repeated watchdog timeouts");
      break;
    case IPMI_OEM_FUJITSU_POWER_OFF_SOURCE_FINAL_POWER_OFF_AFTER_REPEATED_CPU_ERRORS:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Final power-off after repeated CPU errors");
      break;
    case IPMI_OEM_FUJITSU_POWER_OFF_SOURCE_POWERED_OFF_BY_REMOTE_CONTROL_VIA_REMOTE_MANAGER:
      /* HLiebig: capitalized "remote manager" from doc */
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Powered off by remote control via Remote Manager");
      break;
    default:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Unrecognized source: %02Xh", source);
    }
  
  pstdout_printf (state_data->pstate,
                  "%s\n",
                  str);

  rv = 0;
 cleanup:
  return (rv);
}
static int
_ipmimonitoring_legacy_simple_output_header (ipmi_sensors_state_data_t *state_data,
                                             uint16_t record_id)
{
  char id_string[IPMI_SDR_MAX_ID_STRING_LENGTH + 1];
  uint8_t sensor_type;
  uint8_t event_reading_type_code;
  const char * sensor_type_string = NULL;

  assert (state_data);

  memset (id_string, '\0', IPMI_SDR_MAX_ID_STRING_LENGTH + 1);

  if (ipmi_sdr_parse_id_string (state_data->sdr_ctx,
                                NULL,
                                0,
                                id_string,
                                IPMI_SDR_MAX_ID_STRING_LENGTH) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_sdr_parse_id_string: %s\n",
                       ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
      return (-1);
    }

  if (ipmi_sdr_parse_sensor_type (state_data->sdr_ctx,
                                  NULL,
                                  0,
                                  &sensor_type) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_sdr_parse_sensor_type: %s\n",
                       ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
      return (-1);
    }

  if ((state_data->prog_data->args->interpret_oem_data)
      && (ipmi_sdr_parse_event_reading_type_code (state_data->sdr_ctx,
                                                  NULL,
                                                  0,
                                                  &event_reading_type_code) >= 0))
    sensor_type_string = get_oem_sensor_type_output_string (sensor_type,
                                                            event_reading_type_code,
                                                            state_data->oem_data.manufacturer_id,
                                                            state_data->oem_data.product_id);
  else 
    sensor_type_string = get_sensor_type_output_string (sensor_type);
      
  pstdout_printf (state_data->pstate,
                  "%u | %s | %s",
                  record_id,
                  id_string,
                  sensor_type_string);

  return (0);
}
static ipmi_config_err_t
front_panel_buttons_checkout (ipmi_config_state_data_t *state_data,
			      const char *section_name,
                              struct ipmi_config_keyvalue *kv)
{
  struct front_panel_buttons data;
  ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
  ipmi_config_err_t ret;
  uint8_t enabled = 0;
  char *enabled_str = NULL;

  assert (state_data);
  assert (section_name);
  assert (kv);

  memset (&data, '\0', sizeof (struct front_panel_buttons));
  if ((ret = _get_front_panel_buttons (state_data, &data)) != IPMI_CONFIG_ERR_SUCCESS)
    {
      rv = ret;
      goto cleanup;
    }

  if (!strcasecmp (kv->key->key_name, "Enable_Standby_Button_For_Entering_Standby"))
    enabled = data.standby;
  else if (!strcasecmp (kv->key->key_name, "Enable_Diagnostic_Interrupt_Button"))
    enabled = data.diagnostic_interrupt;
  else if (!strcasecmp (kv->key->key_name, "Enable_Reset_Button"))
    enabled = data.reset;
  else if (!strcasecmp (kv->key->key_name, "Enable_Power_Off_Button_For_Power_Off_Only"))
    enabled = data.power_off;
  else
    {
      if (state_data->prog_data->args->verbose_count)
        pstdout_printf (state_data->pstate,
                        "## Unrecognized section:key_name: %s:%s\n",
                        section_name,
                        kv->key->key_name);
      rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR;
      goto cleanup;
    }

  if (enabled == BUTTON_ENABLED)
    enabled_str = "Yes";
  else if (enabled == BUTTON_DISABLED)
    enabled_str = "No";
  else
    enabled_str = "";

  if (ipmi_config_section_update_keyvalue_output (state_data,
						  kv,
						  enabled_str) < 0)
    return (IPMI_CONFIG_ERR_FATAL_ERROR);

  rv = IPMI_CONFIG_ERR_SUCCESS;
 cleanup:
  return (rv);
}
Ejemplo n.º 7
0
static void
_ipmi_sensors_oem_intel_output_oem_record_fan_control_profile_support (ipmi_sensors_state_data_t *state_data,
								       uint8_t fan_control_profile_support,
								       unsigned int fan_control_profile_number)
{
  assert (state_data);
  assert (state_data->prog_data->args->verbose_count >= 2);
  assert (state_data->prog_data->args->interpret_oem_data);
  assert (state_data->oem_data.manufacturer_id == IPMI_IANA_ENTERPRISE_ID_INTEL);

  pstdout_printf (state_data->pstate,
		  "Fan Control Profile %u Support: %s\n",
		  fan_control_profile_number,
		  fan_control_profile_support == IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE_VALID ? "Yes" : "No");
}
int
ipmi_sensors_output_event_message_list (ipmi_sensors_state_data_t *state_data,
                                        char **event_message_list,
                                        unsigned int event_message_list_len,
                                        char *prefix,
                                        unsigned int each_on_newline)
{
  char spcbuf[IPMI_SENSORS_SPACE_BUFFER + 1];
  int i;

  assert(state_data);
  
  if (prefix)
    pstdout_printf (state_data->pstate, "%s", prefix);
  
  memset(spcbuf, '\0', IPMI_SENSORS_SPACE_BUFFER + 1);
  if (prefix && each_on_newline)
    {
      unsigned int len;
      
      len = strlen(prefix);
      if (len > IPMI_SENSORS_SPACE_BUFFER)
        len = IPMI_SENSORS_SPACE_BUFFER;
      
      for (i = 0; i < len; i++)
        strcat(spcbuf, " ");
    }
  
  if (event_message_list)
    {
      if (event_message_list_len >= 1)
        pstdout_printf (state_data->pstate,
                        "[%s]",
                        event_message_list[0]);

      for (i = 1; i < event_message_list_len; i++)
        {
          if (each_on_newline)
            pstdout_printf (state_data->pstate,
                            "\n");
          pstdout_printf (state_data->pstate,
                          "%s[%s]",
                          spcbuf,
                          event_message_list[i]);
        }

      pstdout_printf (state_data->pstate,
                      "\n");
    }
  else 
    pstdout_printf (state_data->pstate,
                    "[%s]\n",
                    "Unknown"); 
  
  return 0;
}
Ejemplo n.º 9
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);
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
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);
}
Ejemplo n.º 12
0
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);
}
static int
_ipmimonitoring_legacy_simple_output_full_record (ipmi_sensors_state_data_t *state_data,
                                                  uint16_t record_id,
                                                  double *sensor_reading,
                                                  int event_message_output_type,
                                                  uint16_t sensor_event_bitmask,
                                                  char **event_message_list,
                                                  unsigned int event_message_list_len)
{
  int rv = -1;

  assert (state_data);
  assert (IPMI_SENSORS_EVENT_VALID (event_message_output_type));

  if (_ipmimonitoring_legacy_simple_output_header (state_data, record_id) < 0)
    goto cleanup;

  if (state_data->prog_data->args->output_sensor_state)
    {
      char *sensor_state_str = NULL;
      
      if (ipmi_sensors_get_sensor_state (state_data,
                                         event_message_output_type,
                                         sensor_event_bitmask,
                                         &sensor_state_str) < 0)
        goto cleanup;
      
      pstdout_printf (state_data->pstate,
                      " | %s",
                      sensor_state_str);
    }

  if (!state_data->prog_data->args->quiet_readings)
    {
      uint8_t event_reading_type_code;

      if (ipmi_sdr_parse_event_reading_type_code (state_data->sdr_ctx,
                                                  NULL,
                                                  0,
                                                  &event_reading_type_code) < 0)
        {
          pstdout_fprintf (state_data->pstate,
                           stderr,
                           "ipmi_sdr_parse_event_reading_type_code: %s\n",
                           ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
          goto cleanup;
        }
      
      switch (ipmi_event_reading_type_code_class (event_reading_type_code))
        {
        case IPMI_EVENT_READING_TYPE_CODE_CLASS_THRESHOLD:
          {
            char sensor_units_buf[IPMI_SENSORS_UNITS_BUFLEN+1];
            
            memset (sensor_units_buf, '\0', IPMI_SENSORS_UNITS_BUFLEN+1);
            if (get_sensor_units_output_string (state_data->pstate,
                                                state_data->sdr_ctx,
                                                sensor_units_buf,
                                                IPMI_SENSORS_UNITS_BUFLEN,
                                                0) < 0)
              goto cleanup;
            
            
            if (sensor_reading)
              pstdout_printf (state_data->pstate,
                              " | %s | %f\n",
                              sensor_units_buf,
                              *sensor_reading);
            else
              pstdout_printf (state_data->pstate,
                              " | %s | %s\n",
                              sensor_units_buf,
                              IPMIMONITORING_NA_STRING_LEGACY);
          }

          break;
          
        case IPMI_EVENT_READING_TYPE_CODE_CLASS_GENERIC_DISCRETE:
        case IPMI_EVENT_READING_TYPE_CODE_CLASS_SENSOR_SPECIFIC_DISCRETE:
        case IPMI_EVENT_READING_TYPE_CODE_CLASS_OEM:
        default:
          /* sensor units */
          pstdout_printf (state_data->pstate,
                          " | %s | ",
                          IPMIMONITORING_NA_STRING_LEGACY);
          
          if (ipmi_sensors_output_event_message_list (state_data,
                                                      event_message_output_type,
                                                      sensor_event_bitmask,
                                                      event_message_list,
                                                      event_message_list_len,
                                                      NULL,
                                                      0) < 0)
            goto cleanup;
          
          break;
        }
    }
  else
    pstdout_printf (state_data->pstate,
                    "\n");

  rv = 0;
 cleanup:
  return (rv);
}
static int
_sections_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_sensors_config_sdr_callback *sdr_callback_arg;
  ipmi_sensors_config_state_data_t *state_data;
  struct config_section *section = NULL;
  uint8_t event_reading_type_code;
  int event_reading_type_code_class;
  config_err_t ret;

  assert (sdr_ctx);
  assert (sdr_record);
  assert (sdr_record_len);
  assert (arg);

  sdr_callback_arg = (struct ipmi_sensors_config_sdr_callback *)arg;
  state_data = sdr_callback_arg->state_data;

  /* achu:
   *
   * Technically, the IPMI spec lists that compact record formats
   * also support settable thresholds.  However, since compact
   * records don't contain any information for interpreting
   * threshold sensors (e.g. R exponent) I don't know how they
   * could be of any use.  No vendor that I know of supports
   * threshold sensors via a compact record (excluding possible
   * OEM ones).
   *
   * There's a part of me that believes the readable/setting
   * threshold masks for compact sensor records is a cut and paste
   * typo.  It shouldn't be there.
   */
  
  if (record_type != IPMI_SDR_FORMAT_FULL_SENSOR_RECORD
      && record_type != IPMI_SDR_FORMAT_COMPACT_SENSOR_RECORD)
    {
      if (state_data->prog_data->args->config_args.verbose_count)
	pstdout_fprintf (state_data->pstate,
			 stderr,
			 "## Cannot handle SDR record format '0x%X'\n",
			 record_type);
      return (0);
    }
  
  if (ipmi_sdr_parse_event_reading_type_code (state_data->sdr_ctx,
					      sdr_record,
					      sdr_record_len,
					      &event_reading_type_code) < 0)
    {
      pstdout_fprintf (state_data->pstate,
		       stderr,
		       "ipmi_sdr_parse_event_reading_type_code: %s\n",
		       ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
      return (-1);
    }

  event_reading_type_code_class = ipmi_event_reading_type_code_class (event_reading_type_code);

  if (event_reading_type_code_class == IPMI_EVENT_READING_TYPE_CODE_CLASS_THRESHOLD)
    {
      if (record_type != IPMI_SDR_FORMAT_FULL_SENSOR_RECORD)
	{
	  if (state_data->prog_data->args->config_args.verbose_count)
	    pstdout_printf (state_data->pstate,
			    "## Unable to handle threshold sensor with compact SDR record\n");
	  return (0);
	}

      if ((ret = ipmi_sensors_config_threshold_section (state_data,
							&section)) != CONFIG_ERR_SUCCESS)
	{
	  if (ret == CONFIG_ERR_FATAL_ERROR)
	    return (-1);
	  return (0);
	}
    }
  else if (event_reading_type_code_class == IPMI_EVENT_READING_TYPE_CODE_CLASS_GENERIC_DISCRETE
	   || event_reading_type_code_class == IPMI_EVENT_READING_TYPE_CODE_CLASS_SENSOR_SPECIFIC_DISCRETE)
    {
      if ((ret = ipmi_sensors_config_discrete_section (state_data,
						       &section)) != CONFIG_ERR_SUCCESS)
	{
	  if (ret == CONFIG_ERR_FATAL_ERROR)
	    return (-1);
	  return (0);
	}
    }
  else
    {
      if (state_data->prog_data->args->config_args.common_args.debug)
	pstdout_fprintf (state_data->pstate,
			 stderr,
			 "## Cannot handle SDR with event reading type code '0x%X'\n",
			 event_reading_type_code);
      return (0);
    }

  if (config_section_append (&sdr_callback_arg->sections, section) < 0)
    return (-1);

  return (0);
}
/* return (0) - no OEM match
 * return (1) - OEM match
 * return (-1) - error, cleanup and return error
 */
int
ipmi_sensors_oem_intel_node_manager_output_oem_record (ipmi_sensors_state_data_t *state_data)
{
  assert (state_data);
  assert (state_data->prog_data->args->verbose_count >= 2);
  assert (state_data->prog_data->args->interpret_oem_data);

  if (state_data->intel_node_manager.node_manager_data_found)
    {
      uint8_t nm_device_slave_address;
      uint8_t sensor_owner_lun;
      uint8_t channel_number;
      uint8_t nm_health_event_sensor_number;
      uint8_t nm_exception_event_sensor_number;
      uint8_t nm_operational_capabilities_sensor_number;
      uint8_t nm_alert_threshold_exceeded_sensor_number;
      int ret;
      
      if ((ret = ipmi_sdr_oem_parse_intel_node_manager (state_data->sdr_ctx,
							NULL,
							0,
							&nm_device_slave_address,
							&sensor_owner_lun,
							&channel_number,
							&nm_health_event_sensor_number,
							&nm_exception_event_sensor_number,
							&nm_operational_capabilities_sensor_number,
							&nm_alert_threshold_exceeded_sensor_number)) < 0)
	{
	  pstdout_fprintf (state_data->pstate,
			   stderr,
			   "ipmi_sdr_oem_parse_intel_node_manager: %s\n",
			   ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
	  return (-1);
	}
      
      if (ret)
	{
	  pstdout_printf (state_data->pstate,
			  "Node Manager Device Slave Address: %Xh\n",
			  nm_device_slave_address);
	  pstdout_printf (state_data->pstate,
			  "Sensor Owner LUN: %Xh\n",
			  sensor_owner_lun);
	  pstdout_printf (state_data->pstate,
			  "Channel Number: %Xh\n",
			  channel_number);
	  pstdout_printf (state_data->pstate,
			  "Node Manager Health Event Sensor Number: %u\n",
			  nm_health_event_sensor_number);
	  pstdout_printf (state_data->pstate,
			  "Node Manager Exception Event Sensor Number: %u\n",
			  nm_exception_event_sensor_number);
	  pstdout_printf (state_data->pstate,
			  "Node Manager Operational Capabilities Sensor Number: %u\n",
			  nm_operational_capabilities_sensor_number);
	  pstdout_printf (state_data->pstate,
			  "Node Manager Alert Threshold Exceeded Sensor Number: %u\n",
			  nm_alert_threshold_exceeded_sensor_number);

	  return (1);
	}
    }

  return (0);
}
int
ipmi_sensors_output_verbose_sensor_reading_ranges (ipmi_sensors_state_data_t *state_data,
                                                   uint8_t *sdr_record,
                                                   unsigned int sdr_record_len)
{
  double *nominal_reading = NULL;
  double *normal_maximum = NULL;
  double *normal_minimum = NULL;
  double *sensor_maximum_reading = NULL;
  double *sensor_minimum_reading = NULL;
  uint8_t sensor_unit;
  int rv = -1;

  assert(state_data);
  assert(sdr_record);
  assert(sdr_record_len);

  if (sdr_cache_get_sensor_unit (state_data->pstate,
                                 sdr_record,
                                 sdr_record_len,
                                 &sensor_unit) < 0)
    goto cleanup;

  if (sdr_cache_get_sensor_reading_ranges (state_data->pstate,
                                           sdr_record,
                                           sdr_record_len,
                                           &nominal_reading,
                                           &normal_maximum,
                                           &normal_minimum,
                                           &sensor_maximum_reading,
                                           &sensor_minimum_reading) < 0)
      goto cleanup;

  /* don't output at all if there isn't atleast 1 threshold to output */
  if (!sensor_minimum_reading
      && !sensor_maximum_reading
      && !normal_minimum
      && !normal_maximum
      && !nominal_reading)
    {
      rv = 0;
      goto cleanup;
    }

  if (sensor_minimum_reading)
    pstdout_printf (state_data->pstate,
                    "Sensor Min. Reading: %f %s\n",
                    *sensor_minimum_reading,
                    ipmi_sensor_units[sensor_unit]);
  else
    pstdout_printf (state_data->pstate,
                    "Sensor Min. Reading: %s\n",
                    "NA");

  if (sensor_maximum_reading)
    pstdout_printf (state_data->pstate,
                    "Sensor Max. Reading: %f %s\n",
                    *sensor_maximum_reading,
                    ipmi_sensor_units[sensor_unit]);
  else
    pstdout_printf (state_data->pstate,
                    "Sensor Max. Reading: %s\n",
                    "NA");

  if (normal_minimum)
    pstdout_printf (state_data->pstate,
                    "Normal Min.: %f %s\n",
                    *normal_minimum,
                    ipmi_sensor_units[sensor_unit]);
  else
    pstdout_printf (state_data->pstate,
                    "Normal Min.: %s\n",
                    "NA");

  if (normal_maximum)
    pstdout_printf (state_data->pstate,
                    "Normal Max.: %f %s\n",
                    *normal_maximum,
                    ipmi_sensor_units[sensor_unit]);
  else
    pstdout_printf (state_data->pstate,
                    "Normal Max.: %s\n",
                    "NA");

  if (nominal_reading)
    pstdout_printf (state_data->pstate,
                    "Nominal reading: %f %s\n",
                    *nominal_reading,
                    ipmi_sensor_units[sensor_unit]);
  else
    pstdout_printf (state_data->pstate,
                    "Nominal reading: %s\n",
                    "NA");

  rv = 0;
 cleanup:
  if (nominal_reading)
    free(nominal_reading);
  if (normal_maximum)
    free(normal_maximum);
  if (normal_minimum)
    free(normal_minimum);
  if (sensor_maximum_reading)
    free(sensor_maximum_reading);
  if (sensor_minimum_reading)
    free(sensor_minimum_reading);
  return rv;
}
int
ipmi_sensors_output_verbose_thresholds (ipmi_sensors_state_data_t *state_data,
                                        uint8_t *sdr_record,
                                        unsigned int sdr_record_len)
{
  double *lower_non_critical_threshold = NULL;
  double *lower_critical_threshold = NULL;
  double *lower_non_recoverable_threshold = NULL;
  double *upper_non_critical_threshold = NULL;
  double *upper_critical_threshold = NULL;
  double *upper_non_recoverable_threshold = NULL;
  uint8_t sensor_unit;
  int rv = -1;
  
  assert(state_data);
  assert(sdr_record);
  assert(sdr_record_len);

  if (sdr_cache_get_sensor_unit (state_data->pstate,
                                 sdr_record,
                                 sdr_record_len,
                                 &sensor_unit) < 0)
    goto cleanup;

  if (ipmi_sensors_get_thresholds (state_data,
                                   sdr_record,
                                   sdr_record_len,
                                   &lower_non_critical_threshold,
                                   &lower_critical_threshold,
                                   &lower_non_recoverable_threshold,
                                   &upper_non_critical_threshold,
                                   &upper_critical_threshold,
                                   &upper_non_recoverable_threshold) < 0)
    goto cleanup;

  /* don't output at all if there isn't atleast 1 threshold to output */
  if (!lower_critical_threshold
      && !upper_critical_threshold
      && !lower_non_critical_threshold
      && !upper_non_critical_threshold
      && !lower_non_recoverable_threshold
      && !upper_non_recoverable_threshold)
    {
      rv = 0;
      goto cleanup;
    }

  if (lower_critical_threshold)
    pstdout_printf (state_data->pstate,
                    "Lower Critical Threshold: %f %s\n", 
                    *lower_critical_threshold, 
                    ipmi_sensor_units[sensor_unit]);
  else
    pstdout_printf (state_data->pstate, 
                    "Lower Critical Threshold: %s\n", 
                    "NA");

  if (upper_critical_threshold)
    pstdout_printf (state_data->pstate, 
                    "Upper Critical Threshold: %f %s\n", 
                    *upper_critical_threshold, 
                    ipmi_sensor_units[sensor_unit]);
  else
    pstdout_printf (state_data->pstate, 
                    "Upper Critical Threshold: %s\n", 
                    "NA");

  if (lower_non_critical_threshold)
    pstdout_printf (state_data->pstate, 
                    "Lower Non-Critical Threshold: %f %s\n", 
                    *lower_non_critical_threshold, 
                    ipmi_sensor_units[sensor_unit]);
  else
    pstdout_printf (state_data->pstate, 
                    "Lower Non-Critical Threshold: %s\n", 
                    "NA");

  if (upper_non_critical_threshold)
    pstdout_printf (state_data->pstate, 
                    "Upper Non-Critical Threshold: %f %s\n", 
                    *upper_non_critical_threshold, 
                    ipmi_sensor_units[sensor_unit]);
  else
    pstdout_printf (state_data->pstate, 
                    "Upper Non-Critical Threshold: %s\n", 
                    "NA");

  if (lower_non_recoverable_threshold)
    pstdout_printf (state_data->pstate, 
                    "Lower Non-Recoverable Threshold: %f %s\n", 
                    *lower_non_recoverable_threshold, 
                    ipmi_sensor_units[sensor_unit]);
  else
    pstdout_printf (state_data->pstate, 
                    "Lower Non-Recoverable Threshold: %s\n", 
                    "NA");

  if (upper_non_recoverable_threshold)
    pstdout_printf (state_data->pstate, 
                    "Upper Non-Recoverable Threshold: %f %s\n", 
                    *upper_non_recoverable_threshold, 
                    ipmi_sensor_units[sensor_unit]);
  else
    pstdout_printf (state_data->pstate, 
                    "Upper Non-Recoverable Threshold: %s\n", 
                    "NA");

  rv = 0;
 cleanup:
  if (lower_non_critical_threshold)
    free(lower_non_critical_threshold);
  if (lower_critical_threshold)
    free(lower_critical_threshold);
  if (lower_non_recoverable_threshold)
    free(lower_non_recoverable_threshold);
  if (upper_non_critical_threshold)
    free(upper_non_critical_threshold);
  if (upper_critical_threshold)
    free(upper_critical_threshold);
  if (upper_non_recoverable_threshold)
    free(upper_non_recoverable_threshold);
  return rv;
}                              
static int
_simple_output_compact_record (ipmi_sensors_state_data_t *state_data,
                               uint16_t record_id,
                               uint8_t sensor_number,
                               int event_message_output_type,
                               uint16_t sensor_event_bitmask,                              
                               char **event_message_list,
                               unsigned int event_message_list_len)
{
  assert (state_data);
  assert (IPMI_SENSORS_EVENT_VALID (event_message_output_type));

  if (_simple_output_header (state_data,
                             record_id,
                             sensor_number,
                             event_message_output_type,
                             sensor_event_bitmask) < 0)
    return (-1);

  if (!state_data->prog_data->args->quiet_readings)
    {
      char fmt[IPMI_SENSORS_FMT_BUFLEN + 1];
  
      memset (fmt, '\0', IPMI_SENSORS_FMT_BUFLEN + 1);

      if (state_data->prog_data->args->comma_separated_output)
        snprintf (fmt,
                  IPMI_SENSORS_FMT_BUFLEN,
                  ",%%s,%%s");
      else
        snprintf (fmt,
                  IPMI_SENSORS_FMT_BUFLEN,
                  " | %%-10s | %%-%ds",
                  state_data->column_width.sensor_units);

      pstdout_printf (state_data->pstate,
                      fmt,
                      IPMI_SENSORS_NA_STRING,
                      IPMI_SENSORS_NA_STRING);
    }

  if (state_data->prog_data->args->output_sensor_thresholds)
    {
      if (state_data->prog_data->args->comma_separated_output)
        pstdout_printf (state_data->pstate,
                        ",%s,%s,%s,%s,%s,%s",
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING);
      else
        pstdout_printf (state_data->pstate,
                        " | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s",
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING,
                        IPMI_SENSORS_NA_STRING);
    }
 
  if (state_data->prog_data->args->comma_separated_output)
    pstdout_printf (state_data->pstate, ",");
  else
    pstdout_printf (state_data->pstate, " | ");

  if (ipmi_sensors_output_event_message_list (state_data,
                                              event_message_output_type,
                                              sensor_event_bitmask,
                                              event_message_list,
                                              event_message_list_len,
                                              NULL,
                                              0) < 0)
    return (-1);

  return (0);
}
static int
_simple_output_full_record (ipmi_sensors_state_data_t *state_data,
                            uint16_t record_id,
                            uint8_t sensor_number,
                            double *sensor_reading,
                            int event_message_output_type,
                            uint16_t sensor_event_bitmask,
                            char **event_message_list,
                            unsigned int event_message_list_len)
{
  char fmt[IPMI_SENSORS_FMT_BUFLEN + 1];
  uint8_t event_reading_type_code;
  double *lower_non_critical_threshold = NULL;
  double *upper_non_critical_threshold = NULL;
  double *lower_critical_threshold = NULL;
  double *upper_critical_threshold = NULL;
  double *lower_non_recoverable_threshold = NULL;
  double *upper_non_recoverable_threshold = NULL;
  int rv = -1;

  assert (state_data);
  assert (IPMI_SENSORS_EVENT_VALID (event_message_output_type));

  if (_simple_output_header (state_data,
                             record_id,
                             sensor_number,
                             event_message_output_type,
                             sensor_event_bitmask) < 0)
    goto cleanup;

  if (ipmi_sdr_parse_event_reading_type_code (state_data->sdr_ctx,
                                              NULL,
                                              0,
                                              &event_reading_type_code) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_sdr_parse_event_reading_type_code: %s\n",
                       ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
      goto cleanup;
    }

  switch (ipmi_event_reading_type_code_class (event_reading_type_code))
    {
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_THRESHOLD:
      if (!state_data->prog_data->args->quiet_readings)
        {
          char sensor_units_buf[IPMI_SENSORS_UNITS_BUFLEN+1];

          memset (sensor_units_buf, '\0', IPMI_SENSORS_UNITS_BUFLEN+1);
          if (get_sensor_units_output_string (state_data->pstate,
                                              state_data->sdr_ctx,
                                              sensor_units_buf,
                                              IPMI_SENSORS_UNITS_BUFLEN,
                                              state_data->prog_data->args->non_abbreviated_units) < 0)
            goto cleanup;

          memset (fmt, '\0', IPMI_SENSORS_FMT_BUFLEN + 1);

          if (sensor_reading)
            {
              if (state_data->prog_data->args->comma_separated_output)
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          ",%%.2f,%%s");
              else
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          " | %%-10.2f | %%-%ds",
                          state_data->column_width.sensor_units);
              
              pstdout_printf (state_data->pstate,
                              fmt,
                              _round_double2 (*sensor_reading),
                              sensor_units_buf);
            }
          else
            {
              if (state_data->prog_data->args->comma_separated_output)
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          ",%%s,%%s");
              else
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          " | %%-10s | %%-%ds",
                          state_data->column_width.sensor_units);
              
              pstdout_printf (state_data->pstate,
                              fmt,
                              IPMI_SENSORS_NA_STRING,
                              sensor_units_buf);
            }
        }

      if (state_data->prog_data->args->output_sensor_thresholds)
        {
          char thresholdfmt[IPMI_SENSORS_FMT_BUFLEN + 1];
          char nafmt[IPMI_SENSORS_FMT_BUFLEN + 1];

          if (ipmi_sensors_get_thresholds (state_data,
                                           &lower_non_critical_threshold,
                                           &lower_critical_threshold,
                                           &lower_non_recoverable_threshold,
                                           &upper_non_critical_threshold,
                                           &upper_critical_threshold,
                                           &upper_non_recoverable_threshold) < 0)
            goto cleanup;

          memset (fmt, '\0', IPMI_SENSORS_FMT_BUFLEN + 1);

          if (state_data->prog_data->args->comma_separated_output)
            {
              snprintf (thresholdfmt,
                        IPMI_SENSORS_FMT_BUFLEN,
                        ",%%.2f");

              snprintf (nafmt,
                        IPMI_SENSORS_FMT_BUFLEN,
                        ",%%s");
            }
          else
            {
              snprintf (thresholdfmt,
                        IPMI_SENSORS_FMT_BUFLEN,
                        " | %%-10.2f");

              snprintf (nafmt,
                        IPMI_SENSORS_FMT_BUFLEN,
                        " | %%-10s");
            }

          if (lower_non_recoverable_threshold)
            pstdout_printf (state_data->pstate,
                            thresholdfmt,
                            *lower_non_recoverable_threshold);
          else
            pstdout_printf (state_data->pstate,
                            nafmt,
                            IPMI_SENSORS_NA_STRING);

          if (lower_critical_threshold)
            pstdout_printf (state_data->pstate,
                            thresholdfmt,
                            *lower_critical_threshold);
          else
            pstdout_printf (state_data->pstate,
                            nafmt,
                            IPMI_SENSORS_NA_STRING);

          if (lower_non_critical_threshold)
            pstdout_printf (state_data->pstate,
                            thresholdfmt,
                            *lower_non_critical_threshold);
          else
            pstdout_printf (state_data->pstate,
                            nafmt,
                            IPMI_SENSORS_NA_STRING);
                          
          if (upper_non_critical_threshold)
            pstdout_printf (state_data->pstate,
                            thresholdfmt,
                            *upper_non_critical_threshold);
          else
            pstdout_printf (state_data->pstate,
                            nafmt,
                            IPMI_SENSORS_NA_STRING);

          if (upper_critical_threshold)
            pstdout_printf (state_data->pstate,
                            thresholdfmt,
                            *upper_critical_threshold);
          else
            pstdout_printf (state_data->pstate,
                            nafmt,
                            IPMI_SENSORS_NA_STRING);

          if (upper_non_recoverable_threshold)
            pstdout_printf (state_data->pstate,
                            thresholdfmt,
                            *upper_non_recoverable_threshold);
          else
            pstdout_printf (state_data->pstate,
                            nafmt,
                            IPMI_SENSORS_NA_STRING);
        }

      if (state_data->prog_data->args->comma_separated_output)
        pstdout_printf (state_data->pstate, ",");
      else
        pstdout_printf (state_data->pstate, " | ");

      if (ipmi_sensors_output_event_message_list (state_data,
                                                  event_message_output_type,
                                                  sensor_event_bitmask,
                                                  event_message_list,
                                                  event_message_list_len,
                                                  NULL,
                                                  0) < 0)
        goto cleanup;

      break;
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_GENERIC_DISCRETE:
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_SENSOR_SPECIFIC_DISCRETE:
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_OEM:
    default:
      if (!state_data->prog_data->args->quiet_readings)
        {
          if (state_data->prog_data->args->common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_DISCRETE_READING
              && sensor_reading)
            {
              char sensor_units_buf[IPMI_SENSORS_UNITS_BUFLEN+1];

              memset (sensor_units_buf, '\0', IPMI_SENSORS_UNITS_BUFLEN+1);
              if (get_sensor_units_output_string (state_data->pstate,
                                                  state_data->sdr_ctx,
                                                  sensor_units_buf,
                                                  IPMI_SENSORS_UNITS_BUFLEN,
                                                  state_data->prog_data->args->non_abbreviated_units) < 0)
                goto cleanup;
              
              memset (fmt, '\0', IPMI_SENSORS_FMT_BUFLEN + 1);

              if (state_data->prog_data->args->comma_separated_output)
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          ",%%.2f,%%s");
              else
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          " | %%-10.2f | %%-%ds",
                          state_data->column_width.sensor_units);
                  
              pstdout_printf (state_data->pstate,
                              fmt,
                              _round_double2 (*sensor_reading),
                              sensor_units_buf);
            }
          else
            {
              memset (fmt, '\0', IPMI_SENSORS_FMT_BUFLEN + 1);

              if (state_data->prog_data->args->comma_separated_output)
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          ",%%s,%%s");
              else
                snprintf (fmt,
                          IPMI_SENSORS_FMT_BUFLEN,
                          " | %%-10s | %%-%ds",
                          state_data->column_width.sensor_units);
              
              pstdout_printf (state_data->pstate,
                              fmt,
                              IPMI_SENSORS_NA_STRING,
                              IPMI_SENSORS_NA_STRING);
            }
        }

      if (state_data->prog_data->args->output_sensor_thresholds)
        {
          if (state_data->prog_data->args->comma_separated_output)
            pstdout_printf (state_data->pstate,
                            ",%s,%s,%s,%s,%s,%s",
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING);
          else
            pstdout_printf (state_data->pstate,
                            " | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s",
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING,
                            IPMI_SENSORS_NA_STRING);
        }
 
      if (state_data->prog_data->args->comma_separated_output)
        pstdout_printf (state_data->pstate, ",");
      else
        pstdout_printf (state_data->pstate, " | ");
      
      if (ipmi_sensors_output_event_message_list (state_data,
                                                  event_message_output_type,
                                                  sensor_event_bitmask,
                                                  event_message_list,
                                                  event_message_list_len,
                                                  NULL,
                                                  0) < 0)
        goto cleanup;
      break;
    }

  rv = 0;
 cleanup:
  free (lower_non_critical_threshold);
  free (upper_non_critical_threshold);
  free (lower_critical_threshold);
  free (upper_critical_threshold);
  free (lower_non_recoverable_threshold);
  free (upper_non_recoverable_threshold);
  return (rv);
}
static int
_simple_output_header (ipmi_sensors_state_data_t *state_data,
                       uint16_t record_id,
                       uint8_t sensor_number,
                       int event_message_output_type,
                       uint16_t sensor_event_bitmask)
{
  char fmt[IPMI_SENSORS_FMT_BUFLEN + 1];
  char sensor_name[IPMI_SDR_MAX_SENSOR_NAME_LENGTH + 1];
  unsigned int sensor_name_flags = 0;
  const char *sensor_type_string;
  uint8_t event_reading_type_code;

  assert (state_data);
  assert (IPMI_SENSORS_EVENT_VALID (event_message_output_type));

  memset (sensor_name, '\0', IPMI_SDR_MAX_SENSOR_NAME_LENGTH + 1);
      
  if (!state_data->prog_data->args->shared_sensors)
    sensor_name_flags |= IPMI_SDR_SENSOR_NAME_FLAGS_IGNORE_SHARED_SENSORS;

  if (state_data->prog_data->args->entity_sensor_names)
    {
      if (ipmi_sdr_parse_entity_sensor_name (state_data->sdr_ctx,
                                             NULL,
                                             0,
                                             sensor_number,
                                             sensor_name_flags,
                                             sensor_name,
                                             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);
        }
    }
  else
    {
      if (ipmi_sdr_parse_sensor_name (state_data->sdr_ctx,
                                      NULL,
                                      0,
                                      sensor_number,
                                      sensor_name_flags,
                                      sensor_name,
                                      IPMI_SDR_MAX_SENSOR_NAME_LENGTH) < 0)
        {
          pstdout_fprintf (state_data->pstate,
                           stderr,
                           "ipmi_sdr_parse_sensor_name: %s\n",
                           ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
          return (-1);
        }
    }
  
  memset (fmt, '\0', IPMI_SENSORS_FMT_BUFLEN + 1);
  if (state_data->prog_data->args->no_sensor_type_output)
    {
      if (state_data->prog_data->args->comma_separated_output)
        snprintf (fmt,
                  IPMI_SENSORS_FMT_BUFLEN,
                  "%%u,%%s");
      else
        snprintf (fmt,
                  IPMI_SENSORS_FMT_BUFLEN,
                  "%%-%du | %%-%ds",
                  state_data->column_width.record_id,
                  state_data->column_width.sensor_name);
      
      pstdout_printf (state_data->pstate,
                      fmt,
                      record_id,
                      sensor_name);
    }
  else
    {     
      uint8_t sensor_type;

      if (ipmi_sdr_parse_sensor_type (state_data->sdr_ctx,
                                      NULL,
                                      0,
                                      &sensor_type) < 0)
        {
          pstdout_fprintf (state_data->pstate,
                           stderr,
                           "ipmi_sdr_parse_sensor_type: %s\n",
                           ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
          return (-1);
        }
      
      if (state_data->prog_data->args->comma_separated_output)
        snprintf (fmt,
                  IPMI_SENSORS_FMT_BUFLEN,
                  "%%u,%%s,%%s");
      else
        snprintf (fmt,
                  IPMI_SENSORS_FMT_BUFLEN,
                  "%%-%du | %%-%ds | %%-%ds",
                  state_data->column_width.record_id,
                  state_data->column_width.sensor_name,
                  state_data->column_width.sensor_type);
      
      if ((state_data->prog_data->args->interpret_oem_data)
          && (ipmi_sdr_parse_event_reading_type_code (state_data->sdr_ctx,
                                                      NULL,
                                                      0,
                                                      &event_reading_type_code) >= 0))
        sensor_type_string = get_oem_sensor_type_output_string (sensor_type,
                                                                event_reading_type_code,
                                                                state_data->oem_data.manufacturer_id,
                                                                state_data->oem_data.product_id);
      else 
        sensor_type_string = get_sensor_type_output_string (sensor_type);
      
      pstdout_printf (state_data->pstate,
                      fmt,
                      record_id,
                      sensor_name,
                      sensor_type_string);
    }

  if (state_data->prog_data->args->output_sensor_state)
    {
      char *sensor_state_str = NULL;

      if (ipmi_sensors_get_sensor_state (state_data,
                                         event_message_output_type,
                                         sensor_event_bitmask,
                                         &sensor_state_str) < 0)
        return (-1);

      if (state_data->prog_data->args->comma_separated_output)
        snprintf (fmt,
                  IPMI_SENSORS_FMT_BUFLEN,
                  ",%%s");
      else
        snprintf (fmt,
                  IPMI_SENSORS_FMT_BUFLEN,
                  " | %%-8s");

      pstdout_printf (state_data->pstate,
                      fmt,
                      sensor_state_str);
    }
      
  return (0);
}
static ipmi_config_err_t
front_panel_buttons_commit (ipmi_config_state_data_t *state_data,
			    const char *section_name,
                            const struct ipmi_config_keyvalue *kv)
{
  struct front_panel_buttons data;
  ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;
  ipmi_config_err_t ret;
  uint8_t enable_or_disable;
  uint8_t disable_allowed;

  assert (state_data);
  assert (section_name);
  assert (kv);

  memset (&data, '\0', sizeof (struct front_panel_buttons));
  if ((ret = _get_front_panel_buttons (state_data, &data)) != IPMI_CONFIG_ERR_SUCCESS)
    {
      rv = ret;
      goto cleanup;
    }

  if (!strcasecmp (kv->key->key_name, "Enable_Standby_Button_For_Entering_Standby"))
    {
      data.standby = same (kv->value_input, "yes") ? BUTTON_ENABLED : BUTTON_DISABLED;
      enable_or_disable = data.standby;
      disable_allowed = data.standby_disable_allowed;
    }
  else if (!strcasecmp (kv->key->key_name, "Enable_Diagnostic_Interrupt_Button"))
    {
      data.diagnostic_interrupt = same (kv->value_input, "yes") ? BUTTON_ENABLED : BUTTON_DISABLED;
      enable_or_disable = data.diagnostic_interrupt;
      disable_allowed = data.diagnostic_interrupt_disable_allowed;
    }
  else if (!strcasecmp (kv->key->key_name, "Enable_Reset_Button"))
    {
      data.reset = same (kv->value_input, "yes") ? BUTTON_ENABLED : BUTTON_DISABLED;
      enable_or_disable = data.reset;
      disable_allowed = data.reset_disable_allowed;
    }
  else if (!strcasecmp (kv->key->key_name, "Enable_Power_Off_Button_For_Power_Off_Only"))
    {
      data.power_off = same (kv->value_input, "yes") ? BUTTON_ENABLED : BUTTON_DISABLED;
      enable_or_disable = data.power_off;
      disable_allowed = data.power_off_disable_allowed;
    }
  else
    {
      if (state_data->prog_data->args->verbose_count)
        pstdout_printf (state_data->pstate,
                        "## Unrecognized section:key_name: %s:%s\n",
                        section_name,
                        kv->key->key_name);
      rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR;
      goto cleanup;
    }

  if (enable_or_disable == BUTTON_DISABLED
      && disable_allowed == BUTTON_DISABLE_NOT_ALLOWED)
    {
      if (state_data->prog_data->args->verbose_count > 1)
        pstdout_printf (state_data->pstate,
                        "## Button disable on section:key_name '%s:%s' not allowed\n",
                        section_name,
                        kv->key->key_name);
      rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR;
      goto cleanup;
    }

  if (data.standby == BUTTON_UNKNOWN)
    {
      if (state_data->front_panel_enable_standby_button_for_entering_standby_initialized)
        data.standby = state_data->front_panel_enable_standby_button_for_entering_standby;
      else
        data.standby = BUTTON_ENABLED;
    }
  if (data.diagnostic_interrupt == BUTTON_UNKNOWN)
    {
      if (state_data->front_panel_enable_diagnostic_interrupt_button_initialized)
        data.diagnostic_interrupt = state_data->front_panel_enable_diagnostic_interrupt_button;
      else
        data.diagnostic_interrupt = BUTTON_ENABLED;
    }
  if (data.reset == BUTTON_UNKNOWN)
    {
      if (state_data->front_panel_enable_reset_button_initialized)
        data.reset = state_data->front_panel_enable_reset_button;
      else
        data.reset = BUTTON_ENABLED;
    }
  if (data.power_off == BUTTON_UNKNOWN)
    {
      if (state_data->front_panel_enable_power_off_button_for_power_off_only_initialized)
        data.power_off = state_data->front_panel_enable_power_off_button_for_power_off_only;
      else
        data.power_off = BUTTON_ENABLED;
    }

  if ((ret = _set_front_panel_buttons (state_data, &data)) != IPMI_CONFIG_ERR_SUCCESS)
    {
      rv = ret;
      goto cleanup;
    }

  rv = IPMI_CONFIG_ERR_SUCCESS;
 cleanup:
  return (rv);
}
Ejemplo n.º 22
0
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);
}
Ejemplo n.º 23
0
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);
}
Ejemplo n.º 24
0
int
ipmi_oem_fujitsu_get_power_on_source (ipmi_oem_state_data_t *state_data)
{
  uint8_t source = 0;
  char str[IPMI_OEM_STR_BUFLEN];
  int rv = -1;

  assert (state_data);
  assert (!state_data->prog_data->args->oem_options_count);

  if (_ipmi_oem_get_power_source (state_data,
                                  IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_POWER_ON_SOURCE,
                                  &source) < 0)
    goto cleanup;

  memset (str, '\0', IPMI_OEM_STR_BUFLEN);

  switch (source)
    {
    case IPMI_OEM_FUJITSU_POWER_ON_SOURCE_SOFTWARE_OR_COMMAND:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Software or command");
      break;
    case IPMI_OEM_FUJITSU_POWER_ON_SOURCE_POWER_SWITCH:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Power switch");
      break;
    case IPMI_OEM_FUJITSU_POWER_ON_SOURCE_AUTOMATIC_RESTART_AFTER_POWER_FAILURE:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Automatic restart after power failure");
      break;
    case IPMI_OEM_FUJITSU_POWER_ON_SOURCE_CLOCK_OR_TIMER:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Clock or timer");
      break;
    case IPMI_OEM_FUJITSU_POWER_ON_SOURCE_AUTOMATIC_RESTART_AFTER_FAN_FAILURE_SHUTDOWN:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Automatic restart after fan failure shutdown");
      break;
    case IPMI_OEM_FUJITSU_POWER_ON_SOURCE_AUTOMATIC_RESTART_AFTER_CRITICAL_TEMPERATURE_SHUTDOWN:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Automatic restart after critical temperature shutdown");
      break;
    case IPMI_OEM_FUJITSU_POWER_ON_SOURCE_REBOOT_AFTER_WATCHDOG_TIMEOUT:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Reboot after watchdog timeout");
      break;
    case IPMI_OEM_FUJITSU_POWER_ON_SOURCE_REMOTE_ON:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Remote on");
      break;
    case IPMI_OEM_FUJITSU_POWER_ON_SOURCE_REBOOT_AFTER_A_CPU_ERROR:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Reboot after a CPU error");
      break;
    case IPMI_OEM_FUJITSU_POWER_ON_SOURCE_REBOOT_BY_HARDWARE_RESET:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Reboot by hardware reset");
      break;
    case IPMI_OEM_FUJITSU_POWER_ON_SOURCE_REBOOT_AFTER_WARM_START:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Reboot after warm start");
      break;
    case IPMI_OEM_FUJITSU_POWER_ON_SOURCE_POWERED_ON_BY_A_PCI_BUS_POWER_MANAGEMENT_EVENT:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Powered on by a PCI Bus Power Management Event");
      break;
    case IPMI_OEM_FUJITSU_POWER_ON_SOURCE_POWERED_ON_BY_REMOTE_CONTROL_VIA_REMOTE_MANAGER:
      /* HLiebig: capitalized "remote manager" from doc */
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Powered on by remote control via Remote Manager");
      break;
    case IPMI_OEM_FUJITSU_POWER_ON_SOURCE_REBOOT_RESET_BY_REMOTE_CONTROL_VIA_REMOTE_MANAGER:
      /* HLiebig: capitalized "remote manager" from doc */
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Reboot/reset by remote control via Remote Manager");
      break;
    default:
      snprintf (str, IPMI_OEM_STR_BUFLEN, "Unrecognized source: %02Xh", source);
    }
  
  pstdout_printf (state_data->pstate,
                  "%s\n",
                  str);

  rv = 0;
 cleanup:
  return (rv);
}
/* return (0) - no OEM match
 * return (1) - OEM match
 * return (-1) - error, cleanup and return error
 */
int
ipmi_sensors_oem_intel_quanta_qssc_s4r_output_oem_record (ipmi_sensors_state_data_t *state_data,
                                                          uint32_t oem_record_manufacturer_id,
                                                          const uint8_t *oem_data,
                                                          unsigned int oem_data_len)
{
  int ret;

  assert (state_data);
  assert (oem_data);
  assert (oem_data_len);
  assert (state_data->prog_data->args->verbose_count >= 2);
  assert (state_data->prog_data->args->interpret_oem_data);
  assert (state_data->oem_data.manufacturer_id == IPMI_IANA_ENTERPRISE_ID_INTEL);
  assert (state_data->oem_data.product_id == IPMI_INTEL_PRODUCT_ID_QUANTA_QSSC_S4R);
  
  /*
   * Quanta QSSC-S4R/Appro GB812X-CN
   * (Quanta motherboard contains Intel manufacturer ID)
   */

  if ((ret = ipmi_sensors_oem_intel_node_manager_output_oem_record (state_data)) < 0)
    return (-1);

  if (ret)
    return (1);
  
  if (oem_record_manufacturer_id == IPMI_IANA_ENTERPRISE_ID_INTEL)
    {
      uint8_t record_subtype;

      record_subtype = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_SUBTYPE_INDEX];

      if (record_subtype == IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_SUBTYPE
          && oem_data_len >= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_OEM_DATA_LENGTH)
        {
          uint8_t memory_throttling_mode;
          uint8_t fan_control_profile_support_0;
          uint8_t fan_control_profile_support_1;
          uint8_t fan_control_profile_support_2;
          uint8_t fan_control_profile_support_3;
          uint8_t fan_control_profile_support_4;
          uint8_t fan_control_profile_support_5;
          uint8_t fan_control_profile_support_6;
          uint8_t fan_control_profile_support_7;
          uint8_t tempinlet;
          uint8_t temprise;
          uint16_t airflow;
          uint16_t dimmpitch;
          uint8_t throttle_mode;
          uint8_t thermal_register_lock;
          uint8_t hysteresis;
          uint8_t control_event_mode;
          char *memory_throttling_mode_str;
          char *throttle_mode_str;
          char *hysteresis_str;
          char *control_event_mode_str;
        
          memory_throttling_mode = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_MEMORY_THROTTLING_MODE_INDEX];
          memory_throttling_mode &= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_MEMORY_THROTTLING_MODE_BITMASK;
          memory_throttling_mode >>= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_MEMORY_THROTTLING_MODE_SHIFT;
        
          fan_control_profile_support_0 = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE_INDEX];
          fan_control_profile_support_0 &= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE0_BITMASK;
          fan_control_profile_support_0 >>= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE0_SHIFT;
        
          fan_control_profile_support_1 = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE_INDEX];
          fan_control_profile_support_1 &= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE1_BITMASK;
          fan_control_profile_support_1 >>= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE1_SHIFT;
        
          fan_control_profile_support_2 = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE_INDEX];
          fan_control_profile_support_2 &= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE2_BITMASK;
          fan_control_profile_support_2 >>= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE2_SHIFT;
        
          fan_control_profile_support_3 = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE_INDEX];
          fan_control_profile_support_3 &= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE3_BITMASK;
          fan_control_profile_support_3 >>= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE3_SHIFT;
        
          fan_control_profile_support_4 = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE_INDEX];
          fan_control_profile_support_4 &= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE4_BITMASK;
          fan_control_profile_support_4 >>= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE4_SHIFT;
        
          fan_control_profile_support_5 = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE_INDEX];
          fan_control_profile_support_5 &= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE5_BITMASK;
          fan_control_profile_support_5 >>= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE5_SHIFT;
        
          fan_control_profile_support_6 = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE_INDEX];
          fan_control_profile_support_6 &= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE6_BITMASK;
          fan_control_profile_support_6 >>= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE6_SHIFT;
        
          fan_control_profile_support_7 = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE_INDEX];
          fan_control_profile_support_7 &= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE7_BITMASK;
          fan_control_profile_support_7 >>= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_FAN_PROFILE7_SHIFT;
        
          tempinlet = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_TEMPINLET_INDEX];

          temprise = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_TEMPRISE_INDEX];
        
          airflow = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_AIRFLOW_INDEX_START];
          airflow |= (oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_AIRFLOW_INDEX_START + 1] << 8); 
        
          dimmpitch = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_DIMMPITCH_INDEX_START];
          dimmpitch |= (oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_DIMMPITCH_INDEX_START + 1] << 8); 
        
          throttle_mode = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_THROTTLE_MODE_INDEX];
          throttle_mode &= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_THROTTLE_MODE_BITMASK;
          throttle_mode >>= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_THROTTLE_MODE_SHIFT;
        
          thermal_register_lock = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_THERMAL_REGISTER_LOCK_INDEX];
          thermal_register_lock &= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_THERMAL_REGISTER_LOCK_BITMASK;
          thermal_register_lock >>= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_THERMAL_REGISTER_LOCK_SHIFT;

          hysteresis = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_HYSTERESIS_INDEX];
          hysteresis &= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_HYSTERESIS_BITMASK;
          hysteresis >>= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_HYSTERESIS_SHIFT;
              
          control_event_mode = oem_data[IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_CONTROL_EVENT_MODE_INDEX];
          control_event_mode &= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_CONTROL_EVENT_MODE_BITMASK;
          control_event_mode >>= IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_CONTROL_EVENT_MODE_SHIFT;

          if (memory_throttling_mode == IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_MEMORY_THROTTLING_MODE_NONE_SUPPORTED)
            memory_throttling_mode_str = "None Supported";
          else if (memory_throttling_mode == IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_MEMORY_THROTTLING_MODE_OPEN_LOOP_THROUGHPUT_THROTTLING)
            memory_throttling_mode_str = "Open-loop throughput throttling (OLTT)";
          else if (memory_throttling_mode == IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_MEMORY_THROTTLING_MODE_CLOSE_LOOP_THERMAL_THROTTLING)
            memory_throttling_mode_str = "Close-loop thermal throttling (CLTT)";
          else
            memory_throttling_mode_str = "Unspecified";
        
          pstdout_printf (state_data->pstate,
                          "Memory Throttling Mode: %s\n",
                          memory_throttling_mode_str);
        
          _ipmi_sensors_oem_intel_quanta_qssc_s4r_output_oem_record_fan_control_profile_support (state_data, fan_control_profile_support_0, 0);
          _ipmi_sensors_oem_intel_quanta_qssc_s4r_output_oem_record_fan_control_profile_support (state_data, fan_control_profile_support_1, 1);
          _ipmi_sensors_oem_intel_quanta_qssc_s4r_output_oem_record_fan_control_profile_support (state_data, fan_control_profile_support_2, 2);
          _ipmi_sensors_oem_intel_quanta_qssc_s4r_output_oem_record_fan_control_profile_support (state_data, fan_control_profile_support_3, 3);
          _ipmi_sensors_oem_intel_quanta_qssc_s4r_output_oem_record_fan_control_profile_support (state_data, fan_control_profile_support_4, 4);
          _ipmi_sensors_oem_intel_quanta_qssc_s4r_output_oem_record_fan_control_profile_support (state_data, fan_control_profile_support_5, 5);
          _ipmi_sensors_oem_intel_quanta_qssc_s4r_output_oem_record_fan_control_profile_support (state_data, fan_control_profile_support_6, 6);
          _ipmi_sensors_oem_intel_quanta_qssc_s4r_output_oem_record_fan_control_profile_support (state_data, fan_control_profile_support_7, 7);
              
          /* Stored in .5 C units */
          pstdout_printf (state_data->pstate,
                          "Temperature at Chassis Inlet: %u C\n",
                          tempinlet/2);
          
          /* Stored in .5 C units */
          pstdout_printf (state_data->pstate,
                          "Temperature rise from Chassis Inlet to DIMM Local Ambient: %u C\n",
                          temprise/2);

          /* Stored in mm/sec units */
          pstdout_printf (state_data->pstate,
                          "Average air flow velocity in DIMM channel: %u m/sec\n", 
                          (float)airflow/1000);

          /* Stored in 1/1000 in units */
          pstdout_printf (state_data->pstate,
                          "Pitch between DIMMS: %.2f in\n", 
                          (float)dimmpitch/1000);

          if (throttle_mode == IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_THROTTLE_MODE_DISABLED)
            throttle_mode_str = "Disabled";
          else if (throttle_mode == IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_THROTTLE_MODE_VTS_ONLY)
            throttle_mode_str = "VTS Only (OLTT)";
          else if (throttle_mode == IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_THROTTLE_MODE_SOFTWARE_MODE)
            throttle_mode_str = "Software Mode";
          else 
            throttle_mode_str = "EXTTS CLTT";

          pstdout_printf (state_data->pstate,
                          "Throttle Mode: %s\n",
                          throttle_mode_str);
        
          pstdout_printf (state_data->pstate,
                          "Thermal Register Lock: %s\n",
                          thermal_register_lock ? "Enabled" : "Disabled");
        
          if (hysteresis == IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_HYSTERESIS_DISABLE)
            hysteresis_str = "disable hysteresis";
          else if (hysteresis == IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_HYSTERESIS_1_5C)
            hysteresis_str = "1.5C";
          else if (hysteresis == IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_HYSTERESIS_3C)
            hysteresis_str = "3C";
          else 
            hysteresis_str = "6C";
        
          pstdout_printf (state_data->pstate,
                          "Hysteresis: %s\n",
                          hysteresis_str);
        
          if (control_event_mode == IPMI_SDR_OEM_INTEL_QUANTA_QSSC_S4R_THERMAL_PROFILE_DATA_RECORD_CONTROL_EVENT_MODE_ASSERT_NOT_ONLY_CRITICAL)
            control_event_mode_str = "Events asserted above high or low in addition to critical";
          else 
            control_event_mode_str = "Events asserted only if above critical";
        
          pstdout_printf (state_data->pstate,
                          "Control Event Mode: %s\n",
                          control_event_mode_str);

          return (1);
        }
Ejemplo n.º 26
0
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);
}
Ejemplo n.º 27
0
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);
}
Ejemplo n.º 28
0
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);
}
Ejemplo n.º 29
0
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);
}
static int
_legacy_simple_output_full_record (ipmi_sensors_state_data_t *state_data,
                                   uint16_t record_id,
                                   double *sensor_reading,
                                   int event_message_output_type,
                                   uint16_t sensor_event_bitmask,
                                   char **event_message_list,
                                   unsigned int event_message_list_len)
{
  uint8_t event_reading_type_code;
  double *lower_non_critical_threshold = NULL;
  double *upper_non_critical_threshold = NULL;
  double *lower_critical_threshold = NULL;
  double *upper_critical_threshold = NULL;
  double *lower_non_recoverable_threshold = NULL;
  double *upper_non_recoverable_threshold = NULL;
  int rv = -1;

  assert (state_data);
  assert (IPMI_SENSORS_EVENT_VALID (event_message_output_type));

  if (_legacy_simple_output_header (state_data, record_id) < 0)
    goto cleanup;

  if (ipmi_sdr_parse_event_reading_type_code (state_data->sdr_ctx,
                                              NULL,
                                              0,
                                              &event_reading_type_code) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_sdr_parse_event_reading_type_code: %s\n",
                       ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
      goto cleanup;
    }

  switch (ipmi_event_reading_type_code_class (event_reading_type_code))
    {
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_THRESHOLD:
      if (!state_data->prog_data->args->quiet_readings)
        {
          char sensor_units_buf[IPMI_SENSORS_UNITS_BUFLEN+1];
          double *lower_output_threshold = NULL;
          double *upper_output_threshold = NULL;

          memset (sensor_units_buf, '\0', IPMI_SENSORS_UNITS_BUFLEN+1);
          if (get_sensor_units_output_string (state_data->pstate,
                                              state_data->sdr_ctx,
                                              sensor_units_buf,
                                              IPMI_SENSORS_UNITS_BUFLEN,
                                              0) < 0)
            goto cleanup;

          if (ipmi_sensors_get_thresholds (state_data,
                                           &lower_non_critical_threshold,
                                           &lower_critical_threshold,
                                           &lower_non_recoverable_threshold,
                                           &upper_non_critical_threshold,
                                           &upper_critical_threshold,
                                           &upper_non_recoverable_threshold) < 0)
            goto cleanup;

          if (sensor_reading)
            pstdout_printf (state_data->pstate,
                            "%.2f %s ",
                            _round_double2 (*sensor_reading),
                            sensor_units_buf);
          else
            pstdout_printf (state_data->pstate,
                            "%s ",
                            IPMI_SENSORS_NA_STRING_LEGACY);
          
          /* default output is critical thresholds, if those aren't
           * available, move to non-recoverable, and if those aren't
           * available, move on to non-critical.
           */
          
          if (lower_critical_threshold || upper_critical_threshold)
            {
              lower_output_threshold = lower_critical_threshold;
              upper_output_threshold = upper_critical_threshold;
            }
          else if (lower_non_recoverable_threshold || upper_non_recoverable_threshold)
            {
              lower_output_threshold = lower_non_recoverable_threshold;
              upper_output_threshold = upper_non_recoverable_threshold;
            }
          else if (lower_non_critical_threshold || upper_non_critical_threshold)
            {
              lower_output_threshold = lower_non_critical_threshold;
              upper_output_threshold = upper_non_critical_threshold;
            }
          
          if (lower_output_threshold)
            pstdout_printf (state_data->pstate,
                            "(%.2f/",
                            _round_double2 (*lower_output_threshold));
          else
            pstdout_printf (state_data->pstate, "(%s/", IPMI_SENSORS_NA_STRING_LEGACY);
          
          if (upper_output_threshold)
            pstdout_printf (state_data->pstate,
                            "%.2f): ",
                            _round_double2 (*upper_output_threshold));
          else
            pstdout_printf (state_data->pstate, "%s): ", IPMI_SENSORS_NA_STRING_LEGACY);
        }
      /* fall through and also output event messages */
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_GENERIC_DISCRETE:
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_SENSOR_SPECIFIC_DISCRETE:
    case IPMI_EVENT_READING_TYPE_CODE_CLASS_OEM:
    default:
      if (ipmi_sensors_output_event_message_list (state_data,
                                                  event_message_output_type,
                                                  sensor_event_bitmask,
                                                  event_message_list,
                                                  event_message_list_len,
                                                  NULL,
                                                  0) < 0)
        goto cleanup;
      break;
    }

  rv = 0;
 cleanup:
  free (lower_non_critical_threshold);
  free (upper_non_critical_threshold);
  free (lower_critical_threshold);
  free (upper_critical_threshold);
  free (lower_non_recoverable_threshold);
  free (upper_non_recoverable_threshold);
  return (rv);
}