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