xref: /titanic_41/usr/src/lib/libipmi/common/libipmi.h (revision 0cfdb6036e046270988a17ac442e4d717d426a44)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef	_LIBIPMI_H
27 #define	_LIBIPMI_H
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 #include <sys/bmc_intf.h>
32 #include <sys/byteorder.h>
33 
34 /*
35  * Private interfaces for communicating with attached services over IPMI.  This
36  * library is designed for system software communicating with Sun-supported
37  * service processors over /dev/bmc.  It is not a generic IPMI library.
38  *
39  * Documentation references refer to "Intelligent Platform Management Interface
40  * Specification Second Generation v2.0", document revision 1.0 with Februrary
41  * 15, 2006 Markup from "IPMI v2.0 Addenda, Errata, and Clarifications Revision
42  * 3".
43  */
44 
45 #ifdef	__cplusplus
46 extern "C" {
47 #endif
48 
49 typedef struct ipmi_handle ipmi_handle_t;
50 
51 #if !defined(_BIT_FIELDS_LTOH) && !defined(_BIT_FIELDS_HTOL)
52 #error  One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
53 #endif
54 
55 #pragma pack(1)
56 
57 /*
58  * Basic netfn definitions.  See section 5.1.
59  */
60 #define	IPMI_NETFN_APP			BMC_NETFN_APP
61 #define	IPMI_NETFN_STORAGE		BMC_NETFN_STORAGE
62 #define	IPMI_NETFN_SE			BMC_NETFN_SE
63 #define	IPMI_NETFN_OEM			0x2e
64 
65 /*
66  * Error definitions
67  */
68 #define	EIPMI_BASE	2000
69 
70 enum {
71 	EIPMI_NOMEM = EIPMI_BASE,	/* memory allocation failure */
72 	EIPMI_BMC_OPEN_FAILED,		/* failed to open /dev/bmc */
73 	EIPMI_BMC_PUTMSG,		/* putmsg() failed */
74 	EIPMI_BMC_GETMSG,		/* getmsg() failed */
75 	EIPMI_BMC_RESPONSE,		/* response from /dev/bmc failed */
76 	EIPMI_INVALID_COMMAND,		/* invalid command */
77 	EIPMI_COMMAND_TIMEOUT,		/* command timeout */
78 	EIPMI_DATA_LENGTH_EXCEEDED,	/* maximum data length exceeded */
79 	EIPMI_SEND_FAILED,		/* failed to send BMC request */
80 	EIPMI_UNSPECIFIED,		/* unspecified error */
81 	EIPMI_UNKNOWN,			/* unknown error */
82 	EIPMI_BAD_RESPONSE,		/* received unexpected response */
83 	EIPMI_BAD_RESPONSE_LENGTH,	/* unexpected response length */
84 	EIPMI_INVALID_RESERVATION,	/* invalid reservation */
85 	EIPMI_NOT_PRESENT,		/* requested entity not present */
86 	EIPMI_INVALID_REQUEST,		/* malformed request */
87 	EIPMI_BUSY,			/* SP is busy */
88 	EIPMI_NOSPACE,			/* SP is out of space */
89 	EIPMI_UNAVAILABLE,		/* SP is present but unavailable */
90 	EIPMI_ACCESS			/* insufficient privileges */
91 };
92 
93 /*
94  * Basic library functions.
95  *
96  * The ipmi_handle is the primary interface to the library.  The library itself
97  * is not MT-safe, but it is safe within a single handle.  Multithreaded clients
98  * should either open multiple handles, or otherwise synchronize access to the
99  * same handle.
100  *
101  * There is a single command response buffer that is stored with the handle, to
102  * simplify memory management in the caller.  The memory referenced by a command
103  * response is only valid until the next command is issued.  The caller is
104  * responsible for making a copy of the response if it is needed.
105  */
106 extern ipmi_handle_t *ipmi_open(int *, char **);
107 extern void ipmi_close(ipmi_handle_t *);
108 
109 extern int ipmi_errno(ipmi_handle_t *);
110 extern const char *ipmi_errmsg(ipmi_handle_t *);
111 
112 /*
113  * Raw requests.  See section 5.
114  */
115 typedef struct ipmi_cmd {
116 	uint8_t		ic_netfn:6;
117 	uint8_t		ic_lun:2;
118 	uint8_t		ic_cmd;
119 	uint16_t	ic_dlen;
120 	void		*ic_data;
121 } ipmi_cmd_t;
122 
123 extern ipmi_cmd_t *ipmi_send(ipmi_handle_t *, ipmi_cmd_t *);
124 
125 /*
126  * Retrieve basic information about the IPMI device.  See section 20.1 "Get
127  * Device ID Command".
128  */
129 #define	IPMI_CMD_GET_DEVICEID		0x01
130 
131 typedef struct ipmi_deviceid {
132 	uint8_t		id_devid;
133 #if defined(_BIT_FIELDS_LTOH)
134 	uint8_t		id_dev_rev:4;
135 	uint8_t		__reserved:3;
136 	uint8_t		id_dev_sdrs:1;
137 #else
138 	uint8_t		id_dev_sdrs:1;
139 	uint8_t		__reserved:3;
140 	uint8_t		id_dev_rev:4;
141 #endif
142 #if defined(_BIT_FIELDS_LTOH)
143 	uint8_t		id_firm_major:7;
144 	uint8_t		id_dev_available:1;
145 #else
146 	uint8_t		id_dev_available:1;
147 	uint8_t		id_firm_major:7;
148 #endif
149 	uint8_t		id_firm_minor;
150 	uint8_t		id_ipmi_rev;
151 	uint8_t		id_dev_support;
152 	uint8_t		id_manufacturer[3];
153 	uint16_t	id_product;
154 } ipmi_deviceid_t;
155 
156 #define	IPMI_OEM_SUN	0x2a
157 
158 ipmi_deviceid_t *ipmi_get_deviceid(ipmi_handle_t *);
159 
160 #define	ipmi_devid_manufacturer(dp)		\
161 	((dp)->id_manufacturer[0] |		\
162 	((dp)->id_manufacturer[1] << 8) |	\
163 	((dp)->id_manufacturer[2] << 16))
164 
165 /*
166  * SDR (Sensor Device Record) requests.  A cache of the current SDR repository
167  * is kept as part of the IPMI handle and updated when necessary.  Routines to
168  * access the raw SDR repository are also provided.
169  */
170 
171 /*
172  * Reserve repository command.  See section 33.11.
173  */
174 #define	IPMI_CMD_RESERVE_SDR_REPOSITORY	0x22
175 
176 /*
177  * Get SDR command.  See section 33.12.  This command accesses the raw SDR
178  * repository.  Clients can also use the lookup functions to retrieve a
179  * particular SDR record by name.
180  *
181  * The list of possible types is indicated in the sub-chapters of section 43.
182  */
183 typedef struct ipmi_sdr {
184 	uint16_t	is_id;
185 	uint8_t		is_version;
186 	uint8_t		is_type;
187 	uint8_t		is_length;
188 	uint8_t		is_record[1];
189 } ipmi_sdr_t;
190 #define	IPMI_CMD_GET_SDR		0x23
191 
192 #define	IPMI_SDR_FIRST			0x0000
193 #define	IPMI_SDR_LAST			0xFFFF
194 
195 extern ipmi_sdr_t *ipmi_sdr_get(ipmi_handle_t *, uint16_t, uint16_t *);
196 
197 /*
198  * Generic Device Locator Record.  See section 43.7.
199  */
200 
201 #define	IPMI_SDR_TYPE_GENERIC_LOCATOR		0x10
202 
203 typedef struct ipmi_sdr_generic_locator {
204 	/* RECORD KEY BYTES */
205 #if defined(_BIT_FIELDS_LTOH)
206 	uint8_t		__reserved1:1;
207 	uint8_t		is_gl_accessaddr:7;
208 	uint8_t		is_gl_channel_msb:1;
209 	uint8_t		is_gl_slaveaddr:7;
210 	uint8_t		is_gl_bus:3;
211 	uint8_t		is_gl_lun:2;
212 	uint8_t		is_gl_channel:3;
213 #else
214 	uint8_t		is_gl_accessaddr:7;
215 	uint8_t		__reserved1:1;
216 	uint8_t		is_gl_slaveaddr:7;
217 	uint8_t		is_gl_channel_msb:1;
218 	uint8_t		is_gl_channel:3;
219 	uint8_t		is_gl_lun:2;
220 	uint8_t		is_gl_bus:3;
221 #endif
222 	/* RECORD BODY BYTES */
223 #if defined(_BIT_FIELDS_LTOH)
224 	uint8_t		is_gl_span:3;
225 	uint8_t		__reserved2:5;
226 #else
227 	uint8_t		__reserved2:5;
228 	uint8_t		is_gl_span:3;
229 #endif
230 	uint8_t		__reserved3;
231 	uint8_t		is_gl_type;
232 	uint8_t		is_gl_modifier;
233 	uint8_t		is_gl_entity;
234 	uint8_t		is_gl_instance;
235 	uint8_t		is_gl_oem;
236 #if defined(_BIT_FIELDS_LTOH)
237 	uint8_t		is_gl_idlen:6;
238 	uint8_t		is_gl_idtype:2;
239 #else
240 	uint8_t		is_gl_idtype:2;
241 	uint8_t		is_gl_idlen:6;
242 #endif
243 	char		is_gl_idstring[1];
244 } ipmi_sdr_generic_locator_t;
245 
246 /*
247  * FRU Device Locator Record.  See section 43.8.
248  */
249 
250 #define	IPMI_SDR_TYPE_FRU_LOCATOR		0x11
251 
252 typedef struct ipmi_sdr_fru_locator {
253 	/* RECORD KEY BYTES */
254 #if defined(_BIT_FIELDS_LTOH)
255 	uint8_t		__reserved1:1;
256 	uint8_t		is_fl_accessaddr:7;
257 #else
258 	uint8_t		is_fl_accessaddr:7;
259 	uint8_t		__reserved1:1;
260 #endif
261 	union {
262 		struct {
263 			uint8_t	_is_fl_devid;
264 		} _logical;
265 		struct {
266 #if defined(_BIT_FIELDS_LTOH)
267 			uint8_t	__reserved:1;
268 			uint8_t	_is_fl_slaveaddr:7;
269 #else
270 			uint8_t	_is_fl_slaveaddr:7;
271 			uint8_t	__reserved:1;
272 #endif
273 		} _nonintelligent;
274 	} _devid_or_slaveaddr;
275 #if defined(_BIT_FIELDS_LTOH)
276 	uint8_t		is_fl_bus:3;
277 	uint8_t		is_fl_lun:2;
278 	uint8_t		__reserved2:2;
279 	uint8_t		is_fl_logical:1;
280 	uint8_t		__reserved3:4;
281 	uint8_t		is_fl_channel:4;
282 #else
283 	uint8_t		is_fl_logical:1;
284 	uint8_t		__reserved2:2;
285 	uint8_t		is_fl_lun:2;
286 	uint8_t		is_fl_bus:3;
287 	uint8_t		is_fl_channel:4;
288 	uint8_t		__reserved3:4;
289 #endif
290 	/* RECORD BODY BYTES */
291 	uint8_t		__reserved4;
292 	uint8_t		is_fl_type;
293 	uint8_t		is_fl_modifier;
294 	uint8_t		is_fl_entity;
295 	uint8_t		is_fl_instance;
296 	uint8_t		is_fl_oem;
297 #if defined(_BIT_FIELDS_LTOH)
298 	uint8_t		is_fl_idlen:6;
299 	uint8_t		is_fl_idtype:2;
300 #else
301 	uint8_t		is_fl_idtype:2;
302 	uint8_t		is_fl_idlen:6;
303 #endif
304 	char		is_fl_idstring[1];
305 } ipmi_sdr_fru_locator_t;
306 
307 #define	is_fl_devid	_devid_or_slaveaddr._logical._is_fl_devid
308 #define	is_fl_slaveaddr	_devid_or_slaveaddr._nonintelligent._is_fl_slaveaddr
309 
310 /*
311  * The remaining SDR types do not have an associated structure, yet.
312  */
313 #define	IPMI_SDR_TYPE_FULL_SENSOR		0x01
314 #define	IPMI_SDR_TYPE_COMPACT_SENSOR		0x02
315 #define	IPMI_SDR_TYPE_EVENT_ONLY		0x03
316 #define	IPMI_SDR_TYPE_ENTITY_ASSOCIATION	0x08
317 #define	IPMI_SDR_TYPE_DEVICE_RELATIVE		0x09
318 #define	IPMI_SDR_TYPE_MANAGEMENT_DEVICE		0x12
319 #define	IPMI_SDR_TYPE_MANAGEMENT_CONFIRMATION	0x13
320 #define	IPMI_SDR_TYPE_BMC_MESSAGE_CHANNEL	0x14
321 #define	IPMI_SDR_TYPE_OEM			0xC0
322 
323 /*
324  * Lookup the given sensor type by name.  These functions automatically read in
325  * and cache the complete SDR repository.
326  */
327 extern ipmi_sdr_fru_locator_t *ipmi_sdr_lookup_fru(ipmi_handle_t *,
328     const char *);
329 extern ipmi_sdr_generic_locator_t *ipmi_sdr_lookup_generic(ipmi_handle_t *,
330     const char *);
331 
332 /*
333  * Get Sensor Reading.  See section 35.14.
334  */
335 
336 #define	IPMI_CMD_GET_SENSOR_READING	0x2d
337 
338 typedef struct ipmi_sensor_reading {
339 	uint8_t		isr_reading;
340 #if defined(_BIT_FIELDS_LTOH)
341 	uint8_t		__reserved1:5;
342 	uint8_t		isr_state_unavailable:1;
343 	uint8_t		isr_scanning_disabled:1;
344 	uint8_t		isr_event_disabled:1;
345 #else
346 	uint8_t		isr_event_disabled:1;
347 	uint8_t		isr_scanning_disabled:1;
348 	uint8_t		isr_state_unavailable:1;
349 	uint8_t		__reserved1:5;
350 #endif
351 	uint16_t	isr_state;
352 } ipmi_sensor_reading_t;
353 
354 extern ipmi_sensor_reading_t *ipmi_get_sensor_reading(ipmi_handle_t *, uint8_t);
355 
356 /*
357  * Set Sensor Reading.  See section 35.14.
358  */
359 #define	IPMI_CMD_SET_SENSOR_READING	0x30
360 
361 #define	IPMI_SENSOR_OP_CLEAR	0x3	/* clear '0' bits */
362 #define	IPMI_SENSOR_OP_SET	0x2	/* set '1' bits */
363 #define	IPMI_SENSOR_OP_EXACT	0x1	/* set bits exactly */
364 
365 typedef struct ipmi_set_sensor_reading {
366 	uint8_t		iss_id;
367 #if defined(_BIT_FIELDS_LTOH)
368 	uint8_t		iss_set_reading:1;
369 	uint8_t		__reserved:1;
370 	uint8_t		iss_deassrt_op:2;
371 	uint8_t		iss_assert_op:2;
372 	uint8_t		iss_data_bytes:2;
373 #else
374 	uint8_t		iss_data_bytes:2;
375 	uint8_t		iss_assert_op:2;
376 	uint8_t		iss_deassrt_op:2;
377 	uint8_t		__reserved:1;
378 	uint8_t		iss_set_reading:1;
379 #endif
380 	uint8_t		iss_sensor_reading;
381 	uint16_t	iss_assert_state;	/* optional */
382 	uint16_t	iss_deassert_state;	/* optional */
383 	uint8_t		iss_event_data1;	/* optional */
384 	uint8_t		iss_event_data2;	/* optional */
385 	uint8_t		iss_event_data3;	/* optional */
386 } ipmi_set_sensor_reading_t;
387 
388 extern int ipmi_set_sensor_reading(ipmi_handle_t *,
389     ipmi_set_sensor_reading_t *);
390 
391 /*
392  * These IPMI message id/opcodes are documented in Appendix G in the IPMI spec.
393  *
394  * Payloads for these two commands are described in Sections 34.1 and 34.2 of
395  * the spec, respectively.
396  */
397 #define	IPMI_CMD_GET_FRU_INV_AREA	0x10
398 #define	IPMI_CMD_READ_FRU_DATA		0x11
399 
400 /*
401  * Structs to hold the FRU Common Header and the FRU Product Info Area, as
402  * described in the IPMI Platform Management FRU Information Storage
403  * Definition (v1.1).
404  */
405 typedef struct ipmi_fru_hdr
406 {
407 	uint8_t		ifh_format;
408 	uint8_t		ifh_int_use_off;
409 	uint8_t		ifh_chassis_info_off;
410 	uint8_t		ifh_board_info_off;
411 	uint8_t		ifh_product_info_off;
412 	uint8_t		ifh_multi_rec_off;
413 	uint8_t		ifh_pad;
414 	uint8_t		ifh_chksum;
415 } ipmi_fru_hdr_t;
416 
417 /*
418  * Because only 6 bits are used to specify the length of each field in the FRU
419  * product and board info areas, the biggest string we would ever need to hold
420  * would be 63 chars plus a NULL.
421  */
422 #define	FRU_INFO_MAXLEN	64
423 
424 typedef struct ipmi_fru_brd_info
425 {
426 	char	ifbi_manuf_date[3];
427 	char	ifbi_manuf_name[FRU_INFO_MAXLEN];
428 	char	ifbi_board_name[FRU_INFO_MAXLEN];
429 	char	ifbi_product_serial[FRU_INFO_MAXLEN];
430 	char	ifbi_part_number[FRU_INFO_MAXLEN];
431 } ipmi_fru_brd_info_t;
432 
433 typedef struct ipmi_fru_prod_info
434 {
435 	char	ifpi_manuf_name[FRU_INFO_MAXLEN];
436 	char	ifpi_product_name[FRU_INFO_MAXLEN];
437 	char	ifpi_part_number[FRU_INFO_MAXLEN];
438 	char	ifpi_product_version[FRU_INFO_MAXLEN];
439 	char	ifpi_product_serial[FRU_INFO_MAXLEN];
440 	char	ifpi_asset_tag[FRU_INFO_MAXLEN];
441 } ipmi_fru_prod_info_t;
442 
443 int ipmi_fru_read(ipmi_handle_t *, ipmi_sdr_fru_locator_t *, char **);
444 int ipmi_fru_parse_board(ipmi_handle_t *, char *, ipmi_fru_brd_info_t *);
445 int ipmi_fru_parse_product(ipmi_handle_t *, char *, ipmi_fru_prod_info_t *);
446 
447 /*
448  * User management.  The raw functions are private to libipmi, and only the
449  * higher level abstraction (ipmi_user_t) is exported to consumers of the
450  * library.
451  */
452 
453 #define	IPMI_USER_PRIV_CALLBACK		0x1
454 #define	IPMI_USER_PRIV_USER		0x2
455 #define	IPMI_USER_PRIV_OPERATOR		0x3
456 #define	IPMI_USER_PRIV_ADMIN		0x4
457 #define	IPMI_USER_PRIV_OEM		0x5
458 #define	IPMI_USER_PRIV_NONE		0xf
459 
460 typedef struct ipmi_user {
461 	uint8_t		iu_uid;
462 	char		*iu_name;
463 	boolean_t	iu_enabled;
464 	boolean_t	iu_ipmi_msg_enable;
465 	boolean_t	iu_link_auth_enable;
466 	uint8_t		iu_priv;
467 	struct ipmi_user *iu_next;
468 } ipmi_user_t;
469 
470 extern int ipmi_user_iter(ipmi_handle_t *,
471     int (*)(ipmi_user_t *, void *), void *);
472 extern ipmi_user_t *ipmi_user_lookup_name(ipmi_handle_t *, const char *);
473 extern ipmi_user_t *ipmi_user_lookup_id(ipmi_handle_t *, uint8_t);
474 extern int ipmi_user_set_password(ipmi_handle_t *, uint8_t, const char *);
475 
476 /*
477  * The remaining functions are private to the implementation of the Sun ILOM
478  * service processor.  These function first check the manufacturer from the IPMI
479  * device ID, and will return EIPMI_NOT_SUPPORTED if attempted for non-Sun
480  * devices.
481  */
482 
483 /*
484  * Sun OEM LED requests.
485  */
486 
487 #define	IPMI_CMD_SUNOEM_LED_GET		0x21
488 #define	IPMI_CMD_SUNOEM_LED_SET		0x22
489 
490 typedef struct ipmi_cmd_sunoem_led_set {
491 #if defined(_BIT_FIELDS_LTOH)
492 	uint8_t		ic_sls_channel_msb:1;	/* device slave address */
493 	uint8_t		ic_sls_slaveaddr:7;	/* (from SDR record) */
494 #else
495 	uint8_t		ic_sls_slaveaddr:7;
496 	uint8_t		ic_sls_channel_msb:1;
497 #endif
498 	uint8_t		ic_sls_type;		/* led type */
499 #if defined(_BIT_FIELDS_LTOH)
500 	uint8_t		__reserved:1;		/* device access address */
501 	uint8_t		ic_sls_accessaddr:7;	/* (from SDR record) */
502 #else
503 	uint8_t		ic_sls_accessaddr:7;
504 	uint8_t		__reserved:1;
505 #endif
506 	uint8_t		ic_sls_hwinfo;		/* OEM hardware info */
507 	uint8_t		ic_sls_mode;		/* LED mode */
508 	uint8_t		ic_sls_force;		/* force direct access */
509 	uint8_t		ic_sls_role;		/* BMC authorization */
510 } ipmi_cmd_sunoem_led_set_t;
511 
512 typedef struct ipmi_cmd_sunoem_led_get {
513 #if defined(_BIT_FIELDS_LTOH)
514 	uint8_t		ic_slg_channel_msb:1;	/* device slave address */
515 	uint8_t		ic_slg_slaveaddr:7;	/* (from SDR record) */
516 #else
517 	uint8_t		ic_slg_slaveaddr:7;
518 	uint8_t		ic_slg_channel_msb:1;
519 #endif
520 	uint8_t		ic_slg_type;		/* led type */
521 #if defined(_BIT_FIELDS_LTOH)
522 	uint8_t		__reserved:1;		/* device access address */
523 	uint8_t		ic_slg_accessaddr:7;	/* (from SDR record) */
524 #else
525 	uint8_t		ic_slg_accessaddr:7;
526 	uint8_t		__reserved:1;
527 #endif
528 	uint8_t		ic_slg_hwinfo;		/* OEM hardware info */
529 	uint8_t		ic_slg_force;		/* force direct access */
530 } ipmi_cmd_sunoem_led_get_t;
531 
532 #define	IPMI_SUNOEM_LED_TYPE_OK2RM	0
533 #define	IPMI_SUNOEM_LED_TYPE_SERVICE	1
534 #define	IPMI_SUNOEM_LED_TYPE_ACT	2
535 #define	IPMI_SUNOEM_LED_TYPE_LOCATE	3
536 #define	IPMI_SUNOEM_LED_TYPE_ANY	0xFF
537 
538 #define	IPMI_SUNOEM_LED_MODE_OFF	0
539 #define	IPMI_SUNOEM_LED_MODE_ON		1
540 #define	IPMI_SUNOEM_LED_MODE_STANDBY	2
541 #define	IPMI_SUNOEM_LED_MODE_SLOW	3
542 #define	IPMI_SUNOEM_LED_MODE_FAST	4
543 
544 /*
545  * These functions take a SDR record and construct the appropriate form of the
546  * above commands.
547  */
548 extern int ipmi_sunoem_led_set(ipmi_handle_t *,
549     ipmi_sdr_generic_locator_t *, uint8_t);
550 extern int ipmi_sunoem_led_get(ipmi_handle_t *,
551     ipmi_sdr_generic_locator_t *, uint8_t *);
552 
553 /*
554  * Sun OEM uptime.  Note that the underlying command returns the uptime in big
555  * endian form.  This wrapper automatically converts to the appropriate native
556  * form.
557  */
558 
559 #define	IPMI_CMD_SUNOEM_UPTIME		0x08
560 
561 extern int ipmi_sunoem_uptime(ipmi_handle_t *, uint32_t *, uint32_t *);
562 
563 /*
564  * Sun OEM FRU update.  The FRU information is managed through a generic
565  * identifier, and then a type-specific data portion.  The wrapper function will
566  * automatically fill in the data length field according to which type is
567  * specified.
568  */
569 
570 #define	IPMI_CMD_SUNOEM_FRU_UPDATE	0x16
571 
572 #define	IPMI_SUNOEM_FRU_DIMM	0x00
573 #define	IPMI_SUNOEM_FRU_CPU	0x01
574 #define	IPMI_SUNOEM_FRU_BIOS	0x02
575 #define	IPMI_SUNOEM_FRU_DISK	0x03
576 
577 typedef struct ipmi_sunoem_fru {
578 	uint8_t				isf_type;
579 	uint8_t				isf_id;
580 	uint8_t				isf_datalen;
581 	union {
582 		struct {
583 			uint8_t		isf_data[128];
584 		} dimm;
585 		struct {
586 			uint32_t	isf_thermtrip;
587 			uint32_t	isf_eax;
588 			char		isf_product[48];
589 		} cpu;
590 		struct {
591 			char		isf_part[16];
592 			char		isf_version[16];
593 		} bios;
594 		struct {
595 			char		isf_manufacturer[16];
596 			char		isf_model[28];
597 			char		isf_serial[20];
598 			char		isf_version[8];
599 			char		isf_capacity[16];
600 		} disk;
601 	} isf_data;
602 } ipmi_sunoem_fru_t;
603 
604 int ipmi_sunoem_update_fru(ipmi_handle_t *, ipmi_sunoem_fru_t *);
605 
606 #pragma pack()
607 
608 #ifdef	__cplusplus
609 }
610 #endif
611 
612 #endif	/* _LIBIPMI_H */
613