1 /* 2 * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * Redistribution of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * Redistribution in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * Neither the name of Sun Microsystems, Inc. or the names of 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * This software is provided "AS IS," without a warranty of any kind. 20 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, 21 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A 22 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. 23 * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE 24 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING 25 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL 26 * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, 27 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR 28 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF 29 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 30 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 31 */ 32 33 #ifndef IPMI_SDR_H 34 #define IPMI_SDR_H 35 36 #if HAVE_CONFIG_H 37 # include <config.h> 38 #endif 39 40 #include <inttypes.h> 41 #include <math.h> 42 #include <ipmitool/bswap.h> 43 #include <ipmitool/ipmi.h> 44 #include <ipmitool/ipmi_entity.h> 45 46 int ipmi_sdr_main(struct ipmi_intf *, int, char **); 47 48 #define tos32(val, bits) ((val & ((1<<((bits)-1)))) ? (-((val) & (1<<((bits)-1))) | (val)) : (val)) 49 50 #if WORDS_BIGENDIAN 51 # define __TO_TOL(mtol) (uint16_t)(mtol & 0x3f) 52 # define __TO_M(mtol) (int16_t)(tos32((((mtol & 0xff00) >> 8) | ((mtol & 0xc0) << 2)), 10)) 53 # define __TO_B(bacc) (int32_t)(tos32((((bacc & 0xff000000) >> 24) | ((bacc & 0xc00000) >> 14)), 10)) 54 # define __TO_ACC(bacc) (uint32_t)(((bacc & 0x3f0000) >> 16) | ((bacc & 0xf000) >> 6)) 55 # define __TO_ACC_EXP(bacc) (uint32_t)((bacc & 0xc00) >> 10) 56 # define __TO_R_EXP(bacc) (int32_t)(tos32(((bacc & 0xf0) >> 4), 4)) 57 # define __TO_B_EXP(bacc) (int32_t)(tos32((bacc & 0xf), 4)) 58 #else 59 # define __TO_TOL(mtol) (uint16_t)(BSWAP_16(mtol) & 0x3f) 60 # define __TO_M(mtol) (int16_t)(tos32((((BSWAP_16(mtol) & 0xff00) >> 8) | ((BSWAP_16(mtol) & 0xc0) << 2)), 10)) 61 # define __TO_B(bacc) (int32_t)(tos32((((BSWAP_32(bacc) & 0xff000000) >> 24) | \ 62 ((BSWAP_32(bacc) & 0xc00000) >> 14)), 10)) 63 # define __TO_ACC(bacc) (uint32_t)(((BSWAP_32(bacc) & 0x3f0000) >> 16) | ((BSWAP_32(bacc) & 0xf000) >> 6)) 64 # define __TO_ACC_EXP(bacc) (uint32_t)((BSWAP_32(bacc) & 0xc00) >> 10) 65 # define __TO_R_EXP(bacc) (int32_t)(tos32(((BSWAP_32(bacc) & 0xf0) >> 4), 4)) 66 # define __TO_B_EXP(bacc) (int32_t)(tos32((BSWAP_32(bacc) & 0xf), 4)) 67 #endif 68 69 enum { 70 ANALOG_SENSOR, 71 DISCRETE_SENSOR, 72 }; 73 74 #define READING_UNAVAILABLE 0x20 75 #define SCANNING_DISABLED 0x40 76 #define EVENT_MSG_DISABLED 0x80 77 78 #define IS_READING_UNAVAILABLE(val) ((val) & READING_UNAVAILABLE) 79 #define IS_SCANNING_DISABLED(val) (!((val) & SCANNING_DISABLED)) 80 #define IS_EVENT_MSG_DISABLED(val) (!((val) & EVENT_MSG_DISABLED)) 81 82 #define GET_SDR_REPO_INFO 0x20 83 #define GET_SDR_ALLOC_INFO 0x21 84 85 #define SDR_SENSOR_STAT_LO_NC (1<<0) 86 #define SDR_SENSOR_STAT_LO_CR (1<<1) 87 #define SDR_SENSOR_STAT_LO_NR (1<<2) 88 #define SDR_SENSOR_STAT_HI_NC (1<<3) 89 #define SDR_SENSOR_STAT_HI_CR (1<<4) 90 #define SDR_SENSOR_STAT_HI_NR (1<<5) 91 92 #define GET_DEVICE_SDR_INFO 0x20 93 #define GET_DEVICE_SDR 0x21 94 #define GET_SENSOR_FACTORS 0x23 95 #define GET_SENSOR_FACTORS 0x23 96 #define SET_SENSOR_HYSTERESIS 0x24 97 #define GET_SENSOR_HYSTERESIS 0x25 98 #define SET_SENSOR_THRESHOLDS 0x26 99 #define GET_SENSOR_THRESHOLDS 0x27 100 #define SET_SENSOR_EVENT_ENABLE 0x28 101 #define GET_SENSOR_EVENT_ENABLE 0x29 102 #define GET_SENSOR_EVENT_STATUS 0x2b 103 #define GET_SENSOR_READING 0x2d 104 #define GET_SENSOR_TYPE 0x2f 105 106 #ifdef HAVE_PRAGMA_PACK 107 #pragma pack(1) 108 #endif 109 struct sdr_repo_info_rs { 110 uint8_t version; /* SDR version (51h) */ 111 uint16_t count; /* number of records */ 112 uint16_t free; /* free space in SDR */ 113 uint32_t add_stamp; /* last add timestamp */ 114 uint32_t erase_stamp; /* last del timestamp */ 115 uint8_t op_support; /* supported operations */ 116 } ATTRIBUTE_PACKING; 117 #ifdef HAVE_PRAGMA_PACK 118 #pragma pack(0) 119 #endif 120 121 #ifdef HAVE_PRAGMA_PACK 122 #pragma pack(1) 123 #endif 124 /* builtin (device) sdrs support */ 125 struct sdr_device_info_rs { 126 unsigned char count; /* number of records */ 127 unsigned char flags; /* flags */ 128 unsigned char popChangeInd[3]; /* free space in SDR */ 129 } ATTRIBUTE_PACKING; 130 #ifdef HAVE_PRAGMA_PACK 131 #pragma pack(0) 132 #endif 133 134 #ifdef HAVE_PRAGMA_PACK 135 #pragma pack(1) 136 #endif 137 #define GET_SDR_RESERVE_REPO 0x22 138 struct sdr_reserve_repo_rs { 139 uint16_t reserve_id; /* reservation ID */ 140 } ATTRIBUTE_PACKING; 141 #ifdef HAVE_PRAGMA_PACK 142 #pragma pack(0) 143 #endif 144 145 146 #ifdef HAVE_PRAGMA_PACK 147 #pragma pack(1) 148 #endif 149 #define GET_SDR 0x23 150 struct sdr_get_rq { 151 uint16_t reserve_id; /* reservation ID */ 152 uint16_t id; /* record ID */ 153 uint8_t offset; /* offset into SDR */ 154 #define GET_SDR_ENTIRE_RECORD 0xff 155 uint8_t length; /* length to read */ 156 } ATTRIBUTE_PACKING; 157 #ifdef HAVE_PRAGMA_PACK 158 #pragma pack(0) 159 #endif 160 161 #ifdef HAVE_PRAGMA_PACK 162 #pragma pack(1) 163 #endif 164 struct sdr_get_rs { 165 uint16_t next; /* next record id */ 166 uint16_t id; /* record ID */ 167 uint8_t version; /* SDR version (51h) */ 168 #define SDR_RECORD_TYPE_FULL_SENSOR 0x01 169 #define SDR_RECORD_TYPE_COMPACT_SENSOR 0x02 170 #define SDR_RECORD_TYPE_EVENTONLY_SENSOR 0x03 171 #define SDR_RECORD_TYPE_ENTITY_ASSOC 0x08 172 #define SDR_RECORD_TYPE_DEVICE_ENTITY_ASSOC 0x09 173 #define SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR 0x10 174 #define SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR 0x11 175 #define SDR_RECORD_TYPE_MC_DEVICE_LOCATOR 0x12 176 #define SDR_RECORD_TYPE_MC_CONFIRMATION 0x13 177 #define SDR_RECORD_TYPE_BMC_MSG_CHANNEL_INFO 0x14 178 #define SDR_RECORD_TYPE_OEM 0xc0 179 uint8_t type; /* record type */ 180 uint8_t length; /* remaining record bytes */ 181 } ATTRIBUTE_PACKING; 182 #ifdef HAVE_PRAGMA_PACK 183 #pragma pack(0) 184 #endif 185 186 #ifdef HAVE_PRAGMA_PACK 187 #pragma pack(1) 188 #endif 189 struct sdr_record_mask { 190 union { 191 struct { 192 uint16_t assert_event; /* assertion event mask */ 193 uint16_t deassert_event; /* de-assertion event mask */ 194 uint16_t read; /* discrete reading mask */ 195 } ATTRIBUTE_PACKING discrete; 196 struct { 197 #if WORDS_BIGENDIAN 198 uint16_t reserved:1; 199 uint16_t status_lnr:1; 200 uint16_t status_lcr:1; 201 uint16_t status_lnc:1; 202 uint16_t assert_unr_high:1; 203 uint16_t assert_unr_low:1; 204 uint16_t assert_ucr_high:1; 205 uint16_t assert_ucr_low:1; 206 uint16_t assert_unc_high:1; 207 uint16_t assert_unc_low:1; 208 uint16_t assert_lnr_high:1; 209 uint16_t assert_lnr_low:1; 210 uint16_t assert_lcr_high:1; 211 uint16_t assert_lcr_low:1; 212 uint16_t assert_lnc_high:1; 213 uint16_t assert_lnc_low:1; 214 #else 215 uint16_t assert_lnc_low:1; 216 uint16_t assert_lnc_high:1; 217 uint16_t assert_lcr_low:1; 218 uint16_t assert_lcr_high:1; 219 uint16_t assert_lnr_low:1; 220 uint16_t assert_lnr_high:1; 221 uint16_t assert_unc_low:1; 222 uint16_t assert_unc_high:1; 223 uint16_t assert_ucr_low:1; 224 uint16_t assert_ucr_high:1; 225 uint16_t assert_unr_low:1; 226 uint16_t assert_unr_high:1; 227 uint16_t status_lnc:1; 228 uint16_t status_lcr:1; 229 uint16_t status_lnr:1; 230 uint16_t reserved:1; 231 #endif 232 #if WORDS_BIGENDIAN 233 uint16_t reserved_2:1; 234 uint16_t status_unr:1; 235 uint16_t status_ucr:1; 236 uint16_t status_unc:1; 237 uint16_t deassert_unr_high:1; 238 uint16_t deassert_unr_low:1; 239 uint16_t deassert_ucr_high:1; 240 uint16_t deassert_ucr_low:1; 241 uint16_t deassert_unc_high:1; 242 uint16_t deassert_unc_low:1; 243 uint16_t deassert_lnr_high:1; 244 uint16_t deassert_lnr_low:1; 245 uint16_t deassert_lcr_high:1; 246 uint16_t deassert_lcr_low:1; 247 uint16_t deassert_lnc_high:1; 248 uint16_t deassert_lnc_low:1; 249 #else 250 uint16_t deassert_lnc_low:1; 251 uint16_t deassert_lnc_high:1; 252 uint16_t deassert_lcr_low:1; 253 uint16_t deassert_lcr_high:1; 254 uint16_t deassert_lnr_low:1; 255 uint16_t deassert_lnr_high:1; 256 uint16_t deassert_unc_low:1; 257 uint16_t deassert_unc_high:1; 258 uint16_t deassert_ucr_low:1; 259 uint16_t deassert_ucr_high:1; 260 uint16_t deassert_unr_low:1; 261 uint16_t deassert_unr_high:1; 262 uint16_t status_unc:1; 263 uint16_t status_ucr:1; 264 uint16_t status_unr:1; 265 uint16_t reserved_2:1; 266 #endif 267 union { 268 struct { 269 #if WORDS_BIGENDIAN /* settable threshold mask */ 270 uint16_t reserved:2; 271 uint16_t unr:1; 272 uint16_t ucr:1; 273 uint16_t unc:1; 274 uint16_t lnr:1; 275 uint16_t lcr:1; 276 uint16_t lnc:1; 277 /* padding lower 8 bits */ 278 uint16_t readable:8; 279 #else 280 uint16_t readable:8; 281 uint16_t lnc:1; 282 uint16_t lcr:1; 283 uint16_t lnr:1; 284 uint16_t unc:1; 285 uint16_t ucr:1; 286 uint16_t unr:1; 287 uint16_t reserved:2; 288 #endif 289 } ATTRIBUTE_PACKING set; 290 struct { 291 #if WORDS_BIGENDIAN /* readable threshold mask */ 292 /* padding upper 8 bits */ 293 uint16_t settable:8; 294 uint16_t reserved:2; 295 uint16_t unr:1; 296 uint16_t ucr:1; 297 uint16_t unc:1; 298 uint16_t lnr:1; 299 uint16_t lcr:1; 300 uint16_t lnc:1; 301 #else 302 uint16_t lnc:1; 303 uint16_t lcr:1; 304 uint16_t lnr:1; 305 uint16_t unc:1; 306 uint16_t ucr:1; 307 uint16_t unr:1; 308 uint16_t reserved:2; 309 uint16_t settable:8; 310 #endif 311 } ATTRIBUTE_PACKING read; 312 } ATTRIBUTE_PACKING; 313 } ATTRIBUTE_PACKING threshold; 314 } ATTRIBUTE_PACKING type; 315 } ATTRIBUTE_PACKING; 316 #ifdef HAVE_PRAGMA_PACK 317 #pragma pack(0) 318 #endif 319 320 #ifdef HAVE_PRAGMA_PACK 321 #pragma pack(1) 322 #endif 323 struct sdr_record_common_sensor { 324 struct { 325 uint8_t owner_id; 326 #if WORDS_BIGENDIAN 327 uint8_t channel:4; /* channel number */ 328 uint8_t __reserved:2; 329 uint8_t lun:2; /* sensor owner lun */ 330 #else 331 uint8_t lun:2; /* sensor owner lun */ 332 uint8_t __reserved:2; 333 uint8_t channel:4; /* channel number */ 334 #endif 335 uint8_t sensor_num; /* unique sensor number */ 336 } ATTRIBUTE_PACKING keys; 337 338 struct entity_id entity; 339 340 struct { 341 struct { 342 #if WORDS_BIGENDIAN 343 uint8_t __reserved:1; 344 uint8_t scanning:1; 345 uint8_t events:1; 346 uint8_t thresholds:1; 347 uint8_t hysteresis:1; 348 uint8_t type:1; 349 uint8_t event_gen:1; 350 uint8_t sensor_scan:1; 351 #else 352 uint8_t sensor_scan:1; 353 uint8_t event_gen:1; 354 uint8_t type:1; 355 uint8_t hysteresis:1; 356 uint8_t thresholds:1; 357 uint8_t events:1; 358 uint8_t scanning:1; 359 uint8_t __reserved:1; 360 #endif 361 } ATTRIBUTE_PACKING init; 362 struct { 363 #if WORDS_BIGENDIAN 364 uint8_t ignore:1; 365 uint8_t rearm:1; 366 uint8_t hysteresis:2; 367 uint8_t threshold:2; 368 uint8_t event_msg:2; 369 #else 370 uint8_t event_msg:2; 371 uint8_t threshold:2; 372 uint8_t hysteresis:2; 373 uint8_t rearm:1; 374 uint8_t ignore:1; 375 #endif 376 } ATTRIBUTE_PACKING capabilities; 377 uint8_t type; 378 } ATTRIBUTE_PACKING sensor; 379 380 uint8_t event_type; /* event/reading type code */ 381 382 struct sdr_record_mask mask; 383 384 struct { 385 #if WORDS_BIGENDIAN 386 uint8_t analog:2; 387 uint8_t rate:3; 388 uint8_t modifier:2; 389 uint8_t pct:1; 390 #else 391 uint8_t pct:1; 392 uint8_t modifier:2; 393 uint8_t rate:3; 394 uint8_t analog:2; 395 #endif 396 struct { 397 uint8_t base; 398 uint8_t modifier; 399 } ATTRIBUTE_PACKING type; 400 } ATTRIBUTE_PACKING unit; 401 } ATTRIBUTE_PACKING; 402 403 /* SDR Record Common Sensor header macros */ 404 #define IS_THRESHOLD_SENSOR(s) ((s)->event_type == 1) 405 #define UNITS_ARE_DISCRETE(s) ((s)->unit.analog == 3) 406 407 #ifdef HAVE_PRAGMA_PACK 408 #pragma pack(0) 409 #endif 410 411 #ifdef HAVE_PRAGMA_PACK 412 #pragma pack(1) 413 #endif 414 struct sdr_record_compact_sensor { 415 struct sdr_record_common_sensor cmn; 416 struct { 417 #if WORDS_BIGENDIAN 418 uint8_t __reserved:2; 419 uint8_t mod_type:2; 420 uint8_t count:4; 421 #else 422 uint8_t count:4; 423 uint8_t mod_type:2; 424 uint8_t __reserved:2; 425 #endif 426 #if WORDS_BIGENDIAN 427 uint8_t entity_inst:1; 428 uint8_t mod_offset:7; 429 #else 430 uint8_t mod_offset:7; 431 uint8_t entity_inst:1; 432 #endif 433 } ATTRIBUTE_PACKING share; 434 435 struct { 436 struct { 437 uint8_t positive; 438 uint8_t negative; 439 } ATTRIBUTE_PACKING hysteresis; 440 } ATTRIBUTE_PACKING threshold; 441 442 uint8_t __reserved[3]; 443 uint8_t oem; /* reserved for OEM use */ 444 uint8_t id_code; /* sensor ID string type/length code */ 445 uint8_t id_string[16]; /* sensor ID string bytes, only if id_code != 0 */ 446 } ATTRIBUTE_PACKING; 447 #ifdef HAVE_PRAGMA_PACK 448 #pragma pack(0) 449 #endif 450 451 #ifdef HAVE_PRAGMA_PACK 452 #pragma pack(1) 453 #endif 454 struct sdr_record_eventonly_sensor { 455 struct { 456 uint8_t owner_id; 457 #if WORDS_BIGENDIAN 458 uint8_t channel:4; /* channel number */ 459 uint8_t fru_owner:2; /* fru device owner lun */ 460 uint8_t lun:2; /* sensor owner lun */ 461 #else 462 uint8_t lun:2; /* sensor owner lun */ 463 uint8_t fru_owner:2; /* fru device owner lun */ 464 uint8_t channel:4; /* channel number */ 465 #endif 466 uint8_t sensor_num; /* unique sensor number */ 467 } ATTRIBUTE_PACKING keys; 468 469 struct entity_id entity; 470 471 uint8_t sensor_type; /* sensor type */ 472 uint8_t event_type; /* event/reading type code */ 473 474 struct { 475 #if WORDS_BIGENDIAN 476 uint8_t __reserved:2; 477 uint8_t mod_type:2; 478 uint8_t count:4; 479 #else 480 uint8_t count:4; 481 uint8_t mod_type:2; 482 uint8_t __reserved:2; 483 #endif 484 #if WORDS_BIGENDIAN 485 uint8_t entity_inst:1; 486 uint8_t mod_offset:7; 487 #else 488 uint8_t mod_offset:7; 489 uint8_t entity_inst:1; 490 #endif 491 } ATTRIBUTE_PACKING share; 492 493 uint8_t __reserved; 494 uint8_t oem; /* reserved for OEM use */ 495 uint8_t id_code; /* sensor ID string type/length code */ 496 uint8_t id_string[16]; /* sensor ID string bytes, only if id_code != 0 */ 497 498 } ATTRIBUTE_PACKING; 499 #ifdef HAVE_PRAGMA_PACK 500 #pragma pack(0) 501 #endif 502 503 #ifdef HAVE_PRAGMA_PACK 504 #pragma pack(1) 505 #endif 506 struct sdr_record_full_sensor { 507 struct sdr_record_common_sensor cmn; 508 509 #define SDR_SENSOR_L_LINEAR 0x00 510 #define SDR_SENSOR_L_LN 0x01 511 #define SDR_SENSOR_L_LOG10 0x02 512 #define SDR_SENSOR_L_LOG2 0x03 513 #define SDR_SENSOR_L_E 0x04 514 #define SDR_SENSOR_L_EXP10 0x05 515 #define SDR_SENSOR_L_EXP2 0x06 516 #define SDR_SENSOR_L_1_X 0x07 517 #define SDR_SENSOR_L_SQR 0x08 518 #define SDR_SENSOR_L_CUBE 0x09 519 #define SDR_SENSOR_L_SQRT 0x0a 520 #define SDR_SENSOR_L_CUBERT 0x0b 521 #define SDR_SENSOR_L_NONLINEAR 0x70 522 523 uint8_t linearization; /* 70h=non linear, 71h-7Fh=non linear, OEM */ 524 uint16_t mtol; /* M, tolerance */ 525 uint32_t bacc; /* accuracy, B, Bexp, Rexp */ 526 527 struct { 528 #if WORDS_BIGENDIAN 529 uint8_t __reserved:5; 530 uint8_t normal_min:1; /* normal min field specified */ 531 uint8_t normal_max:1; /* normal max field specified */ 532 uint8_t nominal_read:1; /* nominal reading field specified */ 533 #else 534 uint8_t nominal_read:1; /* nominal reading field specified */ 535 uint8_t normal_max:1; /* normal max field specified */ 536 uint8_t normal_min:1; /* normal min field specified */ 537 uint8_t __reserved:5; 538 #endif 539 } ATTRIBUTE_PACKING analog_flag; 540 541 uint8_t nominal_read; /* nominal reading, raw value */ 542 uint8_t normal_max; /* normal maximum, raw value */ 543 uint8_t normal_min; /* normal minimum, raw value */ 544 uint8_t sensor_max; /* sensor maximum, raw value */ 545 uint8_t sensor_min; /* sensor minimum, raw value */ 546 547 struct { 548 struct { 549 uint8_t non_recover; 550 uint8_t critical; 551 uint8_t non_critical; 552 } ATTRIBUTE_PACKING upper; 553 struct { 554 uint8_t non_recover; 555 uint8_t critical; 556 uint8_t non_critical; 557 } ATTRIBUTE_PACKING lower; 558 struct { 559 uint8_t positive; 560 uint8_t negative; 561 } ATTRIBUTE_PACKING hysteresis; 562 } ATTRIBUTE_PACKING threshold; 563 uint8_t __reserved[2]; 564 uint8_t oem; /* reserved for OEM use */ 565 uint8_t id_code; /* sensor ID string type/length code */ 566 uint8_t id_string[16]; /* sensor ID string bytes, only if id_code != 0 */ 567 } ATTRIBUTE_PACKING; 568 #ifdef HAVE_PRAGMA_PACK 569 #pragma pack(0) 570 #endif 571 572 #ifdef HAVE_PRAGMA_PACK 573 #pragma pack(1) 574 #endif 575 struct sdr_record_mc_locator { 576 uint8_t dev_slave_addr; 577 #if WORDS_BIGENDIAN 578 uint8_t __reserved2:4; 579 uint8_t channel_num:4; 580 #else 581 uint8_t channel_num:4; 582 uint8_t __reserved2:4; 583 #endif 584 #if WORDS_BIGENDIAN 585 uint8_t pwr_state_notif:3; 586 uint8_t __reserved3:1; 587 uint8_t global_init:4; 588 #else 589 uint8_t global_init:4; 590 uint8_t __reserved3:1; 591 uint8_t pwr_state_notif:3; 592 #endif 593 uint8_t dev_support; 594 uint8_t __reserved4[3]; 595 struct entity_id entity; 596 uint8_t oem; 597 uint8_t id_code; 598 uint8_t id_string[16]; 599 } ATTRIBUTE_PACKING; 600 #ifdef HAVE_PRAGMA_PACK 601 #pragma pack(0) 602 #endif 603 604 struct sdr_record_fru_locator { 605 uint8_t dev_slave_addr; 606 uint8_t device_id; 607 #if WORDS_BIGENDIAN 608 uint8_t logical:1; 609 uint8_t __reserved2:2; 610 uint8_t lun:2; 611 uint8_t bus:3; 612 #else 613 uint8_t bus:3; 614 uint8_t lun:2; 615 uint8_t __reserved2:2; 616 uint8_t logical:1; 617 #endif 618 #if WORDS_BIGENDIAN 619 uint8_t channel_num:4; 620 uint8_t __reserved3:4; 621 #else 622 uint8_t __reserved3:4; 623 uint8_t channel_num:4; 624 #endif 625 uint8_t __reserved4; 626 uint8_t dev_type; 627 uint8_t dev_type_modifier; 628 struct entity_id entity; 629 uint8_t oem; 630 uint8_t id_code; 631 uint8_t id_string[16]; 632 } ATTRIBUTE_PACKING; 633 #ifdef HAVE_PRAGMA_PACK 634 #pragma pack(0) 635 #endif 636 637 #ifdef HAVE_PRAGMA_PACK 638 #pragma pack(1) 639 #endif 640 struct sdr_record_generic_locator { 641 uint8_t dev_access_addr; 642 uint8_t dev_slave_addr; 643 #if WORDS_BIGENDIAN 644 uint8_t channel_num:3; 645 uint8_t lun:2; 646 uint8_t bus:3; 647 #else 648 uint8_t bus:3; 649 uint8_t lun:2; 650 uint8_t channel_num:3; 651 #endif 652 #if WORDS_BIGENDIAN 653 uint8_t addr_span:3; 654 uint8_t __reserved1:5; 655 #else 656 uint8_t __reserved1:5; 657 uint8_t addr_span:3; 658 #endif 659 uint8_t __reserved2; 660 uint8_t dev_type; 661 uint8_t dev_type_modifier; 662 struct entity_id entity; 663 uint8_t oem; 664 uint8_t id_code; 665 uint8_t id_string[16]; 666 } ATTRIBUTE_PACKING; 667 #ifdef HAVE_PRAGMA_PACK 668 #pragma pack(0) 669 #endif 670 671 #ifdef HAVE_PRAGMA_PACK 672 #pragma pack(1) 673 #endif 674 struct sdr_record_entity_assoc { 675 struct entity_id entity; /* container entity ID and instance */ 676 struct { 677 #if WORDS_BIGENDIAN 678 uint8_t isrange:1; 679 uint8_t islinked:1; 680 uint8_t isaccessable:1; 681 uint8_t __reserved:5; 682 #else 683 uint8_t __reserved:5; 684 uint8_t isaccessable:1; 685 uint8_t islinked:1; 686 uint8_t isrange:1; 687 #endif 688 } flags; 689 uint8_t entity_id_1; /* entity ID 1 | range 1 entity */ 690 uint8_t entity_inst_1; /* entity inst 1 | range 1 first instance */ 691 uint8_t entity_id_2; /* entity ID 2 | range 1 entity */ 692 uint8_t entity_inst_2; /* entity inst 2 | range 1 last instance */ 693 uint8_t entity_id_3; /* entity ID 3 | range 2 entity */ 694 uint8_t entity_inst_3; /* entity inst 3 | range 2 first instance */ 695 uint8_t entity_id_4; /* entity ID 4 | range 2 entity */ 696 uint8_t entity_inst_4; /* entity inst 4 | range 2 last instance */ 697 } ATTRIBUTE_PACKING; 698 #ifdef HAVE_PRAGMA_PACK 699 #pragma pack(0) 700 #endif 701 702 struct sdr_record_oem { 703 uint8_t *data; 704 int data_len; 705 }; 706 707 /* 708 * The Get SDR Repository Info response structure 709 * From table 33-3 of the IPMI v2.0 spec 710 */ 711 #ifdef HAVE_PRAGMA_PACK 712 #pragma pack(1) 713 #endif 714 struct get_sdr_repository_info_rsp { 715 uint8_t sdr_version; 716 uint8_t record_count_lsb; 717 uint8_t record_count_msb; 718 uint8_t free_space[2]; 719 uint8_t most_recent_addition_timestamp[4]; 720 uint8_t most_recent_erase_timestamp[4]; 721 #if WORDS_BIGENDIAN 722 uint8_t overflow_flag:1; 723 uint8_t modal_update_support:2; 724 uint8_t __reserved1:1; 725 uint8_t delete_sdr_supported:1; 726 uint8_t partial_add_sdr_supported:1; 727 uint8_t reserve_sdr_repository_supported:1; 728 uint8_t get_sdr_repository_allo_info_supported:1; 729 #else 730 uint8_t get_sdr_repository_allo_info_supported:1; 731 uint8_t reserve_sdr_repository_supported:1; 732 uint8_t partial_add_sdr_supported:1; 733 uint8_t delete_sdr_supported:1; 734 uint8_t __reserved1:1; 735 uint8_t modal_update_support:2; 736 uint8_t overflow_flag:1; 737 #endif 738 } ATTRIBUTE_PACKING; 739 #ifdef HAVE_PRAGMA_PACK 740 #pragma pack(0) 741 #endif 742 743 struct ipmi_sdr_iterator { 744 uint16_t reservation; 745 int total; 746 int next; 747 int use_built_in; 748 }; 749 750 #ifdef HAVE_PRAGMA_PACK 751 #pragma pack(1) 752 #endif 753 struct sdr_record_list { 754 uint16_t id; 755 uint8_t version; 756 uint8_t type; 757 uint8_t length; 758 uint8_t *raw; 759 struct sdr_record_list *next; 760 union { 761 struct sdr_record_common_sensor *common; 762 struct sdr_record_full_sensor *full; 763 struct sdr_record_compact_sensor *compact; 764 struct sdr_record_eventonly_sensor *eventonly; 765 struct sdr_record_generic_locator *genloc; 766 struct sdr_record_fru_locator *fruloc; 767 struct sdr_record_mc_locator *mcloc; 768 struct sdr_record_entity_assoc *entassoc; 769 struct sdr_record_oem *oem; 770 } ATTRIBUTE_PACKING record; 771 } ATTRIBUTE_PACKING; 772 #ifdef HAVE_PRAGMA_PACK 773 #pragma pack(0) 774 #endif 775 776 777 /* unit description codes (IPMI v1.5 section 37.16) */ 778 #define UNIT_MAX 0x90 779 static const char *unit_desc[] __attribute__ ((unused)) = { 780 "unspecified", 781 "degrees C", "degrees F", "degrees K", 782 "Volts", "Amps", "Watts", "Joules", 783 "Coulombs", "VA", "Nits", 784 "lumen", "lux", "Candela", 785 "kPa", "PSI", "Newton", 786 "CFM", "RPM", "Hz", 787 "microsecond", "millisecond", "second", "minute", "hour", 788 "day", "week", "mil", "inches", "feet", "cu in", "cu feet", 789 "mm", "cm", "m", "cu cm", "cu m", "liters", "fluid ounce", 790 "radians", "steradians", "revolutions", "cycles", 791 "gravities", "ounce", "pound", "ft-lb", "oz-in", "gauss", 792 "gilberts", "henry", "millihenry", "farad", "microfarad", 793 "ohms", "siemens", "mole", "becquerel", "PPM", "reserved", 794 "Decibels", "DbA", "DbC", "gray", "sievert", 795 "color temp deg K", "bit", "kilobit", "megabit", "gigabit", 796 "byte", "kilobyte", "megabyte", "gigabyte", "word", "dword", 797 "qword", "line", "hit", "miss", "retry", "reset", 798 "overflow", "underrun", "collision", "packets", "messages", 799 "characters", "error", "correctable error", "uncorrectable error",}; 800 801 /* sensor type codes (IPMI v1.5 table 36.3) 802 / Updated to v2.0 Table 42-3, Sensor Type Codes */ 803 #define SENSOR_TYPE_MAX 0x2C 804 static const char *sensor_type_desc[] __attribute__ ((unused)) = { 805 "reserved", 806 "Temperature", "Voltage", "Current", "Fan", 807 "Physical Security", "Platform Security", "Processor", 808 "Power Supply", "Power Unit", "Cooling Device", "Other", 809 "Memory", "Drive Slot / Bay", "POST Memory Resize", 810 "System Firmwares", "Event Logging Disabled", "Watchdog1", 811 "System Event", "Critical Interrupt", "Button", 812 "Module / Board", "Microcontroller", "Add-in Card", 813 "Chassis", "Chip Set", "Other FRU", "Cable / Interconnect", 814 "Terminator", "System Boot Initiated", "Boot Error", 815 "OS Boot", "OS Critical Stop", "Slot / Connector", 816 "System ACPI Power State", "Watchdog2", "Platform Alert", 817 "Entity Presence", "Monitor ASIC", "LAN", 818 "Management Subsys Health", "Battery", "Session Audit", 819 "Version Change", "FRU State" }; 820 821 struct sensor_reading { 822 char s_id[17]; /* name of the sensor */ 823 struct sdr_record_full_sensor *full; 824 struct sdr_record_compact_sensor *compact; 825 uint8_t s_reading_valid; /* read value valididity */ 826 uint8_t s_scanning_disabled; /* read of value disabled */ 827 uint8_t s_reading_unavailable; /* read value unavailable */ 828 uint8_t s_reading; /* value which was read */ 829 uint8_t s_data2; /* data2 value read */ 830 uint8_t s_data3; /* data3 value read */ 831 uint8_t s_has_analog_value; /* sensor has analog value */ 832 double s_a_val; /* read value converted to analog */ 833 char s_a_str[16]; /* analog value as a string */ 834 const char *s_a_units; /* analog value units string */ 835 }; 836 837 /* 838 * Determine if bridging is necessary to address a sensor at the given 839 * address (_addr) and (_chan) via the interface (_intf). 840 * 841 * If the sensor is being addressed on channel zero, it resides on 842 * IPMB-0. If the interface target IPMB-0 address is exactly the same as 843 * the sensor address then the sensor resides on the target IPMB-0 844 * so we don't need extra levels of bridging to address the sensor. 845 * Or 846 * If the sensor target address and channel match the interface target address 847 * and channel then there is no extra levels of bridging required. 848 * 849 * Note: 850 * The target IPMB-0 address is the address of the SDR repository that was 851 * accessed using the user specified bridging command line arguments. 852 * Access to any sensor on the target IPMB-0 can be addressed using the 853 * target address and transit address in the interface. 854 */ 855 #define BRIDGE_TO_SENSOR(_intf, _addr, _chan) \ 856 ( !((_chan == 0 && _intf->target_ipmb_addr && \ 857 _intf->target_ipmb_addr == _addr) || \ 858 (_addr == _intf->target_addr && _chan == _intf->target_channel)) ) 859 860 861 struct ipmi_sdr_iterator *ipmi_sdr_start(struct ipmi_intf *intf, 862 int use_builtin); 863 struct sdr_get_rs *ipmi_sdr_get_next_header(struct ipmi_intf *intf, 864 struct ipmi_sdr_iterator *i); 865 uint8_t *ipmi_sdr_get_record(struct ipmi_intf *intf, struct sdr_get_rs *header, 866 struct ipmi_sdr_iterator *i); 867 void ipmi_sdr_end(struct ipmi_intf *intf, struct ipmi_sdr_iterator *i); 868 int ipmi_sdr_print_sdr(struct ipmi_intf *intf, uint8_t type); 869 870 int ipmi_sdr_print_name_from_rawentry(struct ipmi_intf *intf,uint16_t id, 871 uint8_t type,uint8_t * raw); 872 int ipmi_sdr_print_rawentry(struct ipmi_intf *intf, uint8_t type, uint8_t * raw, 873 int len); 874 int ipmi_sdr_print_listentry(struct ipmi_intf *intf, 875 struct sdr_record_list *entry); 876 void ipmi_sdr_print_sensor_hysteresis(struct sdr_record_common_sensor *sensor, 877 struct sdr_record_full_sensor *full, 878 uint8_t hysteresis_value, 879 const char *hdrstr); 880 const char *ipmi_sdr_get_unit_string(uint8_t pct, uint8_t type, 881 uint8_t base, uint8_t modifier); 882 struct sensor_reading * 883 ipmi_sdr_read_sensor_value(struct ipmi_intf *intf, 884 struct sdr_record_common_sensor *sensor, 885 uint8_t sdr_record_type, int precision); 886 const char *ipmi_sdr_get_thresh_status(struct sensor_reading *sr, 887 const char *invalidstr); 888 const char *ipmi_sdr_get_status(int, const char *, uint8_t stat); 889 double sdr_convert_sensor_tolerance(struct sdr_record_full_sensor *sensor, 890 uint8_t val); 891 double sdr_convert_sensor_reading(struct sdr_record_full_sensor *sensor, 892 uint8_t val); 893 double sdr_convert_sensor_hysterisis(struct sdr_record_full_sensor *sensor, 894 uint8_t val); 895 uint8_t sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor *sensor, 896 double val); 897 struct ipmi_rs *ipmi_sdr_get_sensor_reading(struct ipmi_intf *intf, 898 uint8_t sensor); 899 struct ipmi_rs *ipmi_sdr_get_sensor_reading_ipmb(struct ipmi_intf *intf, 900 uint8_t sensor, 901 uint8_t target, 902 uint8_t lun, 903 uint8_t channel); 904 struct ipmi_rs *ipmi_sdr_get_sensor_thresholds(struct ipmi_intf *intf, 905 uint8_t sensor, 906 uint8_t target, uint8_t lun, uint8_t channel); 907 struct ipmi_rs *ipmi_sdr_get_sensor_hysteresis(struct ipmi_intf *intf, 908 uint8_t sensor, 909 uint8_t target, uint8_t lun, uint8_t channel); 910 const char *ipmi_sdr_get_sensor_type_desc(const uint8_t type); 911 int ipmi_sdr_get_reservation(struct ipmi_intf *intf, int use_builtin, 912 uint16_t * reserve_id); 913 914 int ipmi_sdr_print_sensor_eventonly(struct ipmi_intf *intf, 915 struct sdr_record_eventonly_sensor *sensor); 916 int ipmi_sdr_print_sensor_generic_locator(struct ipmi_intf *intf, 917 struct sdr_record_generic_locator 918 *fru); 919 int ipmi_sdr_print_sensor_fru_locator(struct ipmi_intf *intf, 920 struct sdr_record_fru_locator *fru); 921 int ipmi_sdr_print_sensor_mc_locator(struct ipmi_intf *intf, 922 struct sdr_record_mc_locator *mc); 923 int ipmi_sdr_print_sensor_entity_assoc(struct ipmi_intf *intf, 924 struct sdr_record_entity_assoc *assoc); 925 926 struct sdr_record_list *ipmi_sdr_find_sdr_byentity(struct ipmi_intf *intf, 927 struct entity_id *entity); 928 struct sdr_record_list *ipmi_sdr_find_sdr_bynumtype(struct ipmi_intf *intf, 929 uint16_t gen_id, uint8_t num, uint8_t type); 930 struct sdr_record_list *ipmi_sdr_find_sdr_bysensortype(struct ipmi_intf *intf, 931 uint8_t type); 932 struct sdr_record_list *ipmi_sdr_find_sdr_byid(struct ipmi_intf *intf, 933 char *id); 934 struct sdr_record_list *ipmi_sdr_find_sdr_bytype(struct ipmi_intf *intf, 935 uint8_t type); 936 int ipmi_sdr_list_cache(struct ipmi_intf *intf); 937 int ipmi_sdr_list_cache_fromfile(struct ipmi_intf *intf, const char *ifile); 938 void ipmi_sdr_list_empty(struct ipmi_intf *intf); 939 int ipmi_sdr_print_info(struct ipmi_intf *intf); 940 void ipmi_sdr_print_discrete_state(const char *desc, uint8_t sensor_type, 941 uint8_t event_type, uint8_t state1, 942 uint8_t state2); 943 void ipmi_sdr_print_discrete_state_mini(const char *header, const char *separator, 944 uint8_t sensor_type, uint8_t event_type, 945 uint8_t state1, uint8_t state2); 946 int ipmi_sdr_print_sensor_event_status(struct ipmi_intf *intf, 947 uint8_t sensor_num, uint8_t sensor_type, 948 uint8_t event_type, int numeric_fmt, 949 uint8_t target, uint8_t lun, uint8_t channel); 950 int ipmi_sdr_print_sensor_event_enable(struct ipmi_intf *intf, 951 uint8_t sensor_num, uint8_t sensor_type, 952 uint8_t event_type, int numeric_fmt, 953 uint8_t target, uint8_t lun, uint8_t channel); 954 955 #endif /* IPMI_SDR_H */ 956