xref: /illumos-gate/usr/src/lib/libipmi/common/libipmi.h (revision fc80c0dfb0c877aee828d778ea32b77fcf7b1ef4)
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  * The remaining functions are private to the implementation of the Sun ILOM
449  * service processor.  These function first check the manufacturer from the IPMI
450  * device ID, and will return EIPMI_NOT_SUPPORTED if attempted for non-Sun
451  * devices.
452  */
453 
454 /*
455  * Sun OEM LED requests.
456  */
457 
458 #define	IPMI_CMD_SUNOEM_LED_GET		0x21
459 #define	IPMI_CMD_SUNOEM_LED_SET		0x22
460 
461 typedef struct ipmi_cmd_sunoem_led_set {
462 #if defined(_BIT_FIELDS_LTOH)
463 	uint8_t		ic_sls_channel_msb:1;	/* device slave address */
464 	uint8_t		ic_sls_slaveaddr:7;	/* (from SDR record) */
465 #else
466 	uint8_t		ic_sls_slaveaddr:7;
467 	uint8_t		ic_sls_channel_msb:1;
468 #endif
469 	uint8_t		ic_sls_type;		/* led type */
470 #if defined(_BIT_FIELDS_LTOH)
471 	uint8_t		__reserved:1;		/* device access address */
472 	uint8_t		ic_sls_accessaddr:7;	/* (from SDR record) */
473 #else
474 	uint8_t		ic_sls_accessaddr:7;
475 	uint8_t		__reserved:1;
476 #endif
477 	uint8_t		ic_sls_hwinfo;		/* OEM hardware info */
478 	uint8_t		ic_sls_mode;		/* LED mode */
479 	uint8_t		ic_sls_force;		/* force direct access */
480 	uint8_t		ic_sls_role;		/* BMC authorization */
481 } ipmi_cmd_sunoem_led_set_t;
482 
483 typedef struct ipmi_cmd_sunoem_led_get {
484 #if defined(_BIT_FIELDS_LTOH)
485 	uint8_t		ic_slg_channel_msb:1;	/* device slave address */
486 	uint8_t		ic_slg_slaveaddr:7;	/* (from SDR record) */
487 #else
488 	uint8_t		ic_slg_slaveaddr:7;
489 	uint8_t		ic_slg_channel_msb:1;
490 #endif
491 	uint8_t		ic_slg_type;		/* led type */
492 #if defined(_BIT_FIELDS_LTOH)
493 	uint8_t		__reserved:1;		/* device access address */
494 	uint8_t		ic_slg_accessaddr:7;	/* (from SDR record) */
495 #else
496 	uint8_t		ic_slg_accessaddr:7;
497 	uint8_t		__reserved:1;
498 #endif
499 	uint8_t		ic_slg_hwinfo;		/* OEM hardware info */
500 	uint8_t		ic_slg_force;		/* force direct access */
501 } ipmi_cmd_sunoem_led_get_t;
502 
503 #define	IPMI_SUNOEM_LED_TYPE_OK2RM	0
504 #define	IPMI_SUNOEM_LED_TYPE_SERVICE	1
505 #define	IPMI_SUNOEM_LED_TYPE_ACT	2
506 #define	IPMI_SUNOEM_LED_TYPE_LOCATE	3
507 #define	IPMI_SUNOEM_LED_TYPE_ANY	0xFF
508 
509 #define	IPMI_SUNOEM_LED_MODE_OFF	0
510 #define	IPMI_SUNOEM_LED_MODE_ON		1
511 #define	IPMI_SUNOEM_LED_MODE_STANDBY	2
512 #define	IPMI_SUNOEM_LED_MODE_SLOW	3
513 #define	IPMI_SUNOEM_LED_MODE_FAST	4
514 
515 /*
516  * These functions take a SDR record and construct the appropriate form of the
517  * above commands.
518  */
519 extern int ipmi_sunoem_led_set(ipmi_handle_t *,
520     ipmi_sdr_generic_locator_t *, uint8_t);
521 extern int ipmi_sunoem_led_get(ipmi_handle_t *,
522     ipmi_sdr_generic_locator_t *, uint8_t *);
523 
524 /*
525  * Sun OEM uptime.  Note that the underlying command returns the uptime in big
526  * endian form.  This wrapper automatically converts to the appropriate native
527  * form.
528  */
529 
530 #define	IPMI_CMD_SUNOEM_UPTIME		0x08
531 
532 extern int ipmi_sunoem_uptime(ipmi_handle_t *, uint32_t *, uint32_t *);
533 
534 /*
535  * Sun OEM FRU update.  The FRU information is managed through a generic
536  * identifier, and then a type-specific data portion.  The wrapper function will
537  * automatically fill in the data length field according to which type is
538  * specified.
539  */
540 
541 #define	IPMI_CMD_SUNOEM_FRU_UPDATE	0x16
542 
543 #define	IPMI_SUNOEM_FRU_DIMM	0x00
544 #define	IPMI_SUNOEM_FRU_CPU	0x01
545 #define	IPMI_SUNOEM_FRU_BIOS	0x02
546 #define	IPMI_SUNOEM_FRU_DISK	0x03
547 
548 typedef struct ipmi_sunoem_fru {
549 	uint8_t				isf_type;
550 	uint8_t				isf_id;
551 	uint8_t				isf_datalen;
552 	union {
553 		struct {
554 			uint8_t		isf_data[128];
555 		} dimm;
556 		struct {
557 			uint32_t	isf_thermtrip;
558 			uint32_t	isf_eax;
559 			char		isf_product[48];
560 		} cpu;
561 		struct {
562 			char		isf_part[16];
563 			char		isf_version[16];
564 		} bios;
565 		struct {
566 			char		isf_manufacturer[16];
567 			char		isf_model[28];
568 			char		isf_serial[20];
569 			char		isf_version[8];
570 			char		isf_capacity[16];
571 		} disk;
572 	} isf_data;
573 } ipmi_sunoem_fru_t;
574 
575 int ipmi_sunoem_update_fru(ipmi_handle_t *, ipmi_sunoem_fru_t *);
576 
577 #pragma pack()
578 
579 #ifdef	__cplusplus
580 }
581 #endif
582 
583 #endif	/* _LIBIPMI_H */
584