1 /*- 2 * Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 34 #ifdef _KERNEL 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 39 #include <machine/_inttypes.h> 40 41 #else /* !_KERNEL */ 42 43 #include <errno.h> 44 #include <stdint.h> 45 #include <stdlib.h> 46 #include <string.h> 47 48 #endif /* _KERNEL */ 49 50 #include "bhnd_nvram_private.h" 51 #include "bhnd_nvram_io.h" 52 53 #include "bhnd_nvram_datavar.h" 54 #include "bhnd_nvram_data.h" 55 56 /** 57 * Return a human-readable description for the given NVRAM data class. 58 * 59 * @param cls The NVRAM class. 60 */ 61 const char * 62 bhnd_nvram_data_class_desc(bhnd_nvram_data_class *cls) 63 { 64 return (cls->desc); 65 } 66 67 /** 68 * Return the class-level capability flags (@see BHND_NVRAM_DATA_CAP_*) for 69 * of @p cls. 70 * 71 * @param cls The NVRAM class. 72 */ 73 uint32_t 74 bhnd_nvram_data_class_caps(bhnd_nvram_data_class *cls) 75 { 76 return (cls->caps); 77 } 78 79 /** 80 * Serialize all NVRAM properties in @p plist using @p cls's NVRAM data 81 * format, writing the result to @p outp. 82 * 83 * @param cls The NVRAM data class to be used to perform 84 * serialization. 85 * @param props The raw property values to be serialized to 86 * @p outp, in serialization order. 87 * @param options Serialization options for @p cls, or NULL. 88 * @param[out] outp On success, the serialed NVRAM data will be 89 * written to this buffer. This argment may be 90 * NULL if the value is not desired. 91 * @param[in,out] olen The capacity of @p buf. On success, will be set 92 * to the actual length of the serialized data. 93 * 94 * @retval 0 success 95 * 96 * @retval ENOMEM If @p outp is non-NULL and a buffer of @p olen is too 97 * small to hold the serialized data. 98 * @retval EINVAL If a property value required by @p cls is not found in 99 * @p plist. 100 * @retval EFTYPE If a property value in @p plist cannot be represented 101 * as the data type required by @p cls. 102 * @retval ERANGE If a property value in @p plist would would overflow 103 * (or underflow) the data type required by @p cls. 104 * @retval non-zero If serialization otherwise fails, a regular unix error 105 * code will be returned. 106 */ 107 int 108 bhnd_nvram_data_serialize(bhnd_nvram_data_class *cls, 109 bhnd_nvram_plist *props, bhnd_nvram_plist *options, void *outp, 110 size_t *olen) 111 { 112 return (cls->op_serialize(cls, props, options, outp, olen)); 113 } 114 115 /** 116 * Probe to see if this NVRAM data class class supports the data mapped by the 117 * given I/O context, returning a BHND_NVRAM_DATA_PROBE probe result. 118 * 119 * @param cls The NVRAM class. 120 * @param io An I/O context mapping the NVRAM data. 121 * 122 * @retval 0 if this is the only possible NVRAM data class for @p io. 123 * @retval negative if the probe succeeds, a negative value should be returned; 124 * the class returning the highest negative value should be selected to handle 125 * NVRAM parsing. 126 * @retval ENXIO If the NVRAM format is not handled by @p cls. 127 * @retval positive if an error occurs during probing, a regular unix error 128 * code should be returned. 129 */ 130 int 131 bhnd_nvram_data_probe(bhnd_nvram_data_class *cls, struct bhnd_nvram_io *io) 132 { 133 return (cls->op_probe(io)); 134 } 135 136 /** 137 * Probe to see if an NVRAM data class in @p classes supports parsing 138 * of the data mapped by @p io, returning the parsed data in @p data. 139 * 140 * The caller is responsible for deallocating the returned instance via 141 * bhnd_nvram_data_release(). 142 * 143 * @param[out] data On success, the parsed NVRAM data instance. 144 * @param io An I/O context mapping the NVRAM data to be copied and parsed. 145 * @param classes An array of NVRAM data classes to be probed, or NULL to 146 * probe the default supported set. 147 * @param num_classes The number of NVRAM data classes in @p classes. 148 * 149 * @retval 0 success 150 * @retval ENXIO if no class is found capable of parsing @p io. 151 * @retval non-zero if an error otherwise occurs during allocation, 152 * initialization, or parsing of the NVRAM data, a regular unix error code 153 * will be returned. 154 */ 155 int 156 bhnd_nvram_data_probe_classes(struct bhnd_nvram_data **data, 157 struct bhnd_nvram_io *io, bhnd_nvram_data_class *classes[], 158 size_t num_classes) 159 { 160 bhnd_nvram_data_class *cls; 161 int error, prio, result; 162 163 cls = NULL; 164 prio = 0; 165 *data = NULL; 166 167 /* If class array is NULL, default to our linker set */ 168 if (classes == NULL) { 169 classes = SET_BEGIN(bhnd_nvram_data_class_set); 170 num_classes = SET_COUNT(bhnd_nvram_data_class_set); 171 } 172 173 /* Try to find the best data class capable of parsing io */ 174 for (size_t i = 0; i < num_classes; i++) { 175 bhnd_nvram_data_class *next_cls; 176 177 next_cls = classes[i]; 178 179 /* Try to probe */ 180 result = bhnd_nvram_data_probe(next_cls, io); 181 182 /* The parser did not match if an error was returned */ 183 if (result > 0) 184 continue; 185 186 /* Lower priority than previous match; keep 187 * searching */ 188 if (cls != NULL && result <= prio) 189 continue; 190 191 /* Drop any previously parsed data */ 192 if (*data != NULL) { 193 bhnd_nvram_data_release(*data); 194 *data = NULL; 195 } 196 197 /* If this is a 'maybe' match, attempt actual parsing to 198 * verify that this does in fact match */ 199 if (result <= BHND_NVRAM_DATA_PROBE_MAYBE) { 200 /* If parsing fails, keep searching */ 201 error = bhnd_nvram_data_new(next_cls, data, io); 202 if (error) 203 continue; 204 } 205 206 /* Record best new match */ 207 prio = result; 208 cls = next_cls; 209 210 211 /* Terminate search immediately on 212 * BHND_NVRAM_DATA_PROBE_SPECIFIC */ 213 if (result == BHND_NVRAM_DATA_PROBE_SPECIFIC) 214 break; 215 } 216 217 /* If no match, return error */ 218 if (cls == NULL) 219 return (ENXIO); 220 221 /* If the NVRAM data was not parsed above, do so now */ 222 if (*data == NULL) { 223 if ((error = bhnd_nvram_data_new(cls, data, io))) 224 return (error); 225 } 226 227 return (0); 228 } 229 230 /** 231 * Allocate and initialize a new instance of data class @p cls, copying and 232 * parsing NVRAM data from @p io. 233 * 234 * The caller is responsible for releasing the returned parser instance 235 * reference via bhnd_nvram_data_release(). 236 * 237 * @param cls If non-NULL, the data class to be allocated. If NULL, 238 * bhnd_nvram_data_probe_classes() will be used to determine the data format. 239 * @param[out] nv On success, a pointer to the newly allocated NVRAM data instance. 240 * @param io An I/O context mapping the NVRAM data to be copied and parsed. 241 * 242 * @retval 0 success 243 * @retval non-zero if an error occurs during allocation or initialization, a 244 * regular unix error code will be returned. 245 */ 246 int 247 bhnd_nvram_data_new(bhnd_nvram_data_class *cls, struct bhnd_nvram_data **nv, 248 struct bhnd_nvram_io *io) 249 { 250 struct bhnd_nvram_data *data; 251 int error; 252 253 /* If NULL, try to identify the appropriate class */ 254 if (cls == NULL) 255 return (bhnd_nvram_data_probe_classes(nv, io, NULL, 0)); 256 257 /* Allocate new instance */ 258 BHND_NV_ASSERT(sizeof(struct bhnd_nvram_data) <= cls->size, 259 ("instance size %zu less than minimum %zu", cls->size, 260 sizeof(struct bhnd_nvram_data))); 261 262 data = bhnd_nv_calloc(1, cls->size); 263 data->cls = cls; 264 refcount_init(&data->refs, 1); 265 266 /* Let the class handle initialization */ 267 if ((error = cls->op_new(data, io))) { 268 bhnd_nv_free(data); 269 return (error); 270 } 271 272 *nv = data; 273 return (0); 274 } 275 276 /** 277 * Retain and return a reference to the given data instance. 278 * 279 * @param nv The reference to be retained. 280 */ 281 struct bhnd_nvram_data * 282 bhnd_nvram_data_retain(struct bhnd_nvram_data *nv) 283 { 284 refcount_acquire(&nv->refs); 285 return (nv); 286 } 287 288 /** 289 * Release a reference to the given data instance. 290 * 291 * If this is the last reference, the data instance and its associated 292 * resources will be freed. 293 * 294 * @param nv The reference to be released. 295 */ 296 void 297 bhnd_nvram_data_release(struct bhnd_nvram_data *nv) 298 { 299 if (!refcount_release(&nv->refs)) 300 return; 301 302 /* Free any internal resources */ 303 nv->cls->op_free(nv); 304 305 /* Free the instance allocation */ 306 bhnd_nv_free(nv); 307 } 308 309 /** 310 * Return a pointer to @p nv's data class. 311 * 312 * @param nv The NVRAM data instance to be queried. 313 */ 314 bhnd_nvram_data_class * 315 bhnd_nvram_data_get_class(struct bhnd_nvram_data *nv) 316 { 317 return (nv->cls); 318 } 319 320 /** 321 * Return the number of variables in @p nv. 322 * 323 * @param nv The NVRAM data to be queried. 324 */ 325 size_t 326 bhnd_nvram_data_count(struct bhnd_nvram_data *nv) 327 { 328 return (nv->cls->op_count(nv)); 329 } 330 331 /** 332 * Return a borrowed reference to the serialization options for @p nv, 333 * suitable for use with bhnd_nvram_data_serialize(), or NULL if none. 334 * 335 * @param nv The NVRAM data to be queried. 336 */ 337 bhnd_nvram_plist * 338 bhnd_nvram_data_options(struct bhnd_nvram_data *nv) 339 { 340 return (nv->cls->op_options(nv)); 341 } 342 343 /** 344 * Return the capability flags (@see BHND_NVRAM_DATA_CAP_*) for @p nv. 345 * 346 * @param nv The NVRAM data to be queried. 347 */ 348 uint32_t 349 bhnd_nvram_data_caps(struct bhnd_nvram_data *nv) 350 { 351 return (nv->cls->op_caps(nv)); 352 } 353 354 /** 355 * Iterate over @p nv, returning the names of subsequent variables. 356 * 357 * @param nv The NVRAM data to be iterated. 358 * @param[in,out] cookiep A pointer to a cookiep value previously returned 359 * by bhnd_nvram_data_next(), or a NULL value to 360 * begin iteration. 361 * 362 * @return Returns the next variable name, or NULL if there are no more 363 * variables defined in @p nv. 364 */ 365 const char * 366 bhnd_nvram_data_next(struct bhnd_nvram_data *nv, void **cookiep) 367 { 368 const char *name; 369 #ifdef BHND_NV_INVARIANTS 370 void *prev = *cookiep; 371 #endif 372 373 /* Fetch next */ 374 if ((name = nv->cls->op_next(nv, cookiep)) == NULL) 375 return (NULL); 376 377 /* Enforce precedence ordering invariant between bhnd_nvram_data_next() 378 * and bhnd_nvram_data_getvar_order() */ 379 #ifdef BHND_NV_INVARIANTS 380 if (prev != NULL && 381 bhnd_nvram_data_getvar_order(nv, prev, *cookiep) > 0) 382 { 383 BHND_NV_PANIC("%s: returned out-of-order entry", __FUNCTION__); 384 } 385 #endif 386 387 return (name); 388 } 389 390 /** 391 * Search @p nv for a named variable, returning the variable's opaque reference 392 * if found, or NULL if unavailable. 393 * 394 * The BHND_NVRAM_DATA_CAP_INDEXED capability flag will be returned by 395 * bhnd_nvram_data_caps() if @p nv supports effecient name-based 396 * lookups. 397 * 398 * @param nv The NVRAM data to search. 399 * @param name The name to search for. 400 * 401 * @retval non-NULL If @p name is found, the opaque cookie value will be 402 * returned. 403 * @retval NULL If @p name is not found. 404 */ 405 void * 406 bhnd_nvram_data_find(struct bhnd_nvram_data *nv, const char *name) 407 { 408 return (nv->cls->op_find(nv, name)); 409 } 410 411 /** 412 * A generic implementation of bhnd_nvram_data_find(). 413 * 414 * This implementation will use bhnd_nvram_data_next() to perform a 415 * simple O(n) case-insensitve search for @p name. 416 */ 417 void * 418 bhnd_nvram_data_generic_find(struct bhnd_nvram_data *nv, const char *name) 419 { 420 const char *next; 421 void *cookiep; 422 423 cookiep = NULL; 424 while ((next = bhnd_nvram_data_next(nv, &cookiep))) { 425 if (strcmp(name, next) == 0) 426 return (cookiep); 427 } 428 429 /* Not found */ 430 return (NULL); 431 } 432 433 /** 434 * Compare the declaration order of two NVRAM variables. 435 * 436 * Variable declaration order is used to determine the current order of 437 * the variables in the source data, as well as to determine the precedence 438 * of variable declarations in data sources that define duplicate names. 439 * 440 * The comparison order will match the order of variables returned via 441 * bhnd_nvstore_path_data_next(). 442 * 443 * @param nv The NVRAM data. 444 * @param cookiep1 An NVRAM variable cookie previously 445 * returned via bhnd_nvram_data_next() or 446 * bhnd_nvram_data_find(). 447 * @param cookiep2 An NVRAM variable cookie previously 448 * returned via bhnd_nvram_data_next() or 449 * bhnd_nvram_data_find(). 450 * 451 * @retval <= -1 If @p cookiep1 has an earlier declaration order than 452 * @p cookiep2. 453 * @retval 0 If @p cookiep1 and @p cookiep2 are identical. 454 * @retval >= 1 If @p cookiep has a later declaration order than 455 * @p cookiep2. 456 */ 457 int 458 bhnd_nvram_data_getvar_order(struct bhnd_nvram_data *nv, void *cookiep1, 459 void *cookiep2) 460 { 461 return (nv->cls->op_getvar_order(nv, cookiep1, cookiep2)); 462 } 463 464 /** 465 * Read a variable and decode as @p type. 466 * 467 * @param nv The NVRAM data. 468 * @param cookiep An NVRAM variable cookie previously returned 469 * via bhnd_nvram_data_next() or 470 * bhnd_nvram_data_find(). 471 * @param[out] buf On success, the requested value will be written 472 * to this buffer. This argment may be NULL if 473 * the value is not desired. 474 * @param[in,out] len The capacity of @p buf. On success, will be set 475 * to the actual size of the requested value. 476 * @param type The data type to be written to @p buf. 477 * 478 * @retval 0 success 479 * @retval ENOMEM If @p buf is non-NULL and a buffer of @p len is too 480 * small to hold the requested value. 481 * @retval EFTYPE If the variable data cannot be coerced to @p type. 482 * @retval ERANGE If value coercion would overflow @p type. 483 */ 484 int 485 bhnd_nvram_data_getvar(struct bhnd_nvram_data *nv, void *cookiep, void *buf, 486 size_t *len, bhnd_nvram_type type) 487 { 488 return (nv->cls->op_getvar(nv, cookiep, buf, len, type)); 489 } 490 491 /* 492 * Common bhnd_nvram_data_getvar_ptr() wrapper used by 493 * bhnd_nvram_data_generic_rp_getvar() and 494 * bhnd_nvram_data_generic_rp_copy_val(). 495 * 496 * If a variable definition for the requested variable is found via 497 * bhnd_nvram_find_vardefn(), the definition will be used to populate fmt. 498 */ 499 static const void * 500 bhnd_nvram_data_getvar_ptr_info(struct bhnd_nvram_data *nv, void *cookiep, 501 size_t *len, bhnd_nvram_type *type, const bhnd_nvram_val_fmt **fmt) 502 { 503 const struct bhnd_nvram_vardefn *vdefn; 504 const char *name; 505 const void *vptr; 506 507 BHND_NV_ASSERT(bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_READ_PTR, 508 ("instance does not advertise READ_PTR support")); 509 510 /* Fetch pointer to variable data */ 511 vptr = bhnd_nvram_data_getvar_ptr(nv, cookiep, len, type); 512 if (vptr == NULL) 513 return (NULL); 514 515 /* Select a default value format implementation */ 516 517 518 /* Fetch the reference variable name */ 519 name = bhnd_nvram_data_getvar_name(nv, cookiep); 520 521 /* Trim path prefix, if any; the Broadcom NVRAM format assumes a global 522 * namespace for all variable definitions */ 523 if (bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_DEVPATHS) 524 name = bhnd_nvram_trim_path_name(name); 525 526 /* Check the variable definition table for a matching entry; if 527 * it exists, use it to populate the value format. */ 528 vdefn = bhnd_nvram_find_vardefn(name); 529 if (vdefn != NULL) { 530 BHND_NV_ASSERT(vdefn->fmt != NULL, 531 ("NULL format for %s", name)); 532 *fmt = vdefn->fmt; 533 } else if (*type == BHND_NVRAM_TYPE_STRING) { 534 /* Default to Broadcom-specific string interpretation */ 535 *fmt = &bhnd_nvram_val_bcm_string_fmt; 536 } else { 537 /* Fall back on native formatting */ 538 *fmt = bhnd_nvram_val_default_fmt(*type); 539 } 540 541 return (vptr); 542 } 543 544 /** 545 * A generic implementation of bhnd_nvram_data_getvar(). 546 * 547 * This implementation will call bhnd_nvram_data_getvar_ptr() to fetch 548 * a pointer to the variable data and perform data coercion on behalf 549 * of the caller. 550 * 551 * If a variable definition for the requested variable is available via 552 * bhnd_nvram_find_vardefn(), the definition will be used to provide a 553 * formatting instance to bhnd_nvram_val_init(). 554 */ 555 int 556 bhnd_nvram_data_generic_rp_getvar(struct bhnd_nvram_data *nv, void *cookiep, 557 void *outp, size_t *olen, bhnd_nvram_type otype) 558 { 559 bhnd_nvram_val val; 560 const bhnd_nvram_val_fmt *fmt; 561 const void *vptr; 562 bhnd_nvram_type vtype; 563 size_t vlen; 564 int error; 565 566 BHND_NV_ASSERT(bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_READ_PTR, 567 ("instance does not advertise READ_PTR support")); 568 569 /* Fetch variable data and value format*/ 570 vptr = bhnd_nvram_data_getvar_ptr_info(nv, cookiep, &vlen, &vtype, 571 &fmt); 572 if (vptr == NULL) 573 return (EINVAL); 574 575 /* Attempt value coercion */ 576 error = bhnd_nvram_val_init(&val, fmt, vptr, vlen, vtype, 577 BHND_NVRAM_VAL_BORROW_DATA); 578 if (error) 579 return (error); 580 581 error = bhnd_nvram_val_encode(&val, outp, olen, otype); 582 583 /* Clean up */ 584 bhnd_nvram_val_release(&val); 585 return (error); 586 } 587 588 /** 589 * Return a caller-owned copy of an NVRAM entry's variable data. 590 * 591 * The caller is responsible for deallocating the returned value via 592 * bhnd_nvram_val_release(). 593 * 594 * @param nv The NVRAM data. 595 * @param cookiep An NVRAM variable cookie previously returned 596 * via bhnd_nvram_data_next() or bhnd_nvram_data_find(). 597 * @param[out] value On success, the caller-owned value instance. 598 * 599 * @retval 0 success 600 * @retval ENOMEM If allocation fails. 601 * @retval non-zero If initialization of the value otherwise fails, a 602 * regular unix error code will be returned. 603 */ 604 int 605 bhnd_nvram_data_copy_val(struct bhnd_nvram_data *nv, void *cookiep, 606 bhnd_nvram_val **value) 607 { 608 return (nv->cls->op_copy_val(nv, cookiep, value)); 609 } 610 611 /** 612 * A generic implementation of bhnd_nvram_data_copy_val(). 613 * 614 * This implementation will call bhnd_nvram_data_getvar_ptr() to fetch 615 * a pointer to the variable data and perform data coercion on behalf 616 * of the caller. 617 * 618 * If a variable definition for the requested variable is available via 619 * bhnd_nvram_find_vardefn(), the definition will be used to provide a 620 * formatting instance to bhnd_nvram_val_init(). 621 */ 622 int 623 bhnd_nvram_data_generic_rp_copy_val(struct bhnd_nvram_data *nv, 624 void *cookiep, bhnd_nvram_val **value) 625 { 626 const bhnd_nvram_val_fmt *fmt; 627 const void *vptr; 628 bhnd_nvram_type vtype; 629 size_t vlen; 630 631 BHND_NV_ASSERT(bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_READ_PTR, 632 ("instance does not advertise READ_PTR support")); 633 634 /* Fetch variable data and value format*/ 635 vptr = bhnd_nvram_data_getvar_ptr_info(nv, cookiep, &vlen, &vtype, 636 &fmt); 637 if (vptr == NULL) 638 return (EINVAL); 639 640 /* Allocate and return the new value instance */ 641 return (bhnd_nvram_val_new(value, fmt, vptr, vlen, vtype, 642 BHND_NVRAM_VAL_DYNAMIC)); 643 } 644 645 /** 646 * If available and supported by the NVRAM data instance, return a reference 647 * to the internal buffer containing an entry's variable data, 648 * 649 * Note that string values may not be NUL terminated. 650 * 651 * @param nv The NVRAM data. 652 * @param cookiep An NVRAM variable cookie previously returned 653 * via bhnd_nvram_data_next() or 654 * bhnd_nvram_data_find(). 655 * @param[out] len On success, will be set to the actual size of 656 * the requested value. 657 * @param[out] type The data type of the entry data. 658 * 659 * @retval non-NULL success 660 * @retval NULL if direct data access is unsupported by @p nv, or 661 * unavailable for @p cookiep. 662 */ 663 const void * 664 bhnd_nvram_data_getvar_ptr(struct bhnd_nvram_data *nv, void *cookiep, 665 size_t *len, bhnd_nvram_type *type) 666 { 667 return (nv->cls->op_getvar_ptr(nv, cookiep, len, type)); 668 } 669 670 671 /** 672 * Return the variable name associated with a given @p cookiep. 673 * @param nv The NVRAM data to be iterated. 674 * @param[in,out] cookiep A pointer to a cookiep value previously returned 675 * via bhnd_nvram_data_next() or 676 * bhnd_nvram_data_find(). 677 * 678 * @return Returns the variable's name. 679 */ 680 const char * 681 bhnd_nvram_data_getvar_name(struct bhnd_nvram_data *nv, void *cookiep) 682 { 683 return (nv->cls->op_getvar_name(nv, cookiep)); 684 } 685 686 /** 687 * Filter a request to set variable @p name with @p value. 688 * 689 * On success, the caller owns a reference to @p result, and must release 690 * any held resources via bhnd_nvram_val_release(). 691 * 692 * @param nv The NVRAM data instance. 693 * @param name The name of the variable to be set. 694 * @param value The proposed value to be set. 695 * @param[out] result On success, a caller-owned reference to the filtered 696 * value to be set. 697 * 698 * @retval 0 success 699 * @retval ENOENT if @p name is unrecognized by @p nv. 700 * @retval EINVAL if @p name is read-only. 701 * @retval EINVAL if @p value cannot be converted to the required value 702 * type. 703 */ 704 int 705 bhnd_nvram_data_filter_setvar(struct bhnd_nvram_data *nv, const char *name, 706 bhnd_nvram_val *value, bhnd_nvram_val **result) 707 { 708 return (nv->cls->op_filter_setvar(nv, name, value, result)); 709 } 710 711 /** 712 * Filter a request to delete variable @p name. 713 * 714 * @param nv The NVRAM data instance. 715 * @param name The name of the variable to be deleted. 716 * 717 * @retval 0 success 718 * @retval ENOENT if @p name is unrecognized by @p nv. 719 * @retval EINVAL if @p name is read-only. 720 */ 721 int 722 bhnd_nvram_data_filter_unsetvar(struct bhnd_nvram_data *nv, const char *name) 723 { 724 return (nv->cls->op_filter_unsetvar(nv, name)); 725 } 726