int
ipmi_oem_supermicro_reset_intrusion (ipmi_oem_state_data_t *state_data)
{
  uint8_t bytes_rq[IPMI_OEM_MAX_BYTES];
  uint8_t bytes_rs[IPMI_OEM_MAX_BYTES];
  int rs_len;
  int rv = -1;

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

  /* Supermicro OEM
   *
   * 0x30 - OEM network function
   * 0x03 - OEM cmd
   */

  bytes_rq[0] = IPMI_CMD_OEM_SUPERMICRO_RESET_INTRUSION;

  if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx,
                              0, /* lun */
                              IPMI_NET_FN_OEM_SUPERMICRO_GENERIC_RQ, /* network function */
                              bytes_rq, /* data */
                              1, /* num bytes */
                              bytes_rs,
                              IPMI_OEM_MAX_BYTES)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_cmd_raw: %s\n",
                       ipmi_ctx_errormsg (state_data->ipmi_ctx));
      goto cleanup;
    }

  if (ipmi_oem_check_response_and_completion_code (state_data,
                                                   bytes_rs,
                                                   rs_len,
                                                   2,
                                                   IPMI_CMD_OEM_SUPERMICRO_RESET_INTRUSION,
                                                   IPMI_NET_FN_OEM_SUPERMICRO_GENERIC_RS,
                                                   NULL) < 0)
    goto cleanup;

  rv = 0;
 cleanup:
  return (rv);
}
int
ipmi_oem_supermicro_get_pmbus_power_supply_status (ipmi_oem_state_data_t *state_data)
{
  uint8_t bytes_rq[IPMI_OEM_MAX_BYTES];
  uint8_t bytes_rs[IPMI_OEM_MAX_BYTES];
  int rs_len;
  int rv = -1;

  assert (state_data);
  assert (state_data->prog_data->args->oem_options_count == 1);

  if (strcasecmp (state_data->prog_data->args->oem_options[0], "1")
      && strcasecmp (state_data->prog_data->args->oem_options[0], "2")
      && strcasecmp (state_data->prog_data->args->oem_options[0], "3"))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "%s:%s invalid OEM option argument '%s'\n",
                       state_data->prog_data->args->oem_id,
                       state_data->prog_data->args->oem_command,
                       state_data->prog_data->args->oem_options[0]);
      goto cleanup;
    }

  /* Supermicro OEM
   * From Supermicro Engineer 
   *
   * Request 
   *
   * 0x06 - network function
   * 0x52 - cmd (master read/write)
   * 0x07 - (channel = 0, bus id = 3, bus type = private) 
   * 0x?? - slave address
   *      - 0x78 - ps 1 
   *      - 0x7a - ps 2 
   *      - 0x7c - ps 3 
   * 0x01 - read count
   * 0x78 - data to write ... no idea why 0x78
   *
   * Response 
   *
   * 0x52 - cmd
   * 0x?? - Completion Code
   * 0x?? - 0x01 - good
   *      - 0x00 - bad
   */
  
  bytes_rq[0] = IPMI_CMD_MASTER_WRITE_READ;
  bytes_rq[1] = IPMI_OEM_SUPERMICRO_GET_PMBUS_POWER_SUPPLY_STATUS_CHANNEL;
  if (!strcasecmp (state_data->prog_data->args->oem_options[0], "1"))
    bytes_rq[2] = IPMI_OEM_SUPERMICRO_GET_PMBUS_POWER_SUPPLY_STATUS_PS1;
  else if (!strcasecmp (state_data->prog_data->args->oem_options[0], "2"))
    bytes_rq[2] = IPMI_OEM_SUPERMICRO_GET_PMBUS_POWER_SUPPLY_STATUS_PS2;
  else /* !strcasecmp (state_data->prog_data->args->oem_options[0], "3") */
    bytes_rq[2] = IPMI_OEM_SUPERMICRO_GET_PMBUS_POWER_SUPPLY_STATUS_PS3;
  bytes_rq[3] = 1;
  bytes_rq[4] = IPMI_OEM_SUPERMICRO_GET_PMBUS_POWER_SUPPLY_STATUS_MAGIC;

  if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx,
                              0, /* lun */
                              IPMI_NET_FN_APP_RQ,
                              bytes_rq, /* data */
                              5, /* num bytes */
                              bytes_rs,
                              IPMI_OEM_MAX_BYTES)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_cmd_raw: %s\n",
                       ipmi_ctx_errormsg (state_data->ipmi_ctx));
      goto cleanup;
    }

  if (ipmi_oem_check_response_and_completion_code (state_data,
                                                   bytes_rs,
                                                   rs_len,
                                                   3,
                                                   IPMI_CMD_MASTER_WRITE_READ,
                                                   IPMI_NET_FN_APP_RQ,
                                                   NULL) < 0)
    goto cleanup;
  
  if (bytes_rs[2] == IPMI_OEM_SUPERMICRO_GET_PMBUS_POWER_SUPPLY_STATUS_GOOD)
    pstdout_printf (state_data->pstate, "good\n");
  else if (bytes_rs[2] == IPMI_OEM_SUPERMICRO_GET_PMBUS_POWER_SUPPLY_STATUS_BAD)
    pstdout_printf (state_data->pstate, "bad\n");
  else
    pstdout_printf (state_data->pstate, "unknown\n");

  rv = 0;
 cleanup:
  return (rv);
}
int
ipmi_oem_supermicro_extra_firmware_info (ipmi_oem_state_data_t *state_data)
{
  uint8_t bytes_rq[IPMI_OEM_MAX_BYTES];
  uint8_t bytes_rs[IPMI_OEM_MAX_BYTES];
  uint32_t firmware_major_version;
  uint32_t firmware_minor_version;
  uint32_t firmware_sub_version;
  uint32_t firmware_build_number;
  uint8_t firmware_hardware_id;
  char firmware_tag[IPMI_OEM_SUPERMICRO_STRING_MAX+1];
  int rs_len;
  int rv = -1;

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

  memset (firmware_tag, '\0', IPMI_OEM_SUPERMICRO_STRING_MAX + 1);

  /* Supermicro OEM
   *
   * From post by ipmitool developer.
   *
   * http://sourceforge.net/mailarchive/message.php?msg_name=49ABCCC3.4040004%40cern.ch
   *
   * Request
   *
   * 0x3C - OEM network function
   * 0x20 - OEM cmd
   *
   * Response
   * 0x20 - OEM cmd
   * 0x?? - Completion Code
   * 4 bytes - firmware major version (LSB first)
   * 4 bytes - firmware minor version (LSB first)
   * 4 bytes - firmware sub version (LSB first)
   * 4 bytes - firmware build number (LSB first)
   * 1 byte - hardware ID
   * ? bytes - firmware tag, null terminated string
   */

  bytes_rq[0] = IPMI_CMD_OEM_SUPERMICRO_EXTRA_FIRMWARE_INFO;

  if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx,
                              0, /* lun */
                              IPMI_NET_FN_OEM_SUPERMICRO_PEPPERCON_RQ, /* network function */
                              bytes_rq, /* data */
                              1, /* num bytes */
                              bytes_rs,
                              IPMI_OEM_MAX_BYTES)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_cmd_raw: %s\n",
                       ipmi_ctx_errormsg (state_data->ipmi_ctx));
      goto cleanup;
    }

  if (ipmi_oem_check_response_and_completion_code (state_data,
                                                   bytes_rs,
                                                   rs_len,
                                                   19,
                                                   IPMI_CMD_OEM_SUPERMICRO_EXTRA_FIRMWARE_INFO,
                                                   IPMI_NET_FN_OEM_SUPERMICRO_PEPPERCON_RS,
                                                   NULL) < 0)
    goto cleanup;

  firmware_major_version = bytes_rs[2];
  firmware_major_version |= (bytes_rs[3] << 8);
  firmware_major_version |= (bytes_rs[4] << 16);
  firmware_major_version |= (bytes_rs[5] << 24);

  firmware_minor_version = bytes_rs[6];
  firmware_minor_version |= (bytes_rs[7] << 8);
  firmware_minor_version |= (bytes_rs[8] << 16);
  firmware_minor_version |= (bytes_rs[9] << 24);

  firmware_sub_version = bytes_rs[10];
  firmware_sub_version |= (bytes_rs[11] << 8);
  firmware_sub_version |= (bytes_rs[12] << 16);
  firmware_sub_version |= (bytes_rs[13] << 24);

  firmware_build_number = bytes_rs[14];
  firmware_build_number |= (bytes_rs[15] << 8);
  firmware_build_number |= (bytes_rs[16] << 16);
  firmware_build_number |= (bytes_rs[17] << 24);

  firmware_hardware_id = bytes_rs[18];
  
  if (rs_len > 19)
    memcpy (firmware_tag, &bytes_rs[19], rs_len - 19);

  /* assume minor version is BCD, just like in Get Device ID command */
  /* assume sub version is also BCD */ 
  pstdout_printf (state_data->pstate,
                  "Firmware Version      : %u.%02x.%02x\n",
                  firmware_major_version,
                  firmware_minor_version,
                  firmware_sub_version);

  pstdout_printf (state_data->pstate,
                  "Firmware Build Number : %u\n",
                  firmware_build_number);

  pstdout_printf (state_data->pstate,
                  "Firmware Hardware ID  : %u\n",
                  firmware_hardware_id);

  pstdout_printf (state_data->pstate,
                  "Firmware Tag          : %s\n",
                  firmware_tag);

  rv = 0;
 cleanup:
  return (rv);
}
int
ipmi_oem_supermicro_set_bmc_services_status (ipmi_oem_state_data_t *state_data)
{
  uint8_t bytes_rq[IPMI_OEM_MAX_BYTES];
  uint8_t bytes_rs[IPMI_OEM_MAX_BYTES];
  int rs_len;
  int rv = -1;

  assert (state_data);
  assert (state_data->prog_data->args->oem_options_count == 1);

  if (strcasecmp (state_data->prog_data->args->oem_options[0], "enable")
      && strcasecmp (state_data->prog_data->args->oem_options[0], "disable"))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "%s:%s invalid OEM option argument '%s'\n",
                       state_data->prog_data->args->oem_id,
                       state_data->prog_data->args->oem_command,
                       state_data->prog_data->args->oem_options[0]);
      goto cleanup;
    }

  /* Supermicro OEM
   *
   * Request 
   *
   * 0x30 - OEM network function
   * 0x70 - OEM cmd
   * 0xF0 - Sub-command
   * 0x?? - action
   *      - 0x00 - disable
   *      - 0x01 - enable
   *      - 0x02 - status
   *
   * Response 
   *
   * 0x70 - OEM cmd
   * 0x?? - Completion Code
   * 0x?? - if action == status
   *      - 0x00 - disabled
   *      - 0x01 - enabled
   */

  bytes_rq[0] = IPMI_CMD_OEM_SUPERMICRO_GENERIC_EXTENSION;
  bytes_rq[1] = IPMI_OEM_SUPERMICRO_SUB_COMMAND_BMC_SERVICES;

  if (!strcasecmp (state_data->prog_data->args->oem_options[0], "enable"))
    bytes_rq[2] = IPMI_OEM_SUPERMICRO_BMC_SERVICES_ACTION_ENABLE;
  else /* !strcasecmp (state_data->prog_data->args->oem_options[0], "disable") */
    bytes_rq[2] = IPMI_OEM_SUPERMICRO_BMC_SERVICES_ACTION_DISABLE;

  if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx,
                              0, /* lun */
                              IPMI_NET_FN_OEM_SUPERMICRO_GENERIC_RQ, /* network function */
                              bytes_rq, /* data */
                              3, /* num bytes */
                              bytes_rs,
                              IPMI_OEM_MAX_BYTES)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_cmd_raw: %s\n",
                       ipmi_ctx_errormsg (state_data->ipmi_ctx));
      goto cleanup;
    }

  if (ipmi_oem_check_response_and_completion_code (state_data,
                                                   bytes_rs,
                                                   rs_len,
                                                   2,
                                                   IPMI_CMD_OEM_SUPERMICRO_GENERIC_EXTENSION,
                                                   IPMI_NET_FN_OEM_SUPERMICRO_GENERIC_RS,
                                                   NULL) < 0)
    goto cleanup;
  
  rv = 0;
 cleanup:
  return (rv);
}
int
ipmi_oem_supermicro_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);
}
Example #6
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);
}
Example #7
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);
}
Example #8
0
int
ipmi_oem_fujitsu_set_identify_led (ipmi_oem_state_data_t *state_data)
{
  uint8_t bytes_rq[IPMI_OEM_MAX_BYTES];
  uint8_t bytes_rs[IPMI_OEM_MAX_BYTES];
  int rs_len;
  int rv = -1;

  assert (state_data);
  assert (state_data->prog_data->args->oem_options_count == 1);

  if (strcasecmp (state_data->prog_data->args->oem_options[0], "on")
      && strcasecmp (state_data->prog_data->args->oem_options[0], "off"))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "%s:%s invalid OEM option argument '%s'\n",
                       state_data->prog_data->args->oem_id,
                       state_data->prog_data->args->oem_command,
                       state_data->prog_data->args->oem_options[0]);
      goto cleanup;
    }

  /* Fujitsu OEM
   * 
   * http://manuals.ts.fujitsu.com/file/4390/irmc_s2-en.pdf
   *
   * Request
   *
   * 0x2E - OEM network function
   * 0xF5 - OEM cmd
   * 0x?? - Fujitsu IANA (LSB first)
   * 0x?? - Fujitsu IANA
   * 0x?? - Fujitsu IANA
   * 0xB0 - Command Specifier
   * 0x?? - led on/off (0 == off, 1 == on)
   *
   * Response
   *
   * 0xF5 - OEM cmd
   * 0x?? - Completion code
   * 0x?? - Fujitsu IANA (LSB first)
   * 0x?? - Fujitsu IANA
   * 0x?? - Fujitsu IANA
   */
  
  bytes_rq[0] = IPMI_CMD_OEM_FUJITSU_SYSTEM;
  bytes_rq[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF);
  bytes_rq[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8;
  bytes_rq[3] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16;
  bytes_rq[4] = IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_SET_IDENTIFY_LED;

  if (!strcasecmp (state_data->prog_data->args->oem_options[0], "on"))
    bytes_rq[5] = IPMI_OEM_FUJITSU_IDENTIFY_LED_ON;
  else
    bytes_rq[5] = IPMI_OEM_FUJITSU_IDENTIFY_LED_OFF;

  if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx,
                              0, /* lun */
                              IPMI_NET_FN_OEM_GROUP_RQ, /* network function */
                              bytes_rq, /* data */
                              6, /* num bytes */
                              bytes_rs,
                              IPMI_OEM_MAX_BYTES)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_cmd_raw: %s\n",
                       ipmi_ctx_errormsg (state_data->ipmi_ctx));
      goto cleanup;
    }
  
  if (ipmi_oem_check_response_and_completion_code (state_data,
                                                   bytes_rs,
                                                   rs_len,
                                                   5,
                                                   IPMI_CMD_OEM_FUJITSU_SYSTEM,
                                                   IPMI_NET_FN_OEM_GROUP_RS,
                                                   NULL) < 0)
    goto cleanup;

  rv = 0;
 cleanup:
  return (rv);
}
Example #9
0
int
ipmi_oem_sun_set_led (ipmi_oem_state_data_t *state_data)
{
  uint8_t bytes_rq[IPMI_OEM_MAX_BYTES];
  uint8_t bytes_rs[IPMI_OEM_MAX_BYTES];
  int rs_len;
  uint16_t record_id;
  uint8_t led_mode;
  long value;
  char *ptr;
  uint8_t sdr_record[IPMI_SDR_MAX_RECORD_LENGTH];
  int sdr_record_len = 0;
  uint8_t record_type;
  uint8_t entity_instance_type;
  int rv = -1;

  assert (state_data);
  assert (state_data->prog_data->args->oem_options_count == 2);

  errno = 0;
  value = strtol (state_data->prog_data->args->oem_options[0], &ptr, 10);
  if (errno
      || ptr[0] != '\0'
      || value < 0
      || value < IPMI_SDR_RECORD_ID_FIRST
      || value > IPMI_SDR_RECORD_ID_LAST)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "%s:%s invalid record_id\n",
                       state_data->prog_data->args->oem_id,
                       state_data->prog_data->args->oem_command);
      goto cleanup;
    }

  record_id = value;

  if (strcasecmp (state_data->prog_data->args->oem_options[1], "off")
      && strcasecmp (state_data->prog_data->args->oem_options[1], "on")
      && strcasecmp (state_data->prog_data->args->oem_options[1], "standby")
      && strcasecmp (state_data->prog_data->args->oem_options[1], "slow")
      && strcasecmp (state_data->prog_data->args->oem_options[1], "fast"))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "%s:%s invalid OEM option argument '%s'\n",
                       state_data->prog_data->args->oem_id,
                       state_data->prog_data->args->oem_command,
                       state_data->prog_data->args->oem_options[1]);
      goto cleanup;
    }

  if (!strcasecmp (state_data->prog_data->args->oem_options[1], "off"))
    led_mode = IPMI_OEM_SUN_LED_MODE_OFF;
  else if (!strcasecmp (state_data->prog_data->args->oem_options[1], "on"))
    led_mode = IPMI_OEM_SUN_LED_MODE_ON;
  else if (!strcasecmp (state_data->prog_data->args->oem_options[1], "standby"))
    led_mode = IPMI_OEM_SUN_LED_MODE_STANDBY;
  else if (!strcasecmp (state_data->prog_data->args->oem_options[1], "slow"))
    led_mode = IPMI_OEM_SUN_LED_MODE_SLOW;
  else /* !strcasecmp (state_data->prog_data->args->oem_options[1], "fast") */
    led_mode = IPMI_OEM_SUN_LED_MODE_FAST;

  if (sdr_cache_create_and_load (state_data->sdr_ctx,
                                 state_data->pstate,
                                 state_data->ipmi_ctx,
                                 state_data->hostname,
 				 &state_data->prog_data->args->common_args) < 0)
    goto cleanup;

  /* Sun OEM
   *
   * From Ipmitool (http://ipmitool.sourceforge.net/)
   *
   * Set Led Request
   *
   * 0x2E - OEM network function (is IPMI_NET_FN_OEM_GROUP_RQ)
   * 0x22 - OEM cmd
   * 0x?? - Device Slave Address (in General Device Locator Record)
   *      - Note that the IPMI command requires the entire
   *        byte of the slave address.
   * 0x?? - LED Type (see below [1])
   *      - 0 - ok2rm
   *      - 1 - service
   *      - 2 - activity
   *      - 3 - locate 
   * 0x?? - Controller Address / Device Access Address (in General Device Locator Record)
   *      - 0x20 if the LED is local
   *      - Note that the IPMI command requires the entire
   *        byte of the access address.
   * 0x?? - HW Info (OEM field in General Device Locator Record)
   * 0x?? - LED Mode
   * 0x?? - Force
   *      - 0 - Go thru controller
   *      - 1 - Directly access device
   * 0x?? - Role
   *      - Ipmitool comments state "Used by BMC for authorization purposes"
   *      - achu: I have no idea what this is for, set to 0 like in code
   *
   * An alternate format is described in the ipmitool comments for Sun
   * Blade Moduler Systems.
   *
   * 0x2E - OEM network function (is IPMI_NET_FN_OEM_GROUP_RQ)
   * 0x22 - OEM cmd
   * 0x?? - Device Slave Address (in General Device Locator Record)
   * 0x?? - LED Type
   * 0x?? - Controller Address / Device Access Address (in General Device Locator Record)
   * 0x?? - HW Info (OEM field in General Device Locator Record)
   * 0x?? - LED Mode
   * 0x?? - Entity ID
   * 0x?? - Entity Instance
   *      - 7 bit version
   * 0x?? - Force
   *      - 0 - Go thru controller
   *      - 1 - Directly access device
   * 0x?? - Role
   *      - Ipmitool comments state "Used by BMC for authorization purposes"
   *      - achu: I have no idea what this is for, set to 0 like in code
   *
   * Set Led Response
   *
   * 0x22 - OEM cmd
   * 0x?? - Completion Code
   *
   * achu notes: 
   *
   * [1] - As far as I can tell, the LED type field is useless.  My
   * assumption is that on older Sun systems, or other motherboards I
   * don't have access to, one can specify an LED type, which allows
   * you to enable/disable a particular LED amongst many.  On my Sun
   * Fire 4140, it appears to do nothing and affect nothing.  I will
   * add in a new option later if it becomes necessary for the user to
   * specify an LED type.  In the meantime, I will copy the code use
   * in ipmitool and set this field to the OEM field.
   */
  
  if (ipmi_sdr_cache_search_record_id (state_data->sdr_ctx, record_id) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_sdr_cache_search_record_id: %s\n",
                       ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
      goto cleanup;
    }
  
  if ((sdr_record_len = ipmi_sdr_cache_record_read (state_data->sdr_ctx,
                                                    sdr_record,
                                                    IPMI_SDR_MAX_RECORD_LENGTH)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_sdr_cache_record_read: %s\n",
                       ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
      goto cleanup;
    }
  
  if (ipmi_sdr_parse_record_id_and_type (state_data->sdr_ctx,
                                         sdr_record,
                                         sdr_record_len,
                                         NULL,
                                         &record_type) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_sdr_parse_record_id_and_type: %s\n",
                       ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
      goto cleanup;
    }
  
  if (record_type != IPMI_SDR_FORMAT_GENERIC_DEVICE_LOCATOR_RECORD)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "Record ID points to invalid record type: %Xh\n",
                       record_type);
      goto cleanup;
    }
  
  if (ipmi_sdr_parse_entity_id_instance_type (state_data->sdr_ctx,
                                              sdr_record,
                                              sdr_record_len,
                                              NULL,
                                              NULL,
                                              &entity_instance_type) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_sdr_parse_entity_id_and_instance: %s\n",
                       ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
      goto cleanup;
    }

  if (entity_instance_type != IPMI_SDR_PHYSICAL_ENTITY)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "Record ID points to non physical entity\n");
      goto cleanup;
    }
  
  /* achu: the sun oem commands want the full byte, not just the
   * sub-field, so use indexes instead of sdr-parse lib.
   */
  
  bytes_rq[0] = IPMI_CMD_OEM_SUN_SET_LED;
  bytes_rq[1] = sdr_record[IPMI_SDR_RECORD_GENERIC_DEVICE_LOCATOR_DEVICE_SLAVE_ADDRESS_INDEX];
  bytes_rq[2] = sdr_record[IPMI_SDR_RECORD_GENERIC_DEVICE_LOCATOR_OEM_INDEX];
  bytes_rq[3] = sdr_record[IPMI_SDR_RECORD_GENERIC_DEVICE_LOCATOR_DEVICE_ACCESS_ADDRESS_INDEX];
  bytes_rq[4] = sdr_record[IPMI_SDR_RECORD_GENERIC_DEVICE_LOCATOR_OEM_INDEX];
  bytes_rq[5] = led_mode;
  bytes_rq[6] = IPMI_OEM_SUN_LED_FORCE_GO_THRU_CONTROLLER;
  bytes_rq[7] = 0;              /* see comments above, just set to 0 */
  
  if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx,
                              0, /* lun */
                              IPMI_NET_FN_OEM_GROUP_RQ, /* network function */
                              bytes_rq, /* data */
                              8, /* num bytes */
                              bytes_rs,
                              IPMI_OEM_MAX_BYTES)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_cmd_raw: %s\n",
                       ipmi_ctx_errormsg (state_data->ipmi_ctx));
      goto cleanup;
    }
      
  if (ipmi_oem_check_response_and_completion_code (state_data,
                                                   bytes_rs,
                                                   rs_len,
                                                   2,
                                                   IPMI_CMD_OEM_SUN_SET_LED,
                                                   IPMI_NET_FN_OEM_GROUP_RS,
                                                   NULL) < 0)
    goto cleanup;
 
  rv = 0;
 cleanup: 
  return (rv);
}
Example #10
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);
}
Example #11
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);
}
Example #12
0
static int
_ipmi_oem_get_power_source (ipmi_oem_state_data_t *state_data,
                            uint8_t command_specifier,
                            uint8_t *source)
{
  uint8_t bytes_rq[IPMI_OEM_MAX_BYTES];
  uint8_t bytes_rs[IPMI_OEM_MAX_BYTES];
  int rs_len;
  int rv = -1;

  assert (state_data);
  assert (command_specifier == IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_POWER_ON_SOURCE
          || command_specifier == IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_POWER_OFF_SOURCE);
  assert (source);

  /* Fujitsu OEM
   * 
   * http://manuals.ts.fujitsu.com/file/4390/irmc_s2-en.pdf
   *
   * Request
   *
   * 0x2E - OEM network function
   * 0x01 - OEM cmd
   * 0x?? - Fujitsu IANA (LSB first)
   * 0x?? - Fujitsu IANA
   * 0x?? - Fujitsu IANA
   * 0x?? - Command Specifier
   *
   * Response
   *
   * 0x01 - OEM cmd
   * 0x?? - Completion code
   * 0x?? - Fujitsu IANA (LSB first)
   * 0x?? - Fujitsu IANA
   * 0x?? - Fujitsu IANA
   * 0x01 - data length
   * 0x?? - power on/off source
   */
  
  bytes_rq[0] = IPMI_CMD_OEM_FUJITSU_POWER;
  bytes_rq[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF);
  bytes_rq[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8;
  bytes_rq[3] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16;
  bytes_rq[4] = command_specifier;

  if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx,
                              0, /* lun */
                              IPMI_NET_FN_OEM_GROUP_RQ, /* network function */
                              bytes_rq, /* data */
                              5, /* num bytes */
                              bytes_rs,
                              IPMI_OEM_MAX_BYTES)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_cmd_raw: %s\n",
                       ipmi_ctx_errormsg (state_data->ipmi_ctx));
      goto cleanup;
    }
  
  if (ipmi_oem_check_response_and_completion_code (state_data,
                                                   bytes_rs,
                                                   rs_len,
                                                   7,
                                                   IPMI_CMD_OEM_FUJITSU_POWER,
                                                   IPMI_NET_FN_OEM_GROUP_RS,
                                                   NULL) < 0)
    goto cleanup;

  (*source) = bytes_rs[6];

  rv = 0;
 cleanup:
  return (rv);
}
Example #13
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);
}
Example #14
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);
}
Example #15
0
int
ipmi_oem_fujitsu_get_sel_entry_long_text (ipmi_oem_state_data_t *state_data)
{
  uint8_t bytes_rq[IPMI_OEM_MAX_BYTES];
  uint8_t bytes_rs[IPMI_OEM_MAX_BYTES];
  int rs_len;
  long value;
  uint16_t sel_record_id;
  uint16_t actual_record_id = 0;
  uint32_t timestamp = 0;
  uint8_t css = 0;
  uint8_t severity = 0;
  char time_buf[IPMI_OEM_TIME_BUFLEN + 1];
  char data_buf[IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_MAX_DATA_LENGTH + 1];
  uint8_t data_length;
  uint8_t offset = 0;
  uint8_t component_length = 0;
  char *css_str = NULL;
  char *severity_str = NULL;
  char *endptr = NULL;
  int rv = -1;
  uint8_t max_read_length;
  struct ipmi_oem_data oem_data;

  assert (state_data);
  assert (state_data->prog_data->args->oem_options_count == 1);
  
  errno = 0;
  
  value = strtol (state_data->prog_data->args->oem_options[0], &endptr, 0);
  if (errno
      || endptr[0] != '\0'
      || value < IPMI_SEL_GET_RECORD_ID_FIRST_ENTRY
      || value > IPMI_SEL_GET_RECORD_ID_LAST_ENTRY)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "%s:%s invalid OEM option argument '%s'\n",
                       state_data->prog_data->args->oem_id,
                       state_data->prog_data->args->oem_command,
                       state_data->prog_data->args->oem_options[0]);
      goto cleanup;
    }

  sel_record_id = value;

  memset (data_buf, '\0', IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_MAX_DATA_LENGTH + 1);

  /* HLiebig: Note: Documentation is for iRMC S2 version */
  if ((ipmi_get_oem_data (state_data->pstate,
                          state_data->ipmi_ctx,
                          &oem_data) <= 0)
      || (IPMI_FUJITSU_PRODUCT_ID_IS_IRMC_S1 (oem_data.product_id)))
    {
      max_read_length = IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_IRMC_S1_MAX_READ_LENGTH;
      data_length = IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_IRMC_S1_MAX_DATA_LENGTH;
    }
  else 
    {
      max_read_length = IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_IRMC_S2_MAX_READ_LENGTH;
      data_length = IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_IRMC_S2_MAX_DATA_LENGTH;
    }

  /* Fujitsu OEM
   * 
   * http://manuals.ts.fujitsu.com/file/4390/irmc_s2-ug-en.pdf
   *
   * Request
   *
   * 0x2E - OEM network function
   * 0xF5 - OEM cmd
   * 0x?? - Fujitsu IANA (LSB first)
   * 0x?? - Fujitsu IANA
   * 0x?? - Fujitsu IANA
   * 0x43 - Command Specifier
   * 0x?? - Record ID (LSB first)
   * 0x?? - Record ID ; 0x0000 = "first record", 0xFFFF = "last record"
   * 0x?? - Offset (in response SEL text)
   * 0x?? - MaxResponseDataSize (size of converted SEL data 16:n in response, maximum is 100)
   *
   * Response
   *
   * 0xF5 - OEM cmd
   * 0x?? - Completion code
   * 0x?? - Fujitsu IANA (LSB first)
   * 0x?? - Fujitsu IANA
   * 0x?? - Fujitsu IANA
   * 0x?? - Next Record ID (LSB)
   * 0x?? - Next Record ID (MSB)
   * 0x?? - Actual Record ID (LSB)
   * 0x?? - Actual Record ID (MSB)
   * 0x?? - Record type
   * 0x?? - timestamp (LSB first)
   * 0x?? - timestamp
   * 0x?? - timestamp
   * 0x?? - timestamp
   * 0x?? - severity   
   *      bit 7   - CSS component
   *              - 0 - No CSS component
   *              - 1 - CSS component
   *      bit 6-4 - 000 = INFORMATIONAL
   *                001 = MINOR
   *                010 = MAJOR
   *                011 = CRITICAL
   *                1xx = unknown
   *      bit 3-0 - reserved
   * 0x?? - data length (of the whole text)
   * 0x?? - converted SEL data
   *      - requested number of bytes starting at requested offset (MaxResponseDataSize-1 bytes of data)
   * 0x00 - trailing '\0' character
   */
     
  bytes_rq[0] = IPMI_CMD_OEM_FUJITSU_SYSTEM;
  bytes_rq[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF);
  bytes_rq[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8;
  bytes_rq[3] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16;
  bytes_rq[4] = IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_SEL_ENTRY_LONG_TEXT;
  bytes_rq[5] = (sel_record_id & 0x00FF);
  bytes_rq[6] = (sel_record_id & 0xFF00) >> 8;

  /*
   * From Holger Liebig <holger.liebig at ts.fujitsu.com>
   *
   * "Unfortunately due to memory constrains in the previous BMC
   * generation the maximum length of a single response is limited to
   * 64bytes, while on the current product line you should be able to
   * get the full 100bytes translated SEL text with a single request
   * at least over LAN. Maximum (non standard) KCS transfer size is
   * also different between current (255) and previous (64)
   * generation, so the code should compare the data received with the
   * total length reported in the response."
   */

  /* Request partial or complete string, depending on product */
  bytes_rq[8] = max_read_length;

  while (offset < data_length)
    {
      bytes_rq[7] = offset;

      /* BMC checks for boundaries, offset + len has to be <= 80 (iRMC S1) <= 100 (iRMC S2) */ 
      if (offset + bytes_rq[8] > data_length)
         bytes_rq[8] = data_length - offset;
      
      if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx,
                                  0, /* lun */
                                  IPMI_NET_FN_OEM_GROUP_RQ, /* network function */
                                  bytes_rq, /* data */
                                  9, /* num bytes */
                                  bytes_rs,
                                  IPMI_OEM_MAX_BYTES)) < 0)
        {
          pstdout_fprintf (state_data->pstate,
                           stderr,
                           "ipmi_cmd_raw: %s\n",
                           ipmi_ctx_errormsg (state_data->ipmi_ctx));
          goto cleanup;
        }
      
      if (ipmi_oem_check_response_and_completion_code (state_data,
                                                       bytes_rs,
                                                       rs_len,
                                                       17,
                                                       IPMI_CMD_OEM_FUJITSU_SYSTEM,
                                                       IPMI_NET_FN_OEM_GROUP_RS,
                                                       NULL) < 0)
        goto cleanup;
  
      /* achu: assume a lot of this will be the same not matter how many times we loop */
      if (!offset)
        {
          actual_record_id = bytes_rs[7];
          actual_record_id |= (bytes_rs[8] << 8);

          /* use actual_record_id for subsequent requests to obtain consistent results */
          bytes_rq[5] = bytes_rs[7];
          bytes_rq[6] = bytes_rs[8];

          timestamp = bytes_rs[10];
          timestamp |= (bytes_rs[11] << 8);
          timestamp |= (bytes_rs[12] << 16);
          timestamp |= (bytes_rs[13] << 24);
          
          css = (bytes_rs[14] & IPMI_OEM_FUJITSU_CSS_BITMASK);
          css >>= IPMI_OEM_FUJITSU_CSS_SHIFT;
          
          severity = (bytes_rs[14] & IPMI_OEM_FUJITSU_SEVERITY_BITMASK);
          severity >>= IPMI_OEM_FUJITSU_SEVERITY_SHIFT;
        }
      
      data_length = bytes_rs[15];
      
      /* Every response should be NUL terminated, not just the last
       * component.
       */

      bytes_rs[rs_len - 1] = '\0'; /* just to be sure it's terminated */

      component_length = strlen ((char *)bytes_rs + 16);
  
      /* achu: truncate if there is overflow */
      if (offset + component_length > data_length)
        {
          memcpy (data_buf + offset,
                  &bytes_rs[16],
                  IPMI_OEM_FUJITSU_SEL_ENTRY_LONG_TEXT_MAX_DATA_LENGTH - offset);
          offset = data_length;
        }
      else
        {
          memcpy (data_buf + offset,
                  &bytes_rs[16],
                  component_length);
          offset += component_length;
        }
    }
Example #16
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);
}