libipmi.h revision 2c32020f848d8e5619a1f441a92f0ee4aca1b297
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBIPMI_H
#define _LIBIPMI_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/bmc_intf.h>
#include <sys/byteorder.h>
#include <sys/sysmacros.h>
/*
* Private interfaces for communicating with attached services over IPMI. This
* library is designed for system software communicating with Sun-supported
* service processors over /dev/bmc. It is not a generic IPMI library.
*
* Documentation references refer to "Intelligent Platform Management Interface
* Specification Second Generation v2.0", document revision 1.0 with Februrary
* 15, 2006 Markup from "IPMI v2.0 Addenda, Errata, and Clarifications Revision
* 3".
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ipmi_handle ipmi_handle_t;
#pragma pack(1)
/*
* Basic netfn definitions. See section 5.1.
*/
#define IPMI_NETFN_APP BMC_NETFN_APP
#define IPMI_NETFN_STORAGE BMC_NETFN_STORAGE
#define IPMI_NETFN_SE BMC_NETFN_SE
#define IPMI_NETFN_OEM 0x2e
/*
* Error definitions
*/
#define EIPMI_BASE 2000
enum {
EIPMI_NOMEM = EIPMI_BASE, /* memory allocation failure */
EIPMI_BMC_OPEN_FAILED, /* failed to open /dev/bmc */
EIPMI_BMC_PUTMSG, /* putmsg() failed */
EIPMI_BMC_GETMSG, /* getmsg() failed */
EIPMI_BMC_RESPONSE, /* response from /dev/bmc failed */
EIPMI_INVALID_COMMAND, /* invalid command */
EIPMI_COMMAND_TIMEOUT, /* command timeout */
EIPMI_DATA_LENGTH_EXCEEDED, /* maximum data length exceeded */
EIPMI_SEND_FAILED, /* failed to send BMC request */
EIPMI_UNSPECIFIED, /* unspecified error */
EIPMI_UNKNOWN, /* unknown error */
EIPMI_BAD_RESPONSE, /* received unexpected response */
EIPMI_BAD_RESPONSE_LENGTH, /* unexpected response length */
EIPMI_INVALID_RESERVATION, /* invalid reservation */
EIPMI_NOT_PRESENT, /* requested entity not present */
EIPMI_INVALID_REQUEST, /* malformed request */
EIPMI_BUSY, /* SP is busy */
EIPMI_NOSPACE, /* SP is out of space */
EIPMI_UNAVAILABLE, /* SP is present but unavailable */
EIPMI_ACCESS /* insufficient privileges */
};
/*
* Basic library functions.
*
* The ipmi_handle is the primary interface to the library. The library itself
* is not MT-safe, but it is safe within a single handle. Multithreaded clients
* should either open multiple handles, or otherwise synchronize access to the
* same handle.
*
* There is a single command response buffer that is stored with the handle, to
* simplify memory management in the caller. The memory referenced by a command
* response is only valid until the next command is issued. The caller is
* responsible for making a copy of the response if it is needed.
*/
extern ipmi_handle_t *ipmi_open(int *, char **);
extern void ipmi_close(ipmi_handle_t *);
extern int ipmi_errno(ipmi_handle_t *);
extern const char *ipmi_errmsg(ipmi_handle_t *);
/*
* Raw requests. See section 5.
*/
typedef struct ipmi_cmd {
uint8_t ic_netfn:6;
uint8_t ic_lun:2;
uint8_t ic_cmd;
uint16_t ic_dlen;
void *ic_data;
} ipmi_cmd_t;
extern ipmi_cmd_t *ipmi_send(ipmi_handle_t *, ipmi_cmd_t *);
/*
* Retrieve basic information about the IPMI device. See section 20.1 "Get
* Device ID Command".
*/
#define IPMI_CMD_GET_DEVICEID 0x01
typedef struct ipmi_deviceid {
uint8_t id_devid;
DECL_BITFIELD3(
id_dev_rev :4,
__reserved :3,
id_dev_sdrs :1);
DECL_BITFIELD2(
id_firm_major :7,
id_dev_available :1);
uint8_t id_firm_minor;
uint8_t id_ipmi_rev;
uint8_t id_dev_support;
uint8_t id_manufacturer[3];
uint16_t id_product;
} ipmi_deviceid_t;
#define IPMI_OEM_SUN 0x2a
ipmi_deviceid_t *ipmi_get_deviceid(ipmi_handle_t *);
#define ipmi_devid_manufacturer(dp) \
((dp)->id_manufacturer[0] | \
((dp)->id_manufacturer[1] << 8) | \
((dp)->id_manufacturer[2] << 16))
/*
* SDR (Sensor Device Record) requests. A cache of the current SDR repository
* is kept as part of the IPMI handle and updated when necessary. Routines to
* access the raw SDR repository are also provided.
*/
/*
* Reserve repository command. See section 33.11.
*/
#define IPMI_CMD_RESERVE_SDR_REPOSITORY 0x22
/*
* Get SDR command. See section 33.12. This command accesses the raw SDR
* repository. Clients can also use the lookup functions to retrieve a
* particular SDR record by name.
*
* The list of possible types is indicated in the sub-chapters of section 43.
*/
typedef struct ipmi_sdr {
uint16_t is_id;
uint8_t is_version;
uint8_t is_type;
uint8_t is_length;
uint8_t is_record[1];
} ipmi_sdr_t;
#define IPMI_CMD_GET_SDR 0x23
#define IPMI_SDR_FIRST 0x0000
#define IPMI_SDR_LAST 0xFFFF
extern ipmi_sdr_t *ipmi_sdr_get(ipmi_handle_t *, uint16_t, uint16_t *);
/*
* Generic Device Locator Record. See section 43.7.
*/
#define IPMI_SDR_TYPE_GENERIC_LOCATOR 0x10
typedef struct ipmi_sdr_generic_locator {
/* RECORD KEY BYTES */
DECL_BITFIELD2(
__reserved1 :1,
is_gl_accessaddr :7);
DECL_BITFIELD2(
is_gl_channel_msb :1,
is_gl_slaveaddr :7);
DECL_BITFIELD3(
is_gl_bus :3,
is_gl_lun :2,
is_gl_channel :3);
/* RECORD BODY BYTES */
DECL_BITFIELD2(
is_gl_span :3,
__reserved2 :5);
uint8_t __reserved3;
uint8_t is_gl_type;
uint8_t is_gl_modifier;
uint8_t is_gl_entity;
uint8_t is_gl_instance;
uint8_t is_gl_oem;
DECL_BITFIELD2(
is_gl_idlen :6,
is_gl_idtype :2);
char is_gl_idstring[1];
} ipmi_sdr_generic_locator_t;
/*
* FRU Device Locator Record. See section 43.8.
*/
#define IPMI_SDR_TYPE_FRU_LOCATOR 0x11
typedef struct ipmi_sdr_fru_locator {
/* RECORD KEY BYTES */
DECL_BITFIELD2(
__reserved1 :1,
is_fl_accessaddr :7);
union {
struct {
uint8_t _is_fl_devid;
} _logical;
struct {
DECL_BITFIELD2(
__reserved :1,
_is_fl_slaveaddr :7);
} _nonintelligent;
} _devid_or_slaveaddr;
DECL_BITFIELD4(
is_fl_bus :3,
is_fl_lun :2,
__reserved2 :2,
is_fl_logical :1);
DECL_BITFIELD2(
__reserved3 :4,
is_fl_channel :4);
/* RECORD BODY BYTES */
uint8_t __reserved4;
uint8_t is_fl_type;
uint8_t is_fl_modifier;
uint8_t is_fl_entity;
uint8_t is_fl_instance;
uint8_t is_fl_oem;
DECL_BITFIELD2(
is_fl_idlen :6,
is_fl_idtype :2);
char is_fl_idstring[1];
} ipmi_sdr_fru_locator_t;
#define is_fl_devid _devid_or_slaveaddr._logical._is_fl_devid
#define is_fl_slaveaddr _devid_or_slaveaddr._nonintelligent._is_fl_slaveaddr
/*
* The remaining SDR types do not have an associated structure, yet.
*/
#define IPMI_SDR_TYPE_FULL_SENSOR 0x01
#define IPMI_SDR_TYPE_COMPACT_SENSOR 0x02
#define IPMI_SDR_TYPE_EVENT_ONLY 0x03
#define IPMI_SDR_TYPE_ENTITY_ASSOCIATION 0x08
#define IPMI_SDR_TYPE_DEVICE_RELATIVE 0x09
#define IPMI_SDR_TYPE_MANAGEMENT_DEVICE 0x12
#define IPMI_SDR_TYPE_MANAGEMENT_CONFIRMATION 0x13
#define IPMI_SDR_TYPE_BMC_MESSAGE_CHANNEL 0x14
#define IPMI_SDR_TYPE_OEM 0xC0
/*
* Lookup the given sensor type by name. These functions automatically read in
* and cache the complete SDR repository.
*/
extern ipmi_sdr_fru_locator_t *ipmi_sdr_lookup_fru(ipmi_handle_t *,
const char *);
extern ipmi_sdr_generic_locator_t *ipmi_sdr_lookup_generic(ipmi_handle_t *,
const char *);
/*
* Get Sensor Reading. See section 35.14.
*/
#define IPMI_CMD_GET_SENSOR_READING 0x2d
typedef struct ipmi_sensor_reading {
uint8_t isr_reading;
DECL_BITFIELD4(
__reserved1 :5,
isr_state_unavailable :1,
isr_scanning_disabled :1,
isr_event_disabled :1);
uint16_t isr_state;
} ipmi_sensor_reading_t;
extern ipmi_sensor_reading_t *ipmi_get_sensor_reading(ipmi_handle_t *, uint8_t);
/*
* Set Sensor Reading. See section 35.14.
*/
#define IPMI_CMD_SET_SENSOR_READING 0x30
#define IPMI_SENSOR_OP_CLEAR 0x3 /* clear '0' bits */
#define IPMI_SENSOR_OP_SET 0x2 /* set '1' bits */
#define IPMI_SENSOR_OP_EXACT 0x1 /* set bits exactly */
typedef struct ipmi_set_sensor_reading {
uint8_t iss_id;
DECL_BITFIELD5(
iss_set_reading :1,
__reserved :1,
iss_deassrt_op :2,
iss_assert_op :2,
iss_data_bytes :2);
uint8_t iss_sensor_reading;
uint16_t iss_assert_state; /* optional */
uint16_t iss_deassert_state; /* optional */
uint8_t iss_event_data1; /* optional */
uint8_t iss_event_data2; /* optional */
uint8_t iss_event_data3; /* optional */
} ipmi_set_sensor_reading_t;
extern int ipmi_set_sensor_reading(ipmi_handle_t *,
ipmi_set_sensor_reading_t *);
/*
* These IPMI message id/opcodes are documented in Appendix G in the IPMI spec.
*
* Payloads for these two commands are described in Sections 34.1 and 34.2 of
* the spec, respectively.
*/
#define IPMI_CMD_GET_FRU_INV_AREA 0x10
#define IPMI_CMD_READ_FRU_DATA 0x11
/*
* Structs to hold the FRU Common Header and the FRU Product Info Area, as
* described in the IPMI Platform Management FRU Information Storage
* Definition (v1.1).
*/
typedef struct ipmi_fru_hdr
{
uint8_t ifh_format;
uint8_t ifh_int_use_off;
uint8_t ifh_chassis_info_off;
uint8_t ifh_board_info_off;
uint8_t ifh_product_info_off;
uint8_t ifh_multi_rec_off;
uint8_t ifh_pad;
uint8_t ifh_chksum;
} ipmi_fru_hdr_t;
/*
* Because only 6 bits are used to specify the length of each field in the FRU
* product and board info areas, the biggest string we would ever need to hold
* would be 63 chars plus a NULL.
*/
#define FRU_INFO_MAXLEN 64
typedef struct ipmi_fru_brd_info
{
char ifbi_manuf_date[3];
char ifbi_manuf_name[FRU_INFO_MAXLEN];
char ifbi_board_name[FRU_INFO_MAXLEN];
char ifbi_product_serial[FRU_INFO_MAXLEN];
char ifbi_part_number[FRU_INFO_MAXLEN];
} ipmi_fru_brd_info_t;
typedef struct ipmi_fru_prod_info
{
char ifpi_manuf_name[FRU_INFO_MAXLEN];
char ifpi_product_name[FRU_INFO_MAXLEN];
char ifpi_part_number[FRU_INFO_MAXLEN];
char ifpi_product_version[FRU_INFO_MAXLEN];
char ifpi_product_serial[FRU_INFO_MAXLEN];
char ifpi_asset_tag[FRU_INFO_MAXLEN];
} ipmi_fru_prod_info_t;
int ipmi_fru_read(ipmi_handle_t *, ipmi_sdr_fru_locator_t *, char **);
int ipmi_fru_parse_board(ipmi_handle_t *, char *, ipmi_fru_brd_info_t *);
int ipmi_fru_parse_product(ipmi_handle_t *, char *, ipmi_fru_prod_info_t *);
/*
* User management. The raw functions are private to libipmi, and only the
* higher level abstraction (ipmi_user_t) is exported to consumers of the
* library.
*/
#define IPMI_USER_PRIV_CALLBACK 0x1
#define IPMI_USER_PRIV_USER 0x2
#define IPMI_USER_PRIV_OPERATOR 0x3
#define IPMI_USER_PRIV_ADMIN 0x4
#define IPMI_USER_PRIV_OEM 0x5
#define IPMI_USER_PRIV_NONE 0xf
typedef struct ipmi_user {
uint8_t iu_uid;
char *iu_name;
boolean_t iu_enabled;
boolean_t iu_ipmi_msg_enable;
boolean_t iu_link_auth_enable;
uint8_t iu_priv;
struct ipmi_user *iu_next;
} ipmi_user_t;
extern int ipmi_user_iter(ipmi_handle_t *,
int (*)(ipmi_user_t *, void *), void *);
extern ipmi_user_t *ipmi_user_lookup_name(ipmi_handle_t *, const char *);
extern ipmi_user_t *ipmi_user_lookup_id(ipmi_handle_t *, uint8_t);
extern int ipmi_user_set_password(ipmi_handle_t *, uint8_t, const char *);
/*
* The remaining functions are private to the implementation of the Sun ILOM
* service processor. These function first check the manufacturer from the IPMI
* device ID, and will return EIPMI_NOT_SUPPORTED if attempted for non-Sun
* devices.
*/
/*
* Sun OEM LED requests.
*/
#define IPMI_SUNOEM_LED_MODE_OFF 0
#define IPMI_SUNOEM_LED_MODE_ON 1
#define IPMI_SUNOEM_LED_MODE_STANDBY 2
#define IPMI_SUNOEM_LED_MODE_SLOW 3
#define IPMI_SUNOEM_LED_MODE_FAST 4
/*
* These functions take a SDR record and construct the appropriate form of the
* above commands.
*/
extern int ipmi_sunoem_led_set(ipmi_handle_t *,
ipmi_sdr_generic_locator_t *, uint8_t);
extern int ipmi_sunoem_led_get(ipmi_handle_t *,
ipmi_sdr_generic_locator_t *, uint8_t *);
/*
* Sun OEM uptime. Note that the underlying command returns the uptime in big
* endian form. This wrapper automatically converts to the appropriate native
* form.
*/
#define IPMI_CMD_SUNOEM_UPTIME 0x08
extern int ipmi_sunoem_uptime(ipmi_handle_t *, uint32_t *, uint32_t *);
/*
* Sun OEM FRU update. The FRU information is managed through a generic
* identifier, and then a type-specific data portion. The wrapper function will
* automatically fill in the data length field according to which type is
* specified.
*/
#define IPMI_CMD_SUNOEM_FRU_UPDATE 0x16
#define IPMI_SUNOEM_FRU_DIMM 0x00
#define IPMI_SUNOEM_FRU_CPU 0x01
#define IPMI_SUNOEM_FRU_BIOS 0x02
#define IPMI_SUNOEM_FRU_DISK 0x03
typedef struct ipmi_sunoem_fru {
uint8_t isf_type;
uint8_t isf_id;
uint8_t isf_datalen;
union {
struct {
uint8_t isf_data[128];
} dimm;
struct {
uint32_t isf_thermtrip;
uint32_t isf_eax;
char isf_product[48];
} cpu;
struct {
char isf_part[16];
char isf_version[16];
} bios;
struct {
char isf_manufacturer[16];
char isf_model[28];
char isf_serial[20];
char isf_version[8];
char isf_capacity[16];
} disk;
} isf_data;
} ipmi_sunoem_fru_t;
int ipmi_sunoem_update_fru(ipmi_handle_t *, ipmi_sunoem_fru_t *);
#pragma pack()
#ifdef __cplusplus
}
#endif
#endif /* _LIBIPMI_H */