1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
|
/*
* 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>
/*
* 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;
#if !defined(_BIT_FIELDS_LTOH) && !defined(_BIT_FIELDS_HTOL)
#error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
#endif
#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;
#if defined(_BIT_FIELDS_LTOH)
uint8_t id_dev_rev:4;
uint8_t __reserved:3;
uint8_t id_dev_sdrs:1;
#else
uint8_t id_dev_sdrs:1;
uint8_t __reserved:3;
uint8_t id_dev_rev:4;
#endif
#if defined(_BIT_FIELD_LTOH)
uint8_t id_firm_major:7;
uint8_t id_dev_available:1;
#else
uint8_t id_dev_available:1;
uint8_t id_firm_major:7;
#endif
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 */
#if defined(_BIT_FIELDS_LTOH)
uint8_t __reserved1:1;
uint8_t is_gl_accessaddr:7;
uint8_t is_gl_channel_msb:1;
uint8_t is_gl_slaveaddr:7;
uint8_t is_gl_bus:3;
uint8_t is_gl_lun:2;
uint8_t is_gl_channel:3;
#else
uint8_t is_gl_accessaddr:7;
uint8_t __reserved1:1;
uint8_t is_gl_slaveaddr:7;
uint8_t is_gl_channel_msb:1;
uint8_t is_gl_channel:3;
uint8_t is_gl_lun:2;
uint8_t is_gl_bus:3;
#endif
/* RECORD BODY BYTES */
#if defined(_BIT_FIELDS_LTOH)
uint8_t is_gl_span:3;
uint8_t __reserved2:5;
#else
uint8_t __reserved2:5;
uint8_t is_gl_span:3;
#endif
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;
#if defined(_BIT_FIELDS_LTOH)
uint8_t is_gl_idlen:6;
uint8_t is_gl_idtype:2;
#else
uint8_t is_gl_idtype:2;
uint8_t is_gl_idlen:6;
#endif
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 */
#if defined(_BIT_FIELDS_LTOH)
uint8_t __reserved1:1;
uint8_t is_fl_accessaddr:7;
#else
uint8_t is_fl_accessaddr:7;
uint8_t __reserved1:1;
#endif
union {
struct {
uint8_t _is_fl_devid;
} _logical;
struct {
#if defined(_BIT_FIELDS_LTOH)
uint8_t __reserved:1;
uint8_t _is_fl_slaveaddr:7;
#else
uint8_t _is_fl_slaveaddr:7;
uint8_t __reserved:1;
#endif
} _nonintelligent;
} _devid_or_slaveaddr;
#if defined(_BIT_FIELDS_LTOH)
uint8_t is_fl_bus:3;
uint8_t is_fl_lun:2;
uint8_t __reserved2:2;
uint8_t is_fl_logical:1;
uint8_t __reserved3:4;
uint8_t is_fl_channel:4;
#else
uint8_t is_fl_logical:1;
uint8_t __reserved2:2;
uint8_t is_fl_lun:2;
uint8_t is_fl_bus:3;
uint8_t is_fl_channel:4;
uint8_t __reserved3:4;
#endif
/* 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;
#if defined(_BIT_FIELDS_LTOH)
uint8_t is_fl_idlen:6;
uint8_t is_fl_idtype:2;
#else
uint8_t is_fl_idtype:2;
uint8_t is_fl_idlen:6;
#endif
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;
#if defined(_BIT_FIELDS_LTOH)
uint8_t __reserved1:5;
uint8_t isr_state_unavailable:1;
uint8_t isr_scanning_disabled:1;
uint8_t isr_event_disabled:1;
#else
uint8_t isr_event_disabled:1;
uint8_t isr_scanning_disabled:1;
uint8_t isr_state_unavailable:1;
uint8_t __reserved1:5;
#endif
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;
#if defined(_BIT_FIELDS_LTOH)
uint8_t iss_set_reading:1;
uint8_t __reserved:1;
uint8_t iss_deassrt_op:2;
uint8_t iss_assert_op:2;
uint8_t iss_data_bytes:2;
#else
uint8_t iss_data_bytes:2;
uint8_t iss_assert_op:2;
uint8_t iss_deassrt_op:2;
uint8_t __reserved:1;
uint8_t iss_set_reading:1;
#endif
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 *);
/*
* 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_CMD_SUNOEM_LED_GET 0x21
#define IPMI_CMD_SUNOEM_LED_SET 0x22
typedef struct ipmi_cmd_sunoem_led_set {
uint8_t ic_sls_devaddr; /* device slave address */
uint8_t ic_sls_type; /* led type */
uint8_t ic_sls_ctladdr; /* controller address */
uint8_t ic_sls_hwinfo; /* OEM hardware info */
uint8_t ic_sls_mode; /* LED mode */
uint8_t ic_sls_force; /* force direct access */
uint8_t ic_sls_role; /* BMC authorization */
} ipmi_cmd_sunoem_led_set_t;
typedef struct ipmi_cmd_sunoem_led_get {
uint8_t ic_slg_devaddr; /* device slave address */
uint8_t ic_slg_type; /* led type */
uint8_t ic_slg_ctladdr; /* controller address */
uint8_t ic_slg_hwinfo; /* OEM hardware info */
uint8_t ic_slg_force; /* force direct access */
} ipmi_cmd_sunoem_led_get_t;
#define IPMI_SUNOEM_LED_TYPE_OK2RM 0
#define IPMI_SUNOEM_LED_TYPE_SERVICE 1
#define IPMI_SUNOEM_LED_TYPE_ACT 2
#define IPMI_SUNOEM_LED_TYPE_LOCATE 3
#define IPMI_SUNOEM_LED_TYPE_ANY 0xFF
#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 */
|