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