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