1 /* 2 * ipmi_fru.h 3 * 4 * internal IPMI interface for FRUs 5 * 6 * Author: MontaVista Software, Inc. 7 * Corey Minyard <minyard@mvista.com> 8 * source@mvista.com 9 * 10 * Copyright 2003 MontaVista Software Inc. 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU Lesser General Public License 14 * as published by the Free Software Foundation; either version 2 of 15 * the License, or (at your option) any later version. 16 * 17 * 18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 26 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 27 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * You should have received a copy of the GNU Lesser General Public 30 * License along with this program; if not, write to the Free 31 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 32 */ 33 34 #ifndef OPENIPMI_FRU_INTERNAL_H 35 #define OPENIPMI_FRU_INTERNAL_H 36 37 #include <OpenIPMI/ipmi_fru.h> 38 #include <OpenIPMI/ipmi_err.h> 39 #include <OpenIPMI/os_handler.h> 40 41 os_handler_t *i_ipmi_fru_get_os_handler(ipmi_fru_t *fru); 42 43 /* The callbacks for FRU multi-record OEM handler, to decode the multi-record 44 and get individual field. 45 ipmi_fru_multi_record_oem_decoder_cb(): record is the raw binary multi-record 46 record_len is the length of this raw binary multi-record, 47 the doceded OEM FRU information is outputted and stored in *explain_data_p. 48 ipmi_fru_get_multi_record_oem_field_handler_cb(): this callback is called 49 when user call ipmi_fru_multi_record_get_field(). Please refer to the 50 comments for ipmi_fru_multi_record_get_field(). 51 ipmi_fru_multi_record_free_explain_data_cb(): this callback is used to free 52 the OEM FRU specific data structures. 53 54 */ 55 56 /* Free the data in the node. */ 57 typedef void (*ipmi_fru_oem_node_cb)(ipmi_fru_node_t *node); 58 59 typedef int (*ipmi_fru_oem_node_get_field_cb) 60 (ipmi_fru_node_t *node, 61 unsigned int index, 62 const char **name, 63 enum ipmi_fru_data_type_e *dtype, 64 int *intval, 65 time_t *time, 66 double *floatval, 67 char **data, 68 unsigned int *data_len, 69 ipmi_fru_node_t **sub_node); 70 71 typedef int (*ipmi_fru_oem_node_set_field_cb) 72 (ipmi_fru_node_t *node, 73 unsigned int index, 74 enum ipmi_fru_data_type_e dtype, 75 int intval, 76 time_t time, 77 double floatval, 78 char *data, 79 unsigned int data_len); 80 81 typedef int (*ipmi_fru_oem_node_settable_cb) 82 (ipmi_fru_node_t *node, 83 unsigned int index); 84 85 typedef int (*ipmi_fru_oem_node_subtype_cb) 86 (ipmi_fru_node_t *node, 87 enum ipmi_fru_data_type_e *dtype); 88 89 typedef int (*ipmi_fru_oem_node_enum_val_cb)(ipmi_fru_node_t *node, 90 unsigned int index, 91 int *pos, 92 int *nextpos, 93 const char **data); 94 95 ipmi_fru_node_t *i_ipmi_fru_node_alloc(ipmi_fru_t *fru); 96 97 void *i_ipmi_fru_node_get_data(ipmi_fru_node_t *node); 98 void i_ipmi_fru_node_set_data(ipmi_fru_node_t *node, void *data); 99 void *i_ipmi_fru_node_get_data2(ipmi_fru_node_t *node); 100 void i_ipmi_fru_node_set_data2(ipmi_fru_node_t *node, void *data2); 101 102 void i_ipmi_fru_node_set_destructor(ipmi_fru_node_t *node, 103 ipmi_fru_oem_node_cb destroy); 104 void i_ipmi_fru_node_set_get_field(ipmi_fru_node_t *node, 105 ipmi_fru_oem_node_get_field_cb get_field); 106 void i_ipmi_fru_node_set_set_field(ipmi_fru_node_t *node, 107 ipmi_fru_oem_node_set_field_cb set_field); 108 void i_ipmi_fru_node_set_settable(ipmi_fru_node_t *node, 109 ipmi_fru_oem_node_settable_cb settable); 110 void i_ipmi_fru_node_set_get_subtype(ipmi_fru_node_t *node, 111 ipmi_fru_oem_node_subtype_cb get_subtype); 112 void i_ipmi_fru_node_set_get_enum(ipmi_fru_node_t *node, 113 ipmi_fru_oem_node_enum_val_cb get_enum); 114 115 /* Get the root node of a multi-record. Note that the root record 116 must not be an array. Note that you cannot keep a copy of the fru 117 pointer around after this call returns; it will be unlocked and 118 could go away after this returns. */ 119 typedef int (*ipmi_fru_oem_multi_record_get_root_node_cb) 120 (ipmi_fru_t *fru, 121 unsigned int mr_rec_num, 122 unsigned int manufacturer_id, 123 unsigned char record_type_id, 124 unsigned char *mr_data, 125 unsigned int mr_data_len, 126 void *cb_data, 127 const char **name, 128 ipmi_fru_node_t **node); 129 130 /* Register/deregister a multi-record handler. Note that if the 131 record type id is < 0xc0 (not OEM) then the manufacturer id does 132 not matter. */ 133 int i_ipmi_fru_register_multi_record_oem_handler 134 (unsigned int manufacturer_id, 135 unsigned char record_type_id, 136 ipmi_fru_oem_multi_record_get_root_node_cb get_root, 137 void *cb_data); 138 139 int i_ipmi_fru_deregister_multi_record_oem_handler 140 (unsigned int manufacturer_id, 141 unsigned char record_type_id); 142 143 void i_ipmi_fru_lock(ipmi_fru_t *fru); 144 void i_ipmi_fru_unlock(ipmi_fru_t *fru); 145 146 /* You must be holding the fru lock to call this. */ 147 void i_ipmi_fru_ref_nolock(ipmi_fru_t *fru); 148 149 /* 150 * Some specialized FRU data repositories have protection against 151 * multiple readers/writers to keep them from colliding. The model 152 * here is similar to the other parts of IPMI. You have a timestamp 153 * that tells the last time the repository changed. On reading, the 154 * code will check the timestamp before and after to make sure the 155 * data hasn't changed while being written. There is a lock for 156 * writers. The code will lock (prepare to write), check the 157 * timestamp to make sure another writer has not modified, then write, 158 * then unlock and commit (write complete). Note that you can have 159 * the reader timestamp without the lock, or the lock without the 160 * timestamp. 161 * 162 * You can also override the function that sends the write message. 163 * this function will get the data as formatted for a normal FRU 164 * write. 165 */ 166 typedef void (*i_ipmi_fru_timestamp_cb)(ipmi_fru_t *fru, 167 ipmi_domain_t *domain, 168 int err, 169 uint32_t timestamp); 170 typedef void (*i_ipmi_fru_op_cb)(ipmi_fru_t *fru, 171 ipmi_domain_t *domain, 172 int err); 173 174 typedef int (*i_ipmi_fru_get_timestamp_cb)(ipmi_fru_t *fru, 175 ipmi_domain_t *domain, 176 i_ipmi_fru_timestamp_cb handler); 177 typedef int (*i_ipmi_fru_prepare_write_cb)(ipmi_fru_t *fru, 178 ipmi_domain_t *domain, 179 uint32_t timestamp, 180 i_ipmi_fru_op_cb done); 181 typedef int (*i_ipmi_fru_write_cb)(ipmi_fru_t *fru, 182 ipmi_domain_t *domain, 183 unsigned char *data, 184 unsigned int data_len, 185 i_ipmi_fru_op_cb done); 186 typedef int (*i_ipmi_fru_complete_write_cb)(ipmi_fru_t *fru, 187 ipmi_domain_t *domain, 188 int abort, 189 uint32_t timestamp, 190 i_ipmi_fru_op_cb done); 191 192 int i_ipmi_fru_set_get_timestamp_handler(ipmi_fru_t *fru, 193 i_ipmi_fru_get_timestamp_cb handler); 194 int i_ipmi_fru_set_prepare_write_handler(ipmi_fru_t *fru, 195 i_ipmi_fru_prepare_write_cb handler); 196 int i_ipmi_fru_set_write_handler(ipmi_fru_t *fru, 197 i_ipmi_fru_write_cb handler); 198 int i_ipmi_fru_set_complete_write_handler(ipmi_fru_t *fru, 199 i_ipmi_fru_complete_write_cb handler); 200 201 typedef void (*i_ipmi_fru_setup_data_clean_cb)(ipmi_fru_t *fru, void *data); 202 void i_ipmi_fru_set_setup_data(ipmi_fru_t *fru, 203 void *data, 204 i_ipmi_fru_setup_data_clean_cb cleanup); 205 void *i_ipmi_fru_get_setup_data(ipmi_fru_t *fru); 206 207 void i_ipmi_fru_get_addr(ipmi_fru_t *fru, 208 ipmi_addr_t *addr, 209 unsigned int *addr_len); 210 211 212 /* Add a record telling that a specific area of the FRU data needs to 213 be written. Called from the write handler. */ 214 int i_ipmi_fru_new_update_record(ipmi_fru_t *fru, 215 unsigned int offset, 216 unsigned int length); 217 218 /* Get/set the fru-type secific data. Note that the cleanup_recs 219 function will be called on any rec_data. The right way to set this 220 data is to set the rec data then set your ops. */ 221 void *i_ipmi_fru_get_rec_data(ipmi_fru_t *fru); 222 void i_ipmi_fru_set_rec_data(ipmi_fru_t *fru, void *rec_data); 223 224 /* Get a pointer to the fru data and the length. Only valid during 225 decoding and writing. */ 226 void *i_ipmi_fru_get_data_ptr(ipmi_fru_t *fru); 227 unsigned int i_ipmi_fru_get_data_len(ipmi_fru_t *fru); 228 229 /* Get a debug name for the FRU */ 230 char *i_ipmi_fru_get_iname(ipmi_fru_t *fru); 231 232 /* Misc data about the FRU. */ 233 unsigned int i_ipmi_fru_get_fetch_mask(ipmi_fru_t *fru); 234 int i_ipmi_fru_is_normal_fru(ipmi_fru_t *fru); 235 void i_ipmi_fru_set_is_normal_fru(ipmi_fru_t *fru, int val); 236 237 /* 238 * Interface between the generic FRU code and the specific FRU 239 * decoders. 240 */ 241 242 typedef void (*ipmi_fru_void_op)(ipmi_fru_t *fru); 243 typedef int (*ipmi_fru_err_op)(ipmi_fru_t *fru); 244 typedef int (*ipmi_fru_get_root_node_op)(ipmi_fru_t *fru, 245 const char **name, 246 ipmi_fru_node_t **rnode); 247 248 /* Add a function to cleanup the FRU record data (free all the memory) 249 as the FRU is destroyed. */ 250 void i_ipmi_fru_set_op_cleanup_recs(ipmi_fru_t *fru, ipmi_fru_void_op op); 251 252 /* Called when a write operations completes successfully, to clear out 253 all the write information. */ 254 void i_ipmi_fru_set_op_write_complete(ipmi_fru_t *fru, ipmi_fru_void_op op); 255 256 /* Called to copy all the changed data into the FRU block of data and 257 add update records for the changed data. */ 258 void i_ipmi_fru_set_op_write(ipmi_fru_t *fru, ipmi_fru_err_op op); 259 260 /* Get the root node for the user to decode. */ 261 void i_ipmi_fru_set_op_get_root_node(ipmi_fru_t *fru, 262 ipmi_fru_get_root_node_op op); 263 264 /* Register a decoder for FRU data. The provided function should 265 return success if the FRU is supported and can be decoded properly, 266 ENOSYS if the FRU information doesn't match the format, or anything 267 else for invalid FRU data. It should register the nodes */ 268 int i_ipmi_fru_register_decoder(ipmi_fru_err_op op); 269 int i_ipmi_fru_deregister_decoder(ipmi_fru_err_op op); 270 271 /*********************************************************************** 272 * 273 * Table-driven multirecord FRU handling. 274 * 275 * This makes describing the contents of multi-record data much easier 276 * that writing your own field handling routines. 277 * 278 * You describe your data by filling in layout structures. Three 279 * different structures exist: 280 * 281 * struct - Defines a record node. The top-level of a multi record 282 * is always a record node, and arrays always consist of record 283 * nodes. 284 * 285 * item - These are individual data items (floats, ints, strings, 286 * etc). You supply an array of these in a struct layout to describe 287 * the basic items in a record. 288 * 289 * array - A variable-sized set of record nodes, items (or other 290 * arrays, though that is not yet implemented). You can insert 291 * elements in the array and delete them. 292 * 293 * NOTE: you cannot have an array of bitfields. 294 * 295 **********************************************************************/ 296 typedef struct ipmi_mr_struct_layout_s ipmi_mr_struct_layout_t; 297 typedef struct ipmi_mr_item_layout_s ipmi_mr_item_layout_t; 298 typedef struct ipmi_mr_array_layout_s ipmi_mr_array_layout_t; 299 300 typedef struct ipmi_mr_item_info_s ipmi_mr_item_info_t; 301 typedef struct ipmi_mr_struct_info_s ipmi_mr_struct_info_t; 302 typedef struct ipmi_mr_array_info_s ipmi_mr_array_info_t; 303 304 typedef struct ipmi_mr_offset_s ipmi_mr_offset_t; 305 306 /* The offset structure is in all info structures as the first item, 307 it is sort of the "base type" of all the info types. If an item is 308 contained within another item (like an item or structure in an 309 array, or an array or item in a structure), then the contained item 310 will have a pointer to the parent item's offset structure. If an 311 item is in an array, the "next" pointer of this structure will 312 point to the next item's offset structure in the list. 313 314 All this complexity is used to keep the offsets and lengths sane. 315 If you change an item's size (adding or deleting an element in an 316 array) you must change the length of all the parent items and the 317 offset of all succeeding items for the changed item and all items 318 succeeding all parents. The fact that the offset is relative to 319 the parent means you have to go to all the parents to calculate the 320 real offset, but you don't have to go down arrays to recalculate 321 offsets. */ 322 struct ipmi_mr_offset_s { 323 /* Items that contain this item, if we adjust this items length we 324 need to adjust the parent's lengths as well. */ 325 ipmi_mr_offset_t *parent; 326 327 /* Items after this one that need their offset adjusted if we 328 alter this item's length. */ 329 ipmi_mr_offset_t *next; 330 331 /* Offset from the beginning of the *parent*, not the whole 332 structure. */ 333 uint8_t offset; 334 335 uint8_t length; 336 }; 337 338 /* Stores in the data2 information for the root FRU node. */ 339 typedef struct ipmi_mr_fru_info_s { 340 ipmi_fru_t *fru; 341 unsigned int mr_rec_num; 342 } ipmi_mr_fru_info_t; 343 344 /* A convenience structure for passing to the item get and set 345 routines. */ 346 typedef struct ipmi_mr_getset_s { 347 ipmi_mr_item_layout_t *layout; 348 ipmi_mr_offset_t *offset; 349 unsigned char *rdata; 350 ipmi_mr_fru_info_t *finfo; 351 } ipmi_mr_getset_t; 352 353 /* Information about an array. */ 354 struct ipmi_mr_array_info_s { 355 ipmi_mr_offset_t offset; 356 uint8_t count; /* Number of array elements. */ 357 uint8_t nr_after; /* Number of arrays after me. */ 358 ipmi_mr_array_layout_t *layout; /* Array layout */ 359 360 /* An array of ipmi_mr_struct_info_t, ipmi_mr_array_info_t, or 361 ipmi_mr_item_info_t, depending on layout functions. */ 362 ipmi_mr_offset_t **items; 363 }; 364 365 /* Information about a single item. Note that this is only used in 366 arrays; structures use a different mechanism to manage items so 367 they can store their data more efficiently. */ 368 struct ipmi_mr_item_info_s 369 { 370 ipmi_mr_offset_t offset; 371 uint8_t len; 372 ipmi_mr_item_layout_t *layout; 373 unsigned char *data; 374 }; 375 376 /* Information about a structure. The "data" field holds the data for 377 all items in the structure and the layout start offsets are used to 378 calculated how to get the individual items. */ 379 struct ipmi_mr_struct_info_s 380 { 381 ipmi_mr_offset_t offset; 382 ipmi_mr_struct_layout_t *layout; 383 unsigned char *data; 384 ipmi_mr_array_info_t *arrays; 385 }; 386 387 /* A descriptor for a single item. This an appear in a structure item 388 list or in as an arrays elem_layout. */ 389 struct ipmi_mr_item_layout_s 390 { 391 char *name; 392 enum ipmi_fru_data_type_e dtype; 393 394 uint8_t settable; 395 396 /* Start offset and length, either in bits for a bit offset field 397 or bytes for everything else. */ 398 uint16_t start; 399 uint16_t length; 400 401 union { 402 float multiplier; 403 void *tab_data; 404 } u; 405 406 int (*set_field)(ipmi_mr_getset_t *getset, 407 enum ipmi_fru_data_type_e dtype, 408 int intval, 409 time_t time, 410 double floatval, 411 char *data, 412 unsigned int data_len); 413 int (*get_field)(ipmi_mr_getset_t *getset, 414 enum ipmi_fru_data_type_e *dtype, 415 int *intval, 416 time_t *time, 417 double *floatval, 418 char **data, 419 unsigned int *data_len); 420 int (*get_enum)(ipmi_mr_getset_t *getset, 421 int *pos, 422 int *nextpos, 423 const char **data); 424 }; 425 426 /* Describes an array. */ 427 struct ipmi_mr_array_layout_s 428 { 429 char *name; 430 uint8_t has_count; 431 uint8_t min_elem_size; 432 uint8_t settable; 433 434 /* Either a struct, item, or array layout, depending on the 435 functions. */ 436 void *elem_layout; 437 438 /* Check to make sure the data is valid and calculate the length 439 of the data needed for the element. */ 440 int (*elem_check)(void *layout, 441 unsigned char **mr_data, 442 unsigned int *mr_data_len); 443 /* Decode the element. The new record is returned in "rec". */ 444 int (*elem_decode)(void *layout, 445 unsigned int offset, 446 ipmi_mr_offset_t *offset_parent, 447 ipmi_mr_offset_t **rec, 448 unsigned char **mr_data, 449 unsigned int *mr_data_len); 450 /* Cleanup the array. */ 451 void (*cleanup)(ipmi_mr_array_info_t *arec); 452 /* Get a field from the array. */ 453 int (*get_field)(ipmi_mr_array_info_t *arec, 454 ipmi_fru_node_t *rnode, 455 enum ipmi_fru_data_type_e *dtype, 456 int *intval, 457 time_t *time, 458 double *floatval, 459 char **data, 460 unsigned int *data_len, 461 ipmi_fru_node_t **sub_node); 462 /* Set a field in the array. */ 463 int (*set_field)(ipmi_mr_array_info_t *arec, 464 ipmi_mr_fru_info_t *finfo, 465 enum ipmi_fru_data_type_e dtype, 466 int intval, 467 time_t time, 468 double floatval, 469 char *data, 470 unsigned int data_len); 471 }; 472 473 struct ipmi_mr_struct_layout_s 474 { 475 char *name; 476 uint8_t length; /* Excluding arrays. */ 477 unsigned int item_count; 478 ipmi_mr_item_layout_t *items; 479 unsigned int array_count; 480 ipmi_mr_array_layout_t *arrays; 481 482 void (*cleanup)(ipmi_mr_struct_info_t *rec); 483 }; 484 485 /* Get the actual offset from the beginning of the multi-record. */ 486 uint8_t ipmi_mr_full_offset(ipmi_mr_offset_t *o); 487 488 /* Resized something, adjust all the lengths and offsets in the parents. */ 489 void ipmi_mr_adjust_len(ipmi_mr_offset_t *o, int len); 490 491 /* Functions for processing arrays of structures. */ 492 void ipmi_mr_struct_array_cleanup(ipmi_mr_array_info_t *arec); 493 int ipmi_mr_struct_array_get_field(ipmi_mr_array_info_t *arec, 494 ipmi_fru_node_t *rnode, 495 enum ipmi_fru_data_type_e *dtype, 496 int *intval, 497 time_t *time, 498 double *floatval, 499 char **data, 500 unsigned int *data_len, 501 ipmi_fru_node_t **sub_node); 502 int ipmi_mr_struct_array_set_field(ipmi_mr_array_info_t *arec, 503 ipmi_mr_fru_info_t *finfo, 504 enum ipmi_fru_data_type_e dtype, 505 int intval, 506 time_t time, 507 double floatval, 508 char *data, 509 unsigned int data_len); 510 511 /* Functions for processing arrays of items. */ 512 void ipmi_mr_item_array_cleanup(ipmi_mr_array_info_t *arec); 513 int ipmi_mr_item_array_get_field(ipmi_mr_array_info_t *arec, 514 ipmi_fru_node_t *rnode, 515 enum ipmi_fru_data_type_e *dtype, 516 int *intval, 517 time_t *time, 518 double *floatval, 519 char **data, 520 unsigned int *data_len, 521 ipmi_fru_node_t **sub_node); 522 int ipmi_mr_item_array_set_field(ipmi_mr_array_info_t *arec, 523 ipmi_mr_fru_info_t *finfo, 524 enum ipmi_fru_data_type_e dtype, 525 int intval, 526 time_t time, 527 double floatval, 528 char *data, 529 unsigned int data_len); 530 531 /* Functions for handling structures. */ 532 void ipmi_mr_struct_cleanup(ipmi_mr_struct_info_t *rec); 533 int ipmi_mr_struct_elem_check(void *vlayout, 534 unsigned char **rmr_data, 535 unsigned int *rmr_data_len); 536 int ipmi_mr_struct_decode(void *vlayout, 537 unsigned int offset, 538 ipmi_mr_offset_t *offset_parent, 539 ipmi_mr_offset_t **rrec, 540 unsigned char **rmr_data, 541 unsigned int *rmr_data_len); 542 543 /* Functions for handling items (in arrays only). */ 544 int ipmi_mr_item_elem_check(void *vlayout, 545 unsigned char **rmr_data, 546 unsigned int *rmr_data_len); 547 int ipmi_mr_item_decode(void *vlayout, 548 unsigned int offset, 549 ipmi_mr_offset_t *offset_parent, 550 ipmi_mr_offset_t **rrec, 551 unsigned char **rmr_data, 552 unsigned int *rmr_data_len); 553 554 /* Create a root node based upon a structure layout. */ 555 int ipmi_mr_struct_root(ipmi_fru_t *fru, 556 unsigned int mr_rec_num, 557 unsigned char *rmr_data, 558 unsigned int rmr_data_len, 559 ipmi_mr_struct_layout_t *layout, 560 const char **name, 561 ipmi_fru_node_t **rnode); 562 563 /*********************************************************************** 564 * 565 * Generic field encoders and decoders. 566 * 567 **********************************************************************/ 568 569 /* Little-endian integer, one or more bytes. */ 570 int ipmi_mr_int_set_field(ipmi_mr_getset_t *getset, 571 enum ipmi_fru_data_type_e dtype, 572 int intval, 573 time_t time, 574 double floatval, 575 char *data, 576 unsigned int data_len); 577 int ipmi_mr_int_get_field(ipmi_mr_getset_t *getset, 578 enum ipmi_fru_data_type_e *dtype, 579 int *intval, 580 time_t *time, 581 double *floatval, 582 char **data, 583 unsigned int *data_len); 584 585 /* An integer that has is converted to float. You must set the 586 multiplier field in the layout. */ 587 int ipmi_mr_intfloat_set_field(ipmi_mr_getset_t *getset, 588 enum ipmi_fru_data_type_e dtype, 589 int intval, 590 time_t time, 591 double floatval, 592 char *data, 593 unsigned int data_len); 594 int ipmi_mr_intfloat_get_field(ipmi_mr_getset_t *getset, 595 enum ipmi_fru_data_type_e *dtype, 596 int *intval, 597 time_t *time, 598 double *floatval, 599 char **data, 600 unsigned int *data_len); 601 602 /* A bit field in the structure. Note that this is little endian and 603 the "start" and "length" field of the layout are in bits, not 604 bytes. */ 605 int ipmi_mr_bitint_set_field(ipmi_mr_getset_t *getset, 606 enum ipmi_fru_data_type_e dtype, 607 int intval, 608 time_t time, 609 double floatval, 610 char *data, 611 unsigned int data_len); 612 int ipmi_mr_bitint_get_field(ipmi_mr_getset_t *getset, 613 enum ipmi_fru_data_type_e *dtype, 614 int *intval, 615 time_t *time, 616 double *floatval, 617 char **data, 618 unsigned int *data_len); 619 620 /* A bitint that is a set of strings indexed by the integer value. 621 The tab_data field must be set to an ipmi_mr_tab_item_t 622 structure. */ 623 typedef struct ipmi_mr_tab_item_s { 624 unsigned int count; 625 const char *table[]; 626 } ipmi_mr_tab_item_t; 627 int ipmi_mr_bitvaltab_set_field(ipmi_mr_getset_t *getset, 628 enum ipmi_fru_data_type_e dtype, 629 int intval, 630 time_t time, 631 double floatval, 632 char *data, 633 unsigned int data_len); 634 int ipmi_mr_bitvaltab_get_field(ipmi_mr_getset_t *getset, 635 enum ipmi_fru_data_type_e *dtype, 636 int *intval, 637 time_t *time, 638 double *floatval, 639 char **data, 640 unsigned int *data_len); 641 int ipmi_mr_bitvaltab_get_enum(ipmi_mr_getset_t *getset, 642 int *pos, 643 int *nextpos, 644 const char **data); 645 646 /* A bitint that is a set of floating point values indexed by integer 647 value. The tab_data field must be set to an 648 ipmi_mr_floattab_item_t structure. */ 649 typedef struct ipmi_mr_floattab_item_s { 650 unsigned int count; 651 double defval; /* Default when initialized */ 652 /* You specify a low, nominal, and high value. The nominal value 653 is what it is converted to. Anything between low and high will 654 convert to this value. */ 655 struct { 656 float low; 657 float nominal; 658 float high; 659 const char *nominal_str; 660 } table[]; 661 } ipmi_mr_floattab_item_t; 662 int ipmi_mr_bitfloatvaltab_set_field(ipmi_mr_getset_t *getset, 663 enum ipmi_fru_data_type_e dtype, 664 int intval, 665 time_t time, 666 double floatval, 667 char *data, 668 unsigned int data_len); 669 int ipmi_mr_bitfloatvaltab_get_field(ipmi_mr_getset_t *getset, 670 enum ipmi_fru_data_type_e *dtype, 671 int *intval, 672 time_t *time, 673 double *floatval, 674 char **data, 675 unsigned int *data_len); 676 int ipmi_mr_bitfloatvaltab_get_enum(ipmi_mr_getset_t *getset, 677 int *pos, 678 int *nextpos, 679 const char **data); 680 681 /* A fixed-size area for a standard IPMI FRU string. */ 682 int ipmi_mr_str_set_field(ipmi_mr_getset_t *getset, 683 enum ipmi_fru_data_type_e dtype, 684 int intval, 685 time_t time, 686 double floatval, 687 char *data, 688 unsigned int data_len); 689 int ipmi_mr_str_get_field(ipmi_mr_getset_t *getset, 690 enum ipmi_fru_data_type_e *dtype, 691 int *intval, 692 time_t *time, 693 double *floatval, 694 char **data, 695 unsigned int *data_len); 696 697 /* A fixed-size area for a chunk of bytes. */ 698 int ipmi_mr_binary_set_field(ipmi_mr_getset_t *getset, 699 enum ipmi_fru_data_type_e dtype, 700 int intval, 701 time_t time, 702 double floatval, 703 char *data, 704 unsigned int data_len); 705 int ipmi_mr_binary_get_field(ipmi_mr_getset_t *getset, 706 enum ipmi_fru_data_type_e *dtype, 707 int *intval, 708 time_t *time, 709 double *floatval, 710 char **data, 711 unsigned int *data_len); 712 713 /* A four-byte IP address, represented as a string. */ 714 int ipmi_mr_ip_set_field(ipmi_mr_getset_t *getset, 715 enum ipmi_fru_data_type_e dtype, 716 int intval, 717 time_t time, 718 double floatval, 719 char *data, 720 unsigned int data_len); 721 int ipmi_mr_ip_get_field(ipmi_mr_getset_t *getset, 722 enum ipmi_fru_data_type_e *dtype, 723 int *intval, 724 time_t *time, 725 double *floatval, 726 char **data, 727 unsigned int *data_len); 728 729 #endif /* OPENIPMI_FRU_INTERNAL_H */ 730