13798Seschrock /*
23798Seschrock  * CDDL HEADER START
33798Seschrock  *
43798Seschrock  * The contents of this file are subject to the terms of the
53798Seschrock  * Common Development and Distribution License (the "License").
63798Seschrock  * You may not use this file except in compliance with the License.
73798Seschrock  *
83798Seschrock  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93798Seschrock  * or http://www.opensolaris.org/os/licensing.
103798Seschrock  * See the License for the specific language governing permissions
113798Seschrock  * and limitations under the License.
123798Seschrock  *
133798Seschrock  * When distributing Covered Code, include this CDDL HEADER in each
143798Seschrock  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153798Seschrock  * If applicable, add the following below this CDDL HEADER, with the
163798Seschrock  * fields enclosed by brackets "[]" replaced with your own identifying
173798Seschrock  * information: Portions Copyright [yyyy] [name of copyright owner]
183798Seschrock  *
193798Seschrock  * CDDL HEADER END
203798Seschrock  */
213798Seschrock /*
223798Seschrock  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
233798Seschrock  * Use is subject to license terms.
243798Seschrock  */
253798Seschrock 
263798Seschrock #ifndef	_LIBIPMI_H
273798Seschrock #define	_LIBIPMI_H
283798Seschrock 
293798Seschrock #pragma ident	"%Z%%M%	%I%	%E% SMI"
303798Seschrock 
313798Seschrock #include <sys/bmc_intf.h>
323798Seschrock #include <sys/byteorder.h>
333798Seschrock 
343798Seschrock /*
353798Seschrock  * Private interfaces for communicating with attached services over IPMI.  This
363798Seschrock  * library is designed for system software communicating with Sun-supported
373798Seschrock  * service processors over /dev/bmc.  It is not a generic IPMI library.
383798Seschrock  *
393798Seschrock  * Documentation references refer to "Intelligent Platform Management Interface
403798Seschrock  * Specification Second Generation v2.0", document revision 1.0 with Februrary
413798Seschrock  * 15, 2006 Markup from "IPMI v2.0 Addenda, Errata, and Clarifications Revision
423798Seschrock  * 3".
433798Seschrock  */
443798Seschrock 
453798Seschrock #ifdef	__cplusplus
463798Seschrock extern "C" {
473798Seschrock #endif
483798Seschrock 
493798Seschrock typedef struct ipmi_handle ipmi_handle_t;
503798Seschrock 
513798Seschrock #if !defined(_BIT_FIELDS_LTOH) && !defined(_BIT_FIELDS_HTOL)
523798Seschrock #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
533798Seschrock #endif
543798Seschrock 
553798Seschrock #pragma pack(1)
563798Seschrock 
573798Seschrock /*
583798Seschrock  * Basic netfn definitions.  See section 5.1.
593798Seschrock  */
603798Seschrock #define	IPMI_NETFN_APP			BMC_NETFN_APP
613798Seschrock #define	IPMI_NETFN_STORAGE		BMC_NETFN_STORAGE
623798Seschrock #define	IPMI_NETFN_SE			BMC_NETFN_SE
633798Seschrock #define	IPMI_NETFN_OEM			0x2e
643798Seschrock 
653798Seschrock /*
663798Seschrock  * Error definitions
673798Seschrock  */
683798Seschrock #define	EIPMI_BASE	2000
693798Seschrock 
703798Seschrock enum {
713798Seschrock 	EIPMI_NOMEM = EIPMI_BASE,	/* memory allocation failure */
723798Seschrock 	EIPMI_BMC_OPEN_FAILED,		/* failed to open /dev/bmc */
733798Seschrock 	EIPMI_BMC_PUTMSG,		/* putmsg() failed */
743798Seschrock 	EIPMI_BMC_GETMSG,		/* getmsg() failed */
753798Seschrock 	EIPMI_BMC_RESPONSE,		/* response from /dev/bmc failed */
763798Seschrock 	EIPMI_INVALID_COMMAND,		/* invalid command */
773798Seschrock 	EIPMI_COMMAND_TIMEOUT,		/* command timeout */
783798Seschrock 	EIPMI_DATA_LENGTH_EXCEEDED,	/* maximum data length exceeded */
793798Seschrock 	EIPMI_SEND_FAILED,		/* failed to send BMC request */
803798Seschrock 	EIPMI_UNSPECIFIED,		/* unspecified error */
813798Seschrock 	EIPMI_UNKNOWN,			/* unknown error */
823798Seschrock 	EIPMI_BAD_RESPONSE,		/* received unexpected response */
833798Seschrock 	EIPMI_BAD_RESPONSE_LENGTH,	/* unexpected response length */
843798Seschrock 	EIPMI_INVALID_RESERVATION,	/* invalid reservation */
853798Seschrock 	EIPMI_NOT_PRESENT,		/* requested entity not present */
863798Seschrock 	EIPMI_INVALID_REQUEST,		/* malformed request */
873798Seschrock 	EIPMI_BUSY,			/* SP is busy */
883798Seschrock 	EIPMI_NOSPACE,			/* SP is out of space */
893798Seschrock 	EIPMI_UNAVAILABLE,		/* SP is present but unavailable */
903798Seschrock 	EIPMI_ACCESS			/* insufficient privileges */
913798Seschrock };
923798Seschrock 
933798Seschrock /*
943798Seschrock  * Basic library functions.
953798Seschrock  *
963798Seschrock  * The ipmi_handle is the primary interface to the library.  The library itself
973798Seschrock  * is not MT-safe, but it is safe within a single handle.  Multithreaded clients
983798Seschrock  * should either open multiple handles, or otherwise synchronize access to the
993798Seschrock  * same handle.
1003798Seschrock  *
1013798Seschrock  * There is a single command response buffer that is stored with the handle, to
1023798Seschrock  * simplify memory management in the caller.  The memory referenced by a command
1033798Seschrock  * response is only valid until the next command is issued.  The caller is
1043798Seschrock  * responsible for making a copy of the response if it is needed.
1053798Seschrock  */
1063798Seschrock extern ipmi_handle_t *ipmi_open(int *, char **);
1073798Seschrock extern void ipmi_close(ipmi_handle_t *);
1083798Seschrock 
1093798Seschrock extern int ipmi_errno(ipmi_handle_t *);
1103798Seschrock extern const char *ipmi_errmsg(ipmi_handle_t *);
1113798Seschrock 
1123798Seschrock /*
1133798Seschrock  * Raw requests.  See section 5.
1143798Seschrock  */
1153798Seschrock typedef struct ipmi_cmd {
1163798Seschrock 	uint8_t		ic_netfn:6;
1173798Seschrock 	uint8_t		ic_lun:2;
1183798Seschrock 	uint8_t		ic_cmd;
1193798Seschrock 	uint16_t	ic_dlen;
1203798Seschrock 	void		*ic_data;
1213798Seschrock } ipmi_cmd_t;
1223798Seschrock 
1233798Seschrock extern ipmi_cmd_t *ipmi_send(ipmi_handle_t *, ipmi_cmd_t *);
1243798Seschrock 
1253798Seschrock /*
1263798Seschrock  * Retrieve basic information about the IPMI device.  See section 20.1 "Get
1273798Seschrock  * Device ID Command".
1283798Seschrock  */
1293798Seschrock #define	IPMI_CMD_GET_DEVICEID		0x01
1303798Seschrock 
1313798Seschrock typedef struct ipmi_deviceid {
1323798Seschrock 	uint8_t		id_devid;
1333798Seschrock #if defined(_BIT_FIELDS_LTOH)
1343798Seschrock 	uint8_t		id_dev_rev:4;
1353798Seschrock 	uint8_t		__reserved:3;
1363798Seschrock 	uint8_t		id_dev_sdrs:1;
1373798Seschrock #else
1383798Seschrock 	uint8_t		id_dev_sdrs:1;
1393798Seschrock 	uint8_t		__reserved:3;
1403798Seschrock 	uint8_t		id_dev_rev:4;
1413798Seschrock #endif
1424801Seschrock #if defined(_BIT_FIELDS_LTOH)
1433798Seschrock 	uint8_t		id_firm_major:7;
1443798Seschrock 	uint8_t		id_dev_available:1;
1453798Seschrock #else
1463798Seschrock 	uint8_t		id_dev_available:1;
1473798Seschrock 	uint8_t		id_firm_major:7;
1483798Seschrock #endif
1493798Seschrock 	uint8_t		id_firm_minor;
1503798Seschrock 	uint8_t		id_ipmi_rev;
1513798Seschrock 	uint8_t		id_dev_support;
1523798Seschrock 	uint8_t		id_manufacturer[3];
1533798Seschrock 	uint16_t	id_product;
1543798Seschrock } ipmi_deviceid_t;
1553798Seschrock 
1563798Seschrock #define	IPMI_OEM_SUN	0x2a
1573798Seschrock 
1583798Seschrock ipmi_deviceid_t *ipmi_get_deviceid(ipmi_handle_t *);
1593798Seschrock 
1603798Seschrock #define	ipmi_devid_manufacturer(dp)		\
1613798Seschrock 	((dp)->id_manufacturer[0] |		\
1623798Seschrock 	((dp)->id_manufacturer[1] << 8) |	\
1633798Seschrock 	((dp)->id_manufacturer[2] << 16))
1643798Seschrock 
1653798Seschrock /*
1663798Seschrock  * SDR (Sensor Device Record) requests.  A cache of the current SDR repository
1673798Seschrock  * is kept as part of the IPMI handle and updated when necessary.  Routines to
1683798Seschrock  * access the raw SDR repository are also provided.
1693798Seschrock  */
1703798Seschrock 
1713798Seschrock /*
1723798Seschrock  * Reserve repository command.  See section 33.11.
1733798Seschrock  */
1743798Seschrock #define	IPMI_CMD_RESERVE_SDR_REPOSITORY	0x22
1753798Seschrock 
1763798Seschrock /*
1773798Seschrock  * Get SDR command.  See section 33.12.  This command accesses the raw SDR
1783798Seschrock  * repository.  Clients can also use the lookup functions to retrieve a
1793798Seschrock  * particular SDR record by name.
1803798Seschrock  *
1813798Seschrock  * The list of possible types is indicated in the sub-chapters of section 43.
1823798Seschrock  */
1833798Seschrock typedef struct ipmi_sdr {
1843798Seschrock 	uint16_t	is_id;
1853798Seschrock 	uint8_t		is_version;
1863798Seschrock 	uint8_t		is_type;
1873798Seschrock 	uint8_t		is_length;
1883798Seschrock 	uint8_t		is_record[1];
1893798Seschrock } ipmi_sdr_t;
1903798Seschrock #define	IPMI_CMD_GET_SDR		0x23
1913798Seschrock 
1923798Seschrock #define	IPMI_SDR_FIRST			0x0000
1933798Seschrock #define	IPMI_SDR_LAST			0xFFFF
1943798Seschrock 
1953798Seschrock extern ipmi_sdr_t *ipmi_sdr_get(ipmi_handle_t *, uint16_t, uint16_t *);
1963798Seschrock 
1973798Seschrock /*
1983798Seschrock  * Generic Device Locator Record.  See section 43.7.
1993798Seschrock  */
2003798Seschrock 
2013798Seschrock #define	IPMI_SDR_TYPE_GENERIC_LOCATOR		0x10
2023798Seschrock 
2033798Seschrock typedef struct ipmi_sdr_generic_locator {
2043798Seschrock 	/* RECORD KEY BYTES */
2053798Seschrock #if defined(_BIT_FIELDS_LTOH)
2063798Seschrock 	uint8_t		__reserved1:1;
2073798Seschrock 	uint8_t		is_gl_accessaddr:7;
2083798Seschrock 	uint8_t		is_gl_channel_msb:1;
2093798Seschrock 	uint8_t		is_gl_slaveaddr:7;
2103798Seschrock 	uint8_t		is_gl_bus:3;
2113798Seschrock 	uint8_t		is_gl_lun:2;
2123798Seschrock 	uint8_t		is_gl_channel:3;
2133798Seschrock #else
2143798Seschrock 	uint8_t		is_gl_accessaddr:7;
2153798Seschrock 	uint8_t		__reserved1:1;
2163798Seschrock 	uint8_t		is_gl_slaveaddr:7;
2173798Seschrock 	uint8_t		is_gl_channel_msb:1;
2183798Seschrock 	uint8_t		is_gl_channel:3;
2193798Seschrock 	uint8_t		is_gl_lun:2;
2203798Seschrock 	uint8_t		is_gl_bus:3;
2213798Seschrock #endif
2223798Seschrock 	/* RECORD BODY BYTES */
2233798Seschrock #if defined(_BIT_FIELDS_LTOH)
2243798Seschrock 	uint8_t		is_gl_span:3;
2253798Seschrock 	uint8_t		__reserved2:5;
2263798Seschrock #else
2273798Seschrock 	uint8_t		__reserved2:5;
2283798Seschrock 	uint8_t		is_gl_span:3;
2293798Seschrock #endif
2303798Seschrock 	uint8_t		__reserved3;
2313798Seschrock 	uint8_t		is_gl_type;
2323798Seschrock 	uint8_t		is_gl_modifier;
2333798Seschrock 	uint8_t		is_gl_entity;
2343798Seschrock 	uint8_t		is_gl_instance;
2353798Seschrock 	uint8_t		is_gl_oem;
2363798Seschrock #if defined(_BIT_FIELDS_LTOH)
2373798Seschrock 	uint8_t		is_gl_idlen:6;
2383798Seschrock 	uint8_t		is_gl_idtype:2;
2393798Seschrock #else
2403798Seschrock 	uint8_t		is_gl_idtype:2;
2413798Seschrock 	uint8_t		is_gl_idlen:6;
2423798Seschrock #endif
2433798Seschrock 	char		is_gl_idstring[1];
2443798Seschrock } ipmi_sdr_generic_locator_t;
2453798Seschrock 
2463798Seschrock /*
2473798Seschrock  * FRU Device Locator Record.  See section 43.8.
2483798Seschrock  */
2493798Seschrock 
2503798Seschrock #define	IPMI_SDR_TYPE_FRU_LOCATOR		0x11
2513798Seschrock 
2523798Seschrock typedef struct ipmi_sdr_fru_locator {
2533798Seschrock 	/* RECORD KEY BYTES */
2543798Seschrock #if defined(_BIT_FIELDS_LTOH)
2553798Seschrock 	uint8_t		__reserved1:1;
2563798Seschrock 	uint8_t		is_fl_accessaddr:7;
2573798Seschrock #else
2583798Seschrock 	uint8_t		is_fl_accessaddr:7;
2593798Seschrock 	uint8_t		__reserved1:1;
2603798Seschrock #endif
2613798Seschrock 	union {
2623798Seschrock 		struct {
2633798Seschrock 			uint8_t	_is_fl_devid;
2643798Seschrock 		} _logical;
2653798Seschrock 		struct {
2663798Seschrock #if defined(_BIT_FIELDS_LTOH)
2673798Seschrock 			uint8_t	__reserved:1;
2683798Seschrock 			uint8_t	_is_fl_slaveaddr:7;
2693798Seschrock #else
2703798Seschrock 			uint8_t	_is_fl_slaveaddr:7;
2713798Seschrock 			uint8_t	__reserved:1;
2723798Seschrock #endif
2733798Seschrock 		} _nonintelligent;
2743798Seschrock 	} _devid_or_slaveaddr;
2753798Seschrock #if defined(_BIT_FIELDS_LTOH)
2763798Seschrock 	uint8_t		is_fl_bus:3;
2773798Seschrock 	uint8_t		is_fl_lun:2;
2783798Seschrock 	uint8_t		__reserved2:2;
2793798Seschrock 	uint8_t		is_fl_logical:1;
2803798Seschrock 	uint8_t		__reserved3:4;
2813798Seschrock 	uint8_t		is_fl_channel:4;
2823798Seschrock #else
2833798Seschrock 	uint8_t		is_fl_logical:1;
2843798Seschrock 	uint8_t		__reserved2:2;
2853798Seschrock 	uint8_t		is_fl_lun:2;
2863798Seschrock 	uint8_t		is_fl_bus:3;
2873798Seschrock 	uint8_t		is_fl_channel:4;
2883798Seschrock 	uint8_t		__reserved3:4;
2893798Seschrock #endif
2903798Seschrock 	/* RECORD BODY BYTES */
2913798Seschrock 	uint8_t		__reserved4;
2923798Seschrock 	uint8_t		is_fl_type;
2933798Seschrock 	uint8_t		is_fl_modifier;
2943798Seschrock 	uint8_t		is_fl_entity;
2953798Seschrock 	uint8_t		is_fl_instance;
2963798Seschrock 	uint8_t		is_fl_oem;
2973798Seschrock #if defined(_BIT_FIELDS_LTOH)
2983798Seschrock 	uint8_t		is_fl_idlen:6;
2993798Seschrock 	uint8_t		is_fl_idtype:2;
3003798Seschrock #else
3013798Seschrock 	uint8_t		is_fl_idtype:2;
3023798Seschrock 	uint8_t		is_fl_idlen:6;
3033798Seschrock #endif
3043798Seschrock 	char		is_fl_idstring[1];
3053798Seschrock } ipmi_sdr_fru_locator_t;
3063798Seschrock 
3073798Seschrock #define	is_fl_devid	_devid_or_slaveaddr._logical._is_fl_devid
3083798Seschrock #define	is_fl_slaveaddr	_devid_or_slaveaddr._nonintelligent._is_fl_slaveaddr
3093798Seschrock 
3103798Seschrock /*
3113798Seschrock  * The remaining SDR types do not have an associated structure, yet.
3123798Seschrock  */
3133798Seschrock #define	IPMI_SDR_TYPE_FULL_SENSOR		0x01
3143798Seschrock #define	IPMI_SDR_TYPE_COMPACT_SENSOR		0x02
3153798Seschrock #define	IPMI_SDR_TYPE_EVENT_ONLY		0x03
3163798Seschrock #define	IPMI_SDR_TYPE_ENTITY_ASSOCIATION	0x08
3173798Seschrock #define	IPMI_SDR_TYPE_DEVICE_RELATIVE		0x09
3183798Seschrock #define	IPMI_SDR_TYPE_MANAGEMENT_DEVICE		0x12
3193798Seschrock #define	IPMI_SDR_TYPE_MANAGEMENT_CONFIRMATION	0x13
3203798Seschrock #define	IPMI_SDR_TYPE_BMC_MESSAGE_CHANNEL	0x14
3213798Seschrock #define	IPMI_SDR_TYPE_OEM			0xC0
3223798Seschrock 
3233798Seschrock /*
3243798Seschrock  * Lookup the given sensor type by name.  These functions automatically read in
3253798Seschrock  * and cache the complete SDR repository.
3263798Seschrock  */
3273798Seschrock extern ipmi_sdr_fru_locator_t *ipmi_sdr_lookup_fru(ipmi_handle_t *,
3283798Seschrock     const char *);
3293798Seschrock extern ipmi_sdr_generic_locator_t *ipmi_sdr_lookup_generic(ipmi_handle_t *,
3303798Seschrock     const char *);
3313798Seschrock 
3323798Seschrock /*
3333798Seschrock  * Get Sensor Reading.  See section 35.14.
3343798Seschrock  */
3353798Seschrock 
3363798Seschrock #define	IPMI_CMD_GET_SENSOR_READING	0x2d
3373798Seschrock 
3383798Seschrock typedef struct ipmi_sensor_reading {
3393798Seschrock 	uint8_t		isr_reading;
3403798Seschrock #if defined(_BIT_FIELDS_LTOH)
3413798Seschrock 	uint8_t		__reserved1:5;
3423798Seschrock 	uint8_t		isr_state_unavailable:1;
3433798Seschrock 	uint8_t		isr_scanning_disabled:1;
3443798Seschrock 	uint8_t		isr_event_disabled:1;
3453798Seschrock #else
3463798Seschrock 	uint8_t		isr_event_disabled:1;
3473798Seschrock 	uint8_t		isr_scanning_disabled:1;
3483798Seschrock 	uint8_t		isr_state_unavailable:1;
3493798Seschrock 	uint8_t		__reserved1:5;
3503798Seschrock #endif
3513798Seschrock 	uint16_t	isr_state;
3523798Seschrock } ipmi_sensor_reading_t;
3533798Seschrock 
3543798Seschrock extern ipmi_sensor_reading_t *ipmi_get_sensor_reading(ipmi_handle_t *, uint8_t);
3553798Seschrock 
3563798Seschrock /*
3573798Seschrock  * Set Sensor Reading.  See section 35.14.
3583798Seschrock  */
3593798Seschrock #define	IPMI_CMD_SET_SENSOR_READING	0x30
3603798Seschrock 
3613798Seschrock #define	IPMI_SENSOR_OP_CLEAR	0x3	/* clear '0' bits */
3623798Seschrock #define	IPMI_SENSOR_OP_SET	0x2	/* set '1' bits */
3633798Seschrock #define	IPMI_SENSOR_OP_EXACT	0x1	/* set bits exactly */
3643798Seschrock 
3653798Seschrock typedef struct ipmi_set_sensor_reading {
3663798Seschrock 	uint8_t		iss_id;
3673798Seschrock #if defined(_BIT_FIELDS_LTOH)
3683798Seschrock 	uint8_t		iss_set_reading:1;
3693798Seschrock 	uint8_t		__reserved:1;
3703798Seschrock 	uint8_t		iss_deassrt_op:2;
3713798Seschrock 	uint8_t		iss_assert_op:2;
3723798Seschrock 	uint8_t		iss_data_bytes:2;
3733798Seschrock #else
3743798Seschrock 	uint8_t		iss_data_bytes:2;
3753798Seschrock 	uint8_t		iss_assert_op:2;
3763798Seschrock 	uint8_t		iss_deassrt_op:2;
3773798Seschrock 	uint8_t		__reserved:1;
3783798Seschrock 	uint8_t		iss_set_reading:1;
3793798Seschrock #endif
3803798Seschrock 	uint8_t		iss_sensor_reading;
3813798Seschrock 	uint16_t	iss_assert_state;	/* optional */
3823798Seschrock 	uint16_t	iss_deassert_state;	/* optional */
3833798Seschrock 	uint8_t		iss_event_data1;	/* optional */
3843798Seschrock 	uint8_t		iss_event_data2;	/* optional */
3853798Seschrock 	uint8_t		iss_event_data3;	/* optional */
3863798Seschrock } ipmi_set_sensor_reading_t;
3873798Seschrock 
3883798Seschrock extern int ipmi_set_sensor_reading(ipmi_handle_t *,
3893798Seschrock     ipmi_set_sensor_reading_t *);
3903798Seschrock 
3913798Seschrock /*
392*5068Srobj  * These IPMI message id/opcodes are documented in Appendix G in the IPMI spec.
393*5068Srobj  *
394*5068Srobj  * Payloads for these two commands are described in Sections 34.1 and 34.2 of
395*5068Srobj  * the spec, respectively.
396*5068Srobj  */
397*5068Srobj #define	IPMI_CMD_GET_FRU_INV_AREA	0x10
398*5068Srobj #define	IPMI_CMD_READ_FRU_DATA		0x11
399*5068Srobj 
400*5068Srobj /*
401*5068Srobj  * Structs to hold the FRU Common Header and the FRU Product Info Area, as
402*5068Srobj  * described in the IPMI Platform Management FRU Information Storage
403*5068Srobj  * Definition (v1.1).
404*5068Srobj  */
405*5068Srobj typedef struct ipmi_fru_hdr
406*5068Srobj {
407*5068Srobj 	uint8_t		ifh_format;
408*5068Srobj 	uint8_t		ifh_int_use_off;
409*5068Srobj 	uint8_t		ifh_chassis_info_off;
410*5068Srobj 	uint8_t		ifh_board_info_off;
411*5068Srobj 	uint8_t		ifh_product_info_off;
412*5068Srobj 	uint8_t		ifh_multi_rec_off;
413*5068Srobj 	uint8_t		ifh_pad;
414*5068Srobj 	uint8_t		ifh_chksum;
415*5068Srobj } ipmi_fru_hdr_t;
416*5068Srobj 
417*5068Srobj /*
418*5068Srobj  * Because only 6 bits are used to specify the length of each field in the FRU
419*5068Srobj  * product and board info areas, the biggest string we would ever need to hold
420*5068Srobj  * would be 63 chars plus a NULL.
421*5068Srobj  */
422*5068Srobj #define	FRU_INFO_MAXLEN	64
423*5068Srobj 
424*5068Srobj typedef struct ipmi_fru_brd_info
425*5068Srobj {
426*5068Srobj 	char	ifbi_manuf_date[3];
427*5068Srobj 	char	ifbi_manuf_name[FRU_INFO_MAXLEN];
428*5068Srobj 	char	ifbi_board_name[FRU_INFO_MAXLEN];
429*5068Srobj 	char	ifbi_product_serial[FRU_INFO_MAXLEN];
430*5068Srobj 	char	ifbi_part_number[FRU_INFO_MAXLEN];
431*5068Srobj } ipmi_fru_brd_info_t;
432*5068Srobj 
433*5068Srobj typedef struct ipmi_fru_prod_info
434*5068Srobj {
435*5068Srobj 	char	ifpi_manuf_name[FRU_INFO_MAXLEN];
436*5068Srobj 	char	ifpi_product_name[FRU_INFO_MAXLEN];
437*5068Srobj 	char	ifpi_part_number[FRU_INFO_MAXLEN];
438*5068Srobj 	char	ifpi_product_version[FRU_INFO_MAXLEN];
439*5068Srobj 	char	ifpi_product_serial[FRU_INFO_MAXLEN];
440*5068Srobj 	char	ifpi_asset_tag[FRU_INFO_MAXLEN];
441*5068Srobj } ipmi_fru_prod_info_t;
442*5068Srobj 
443*5068Srobj int ipmi_fru_read(ipmi_handle_t *, ipmi_sdr_fru_locator_t *, char **);
444*5068Srobj int ipmi_fru_parse_board(ipmi_handle_t *, char *, ipmi_fru_brd_info_t *);
445*5068Srobj int ipmi_fru_parse_product(ipmi_handle_t *, char *, ipmi_fru_prod_info_t *);
446*5068Srobj 
447*5068Srobj /*
4483798Seschrock  * The remaining functions are private to the implementation of the Sun ILOM
4493798Seschrock  * service processor.  These function first check the manufacturer from the IPMI
4503798Seschrock  * device ID, and will return EIPMI_NOT_SUPPORTED if attempted for non-Sun
4513798Seschrock  * devices.
4523798Seschrock  */
4533798Seschrock 
4543798Seschrock /*
4553798Seschrock  * Sun OEM LED requests.
4563798Seschrock  */
4573798Seschrock 
4583798Seschrock #define	IPMI_CMD_SUNOEM_LED_GET		0x21
4593798Seschrock #define	IPMI_CMD_SUNOEM_LED_SET		0x22
4603798Seschrock 
4613798Seschrock typedef struct ipmi_cmd_sunoem_led_set {
4624801Seschrock #if defined(_BIT_FIELDS_LTOH)
4634801Seschrock 	uint8_t		ic_sls_channel_msb:1;	/* device slave address */
4644801Seschrock 	uint8_t		ic_sls_slaveaddr:7;	/* (from SDR record) */
4654801Seschrock #else
4664801Seschrock 	uint8_t		ic_sls_slaveaddr:7;
4674801Seschrock 	uint8_t		ic_sls_channel_msb:1;
4684801Seschrock #endif
4693798Seschrock 	uint8_t		ic_sls_type;		/* led type */
4704801Seschrock #if defined(_BIT_FIELDS_LTOH)
4714801Seschrock 	uint8_t		__reserved:1;		/* device access address */
4724801Seschrock 	uint8_t		ic_sls_accessaddr:7;	/* (from SDR record) */
4734801Seschrock #else
4744801Seschrock 	uint8_t		ic_sls_accessaddr:7;
4754801Seschrock 	uint8_t		__reserved:1;
4764801Seschrock #endif
4773798Seschrock 	uint8_t		ic_sls_hwinfo;		/* OEM hardware info */
4783798Seschrock 	uint8_t		ic_sls_mode;		/* LED mode */
4793798Seschrock 	uint8_t		ic_sls_force;		/* force direct access */
4803798Seschrock 	uint8_t		ic_sls_role;		/* BMC authorization */
4813798Seschrock } ipmi_cmd_sunoem_led_set_t;
4823798Seschrock 
4833798Seschrock typedef struct ipmi_cmd_sunoem_led_get {
4844801Seschrock #if defined(_BIT_FIELDS_LTOH)
4854801Seschrock 	uint8_t		ic_slg_channel_msb:1;	/* device slave address */
4864801Seschrock 	uint8_t		ic_slg_slaveaddr:7;	/* (from SDR record) */
4874801Seschrock #else
4884801Seschrock 	uint8_t		ic_slg_slaveaddr:7;
4894801Seschrock 	uint8_t		ic_slg_channel_msb:1;
4904801Seschrock #endif
4913798Seschrock 	uint8_t		ic_slg_type;		/* led type */
4924801Seschrock #if defined(_BIT_FIELDS_LTOH)
4934801Seschrock 	uint8_t		__reserved:1;		/* device access address */
4944801Seschrock 	uint8_t		ic_slg_accessaddr:7;	/* (from SDR record) */
4954801Seschrock #else
4964801Seschrock 	uint8_t		ic_slg_accessaddr:7;
4974801Seschrock 	uint8_t		__reserved:1;
4984801Seschrock #endif
4993798Seschrock 	uint8_t		ic_slg_hwinfo;		/* OEM hardware info */
5003798Seschrock 	uint8_t		ic_slg_force;		/* force direct access */
5013798Seschrock } ipmi_cmd_sunoem_led_get_t;
5023798Seschrock 
5033798Seschrock #define	IPMI_SUNOEM_LED_TYPE_OK2RM	0
5043798Seschrock #define	IPMI_SUNOEM_LED_TYPE_SERVICE	1
5053798Seschrock #define	IPMI_SUNOEM_LED_TYPE_ACT	2
5063798Seschrock #define	IPMI_SUNOEM_LED_TYPE_LOCATE	3
5073798Seschrock #define	IPMI_SUNOEM_LED_TYPE_ANY	0xFF
5083798Seschrock 
5093798Seschrock #define	IPMI_SUNOEM_LED_MODE_OFF	0
5103798Seschrock #define	IPMI_SUNOEM_LED_MODE_ON		1
5113798Seschrock #define	IPMI_SUNOEM_LED_MODE_STANDBY	2
5123798Seschrock #define	IPMI_SUNOEM_LED_MODE_SLOW	3
5133798Seschrock #define	IPMI_SUNOEM_LED_MODE_FAST	4
5143798Seschrock 
5153798Seschrock /*
5163798Seschrock  * These functions take a SDR record and construct the appropriate form of the
5173798Seschrock  * above commands.
5183798Seschrock  */
5193798Seschrock extern int ipmi_sunoem_led_set(ipmi_handle_t *,
5203798Seschrock     ipmi_sdr_generic_locator_t *, uint8_t);
5213798Seschrock extern int ipmi_sunoem_led_get(ipmi_handle_t *,
5223798Seschrock     ipmi_sdr_generic_locator_t *, uint8_t *);
5233798Seschrock 
5243798Seschrock /*
5253798Seschrock  * Sun OEM uptime.  Note that the underlying command returns the uptime in big
5263798Seschrock  * endian form.  This wrapper automatically converts to the appropriate native
5273798Seschrock  * form.
5283798Seschrock  */
5293798Seschrock 
5303798Seschrock #define	IPMI_CMD_SUNOEM_UPTIME		0x08
5313798Seschrock 
5323798Seschrock extern int ipmi_sunoem_uptime(ipmi_handle_t *, uint32_t *, uint32_t *);
5333798Seschrock 
5343798Seschrock /*
5353798Seschrock  * Sun OEM FRU update.  The FRU information is managed through a generic
5363798Seschrock  * identifier, and then a type-specific data portion.  The wrapper function will
5373798Seschrock  * automatically fill in the data length field according to which type is
5383798Seschrock  * specified.
5393798Seschrock  */
5403798Seschrock 
5413798Seschrock #define	IPMI_CMD_SUNOEM_FRU_UPDATE	0x16
5423798Seschrock 
5433798Seschrock #define	IPMI_SUNOEM_FRU_DIMM	0x00
5443798Seschrock #define	IPMI_SUNOEM_FRU_CPU	0x01
5453798Seschrock #define	IPMI_SUNOEM_FRU_BIOS	0x02
5463798Seschrock #define	IPMI_SUNOEM_FRU_DISK	0x03
5473798Seschrock 
5483798Seschrock typedef struct ipmi_sunoem_fru {
5493798Seschrock 	uint8_t				isf_type;
5503798Seschrock 	uint8_t				isf_id;
5513798Seschrock 	uint8_t				isf_datalen;
5523798Seschrock 	union {
5533798Seschrock 		struct {
5543798Seschrock 			uint8_t		isf_data[128];
5553798Seschrock 		} dimm;
5563798Seschrock 		struct {
5573798Seschrock 			uint32_t	isf_thermtrip;
5583798Seschrock 			uint32_t	isf_eax;
5593798Seschrock 			char		isf_product[48];
5603798Seschrock 		} cpu;
5613798Seschrock 		struct {
5623798Seschrock 			char		isf_part[16];
5633798Seschrock 			char		isf_version[16];
5643798Seschrock 		} bios;
5653798Seschrock 		struct {
5663798Seschrock 			char		isf_manufacturer[16];
5673798Seschrock 			char		isf_model[28];
5683798Seschrock 			char		isf_serial[20];
5693798Seschrock 			char		isf_version[8];
5703798Seschrock 			char		isf_capacity[16];
5713798Seschrock 		} disk;
5723798Seschrock 	} isf_data;
5733798Seschrock } ipmi_sunoem_fru_t;
5743798Seschrock 
5753798Seschrock int ipmi_sunoem_update_fru(ipmi_handle_t *, ipmi_sunoem_fru_t *);
5763798Seschrock 
5773798Seschrock #pragma pack()
5783798Seschrock 
5793798Seschrock #ifdef	__cplusplus
5803798Seschrock }
5813798Seschrock #endif
5823798Seschrock 
5833798Seschrock #endif	/* _LIBIPMI_H */
584