177cb4d3eSLandon J. Fuller /*-
277cb4d3eSLandon J. Fuller * Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.org>
377cb4d3eSLandon J. Fuller * All rights reserved.
477cb4d3eSLandon J. Fuller *
577cb4d3eSLandon J. Fuller * Redistribution and use in source and binary forms, with or without
677cb4d3eSLandon J. Fuller * modification, are permitted provided that the following conditions
777cb4d3eSLandon J. Fuller * are met:
877cb4d3eSLandon J. Fuller * 1. Redistributions of source code must retain the above copyright
977cb4d3eSLandon J. Fuller * notice, this list of conditions and the following disclaimer,
1077cb4d3eSLandon J. Fuller * without modification.
1177cb4d3eSLandon J. Fuller * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1277cb4d3eSLandon J. Fuller * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
1377cb4d3eSLandon J. Fuller * redistribution must be conditioned upon including a substantially
1477cb4d3eSLandon J. Fuller * similar Disclaimer requirement for further binary redistribution.
1577cb4d3eSLandon J. Fuller *
1677cb4d3eSLandon J. Fuller * NO WARRANTY
1777cb4d3eSLandon J. Fuller * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1877cb4d3eSLandon J. Fuller * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1977cb4d3eSLandon J. Fuller * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
2077cb4d3eSLandon J. Fuller * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
2177cb4d3eSLandon J. Fuller * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
2277cb4d3eSLandon J. Fuller * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2377cb4d3eSLandon J. Fuller * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2477cb4d3eSLandon J. Fuller * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
2577cb4d3eSLandon J. Fuller * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2677cb4d3eSLandon J. Fuller * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2777cb4d3eSLandon J. Fuller * THE POSSIBILITY OF SUCH DAMAGES.
2877cb4d3eSLandon J. Fuller */
2977cb4d3eSLandon J. Fuller
3077cb4d3eSLandon J. Fuller #include <sys/cdefs.h>
3177cb4d3eSLandon J. Fuller #ifdef _KERNEL
3277cb4d3eSLandon J. Fuller
3377cb4d3eSLandon J. Fuller #include <sys/param.h>
3477cb4d3eSLandon J. Fuller #include <sys/systm.h>
3577cb4d3eSLandon J. Fuller
3677cb4d3eSLandon J. Fuller #include <machine/_inttypes.h>
3777cb4d3eSLandon J. Fuller
3877cb4d3eSLandon J. Fuller #else /* !_KERNEL */
3977cb4d3eSLandon J. Fuller
4077cb4d3eSLandon J. Fuller #include <errno.h>
4177cb4d3eSLandon J. Fuller #include <stdint.h>
4277cb4d3eSLandon J. Fuller #include <stdlib.h>
4377cb4d3eSLandon J. Fuller #include <string.h>
4477cb4d3eSLandon J. Fuller
4577cb4d3eSLandon J. Fuller #endif /* _KERNEL */
4677cb4d3eSLandon J. Fuller
4777cb4d3eSLandon J. Fuller #include "bhnd_nvram_private.h"
4877cb4d3eSLandon J. Fuller #include "bhnd_nvram_io.h"
4977cb4d3eSLandon J. Fuller
5077cb4d3eSLandon J. Fuller #include "bhnd_nvram_datavar.h"
5177cb4d3eSLandon J. Fuller #include "bhnd_nvram_data.h"
5277cb4d3eSLandon J. Fuller
5377cb4d3eSLandon J. Fuller /**
5477cb4d3eSLandon J. Fuller * Return a human-readable description for the given NVRAM data class.
5577cb4d3eSLandon J. Fuller *
5677cb4d3eSLandon J. Fuller * @param cls The NVRAM class.
5777cb4d3eSLandon J. Fuller */
5877cb4d3eSLandon J. Fuller const char *
bhnd_nvram_data_class_desc(bhnd_nvram_data_class * cls)5958efe686SLandon J. Fuller bhnd_nvram_data_class_desc(bhnd_nvram_data_class *cls)
6077cb4d3eSLandon J. Fuller {
6177cb4d3eSLandon J. Fuller return (cls->desc);
6277cb4d3eSLandon J. Fuller }
6377cb4d3eSLandon J. Fuller
6477cb4d3eSLandon J. Fuller /**
65c283839dSLandon J. Fuller * Return the class-level capability flags (@see BHND_NVRAM_DATA_CAP_*) for
66c283839dSLandon J. Fuller * of @p cls.
67c283839dSLandon J. Fuller *
68c283839dSLandon J. Fuller * @param cls The NVRAM class.
69c283839dSLandon J. Fuller */
70c283839dSLandon J. Fuller uint32_t
bhnd_nvram_data_class_caps(bhnd_nvram_data_class * cls)71c283839dSLandon J. Fuller bhnd_nvram_data_class_caps(bhnd_nvram_data_class *cls)
72c283839dSLandon J. Fuller {
73c283839dSLandon J. Fuller return (cls->caps);
74c283839dSLandon J. Fuller }
75c283839dSLandon J. Fuller
76c283839dSLandon J. Fuller /**
77c283839dSLandon J. Fuller * Serialize all NVRAM properties in @p plist using @p cls's NVRAM data
78c283839dSLandon J. Fuller * format, writing the result to @p outp.
79c283839dSLandon J. Fuller *
80c283839dSLandon J. Fuller * @param cls The NVRAM data class to be used to perform
81c283839dSLandon J. Fuller * serialization.
82c283839dSLandon J. Fuller * @param props The raw property values to be serialized to
83c283839dSLandon J. Fuller * @p outp, in serialization order.
84c283839dSLandon J. Fuller * @param options Serialization options for @p cls, or NULL.
85c283839dSLandon J. Fuller * @param[out] outp On success, the serialed NVRAM data will be
86c283839dSLandon J. Fuller * written to this buffer. This argment may be
87c283839dSLandon J. Fuller * NULL if the value is not desired.
88c283839dSLandon J. Fuller * @param[in,out] olen The capacity of @p buf. On success, will be set
89c283839dSLandon J. Fuller * to the actual length of the serialized data.
90c283839dSLandon J. Fuller *
91c283839dSLandon J. Fuller * @retval 0 success
92c283839dSLandon J. Fuller *
93c283839dSLandon J. Fuller * @retval ENOMEM If @p outp is non-NULL and a buffer of @p olen is too
94c283839dSLandon J. Fuller * small to hold the serialized data.
95c283839dSLandon J. Fuller * @retval EINVAL If a property value required by @p cls is not found in
96c283839dSLandon J. Fuller * @p plist.
97c283839dSLandon J. Fuller * @retval EFTYPE If a property value in @p plist cannot be represented
98c283839dSLandon J. Fuller * as the data type required by @p cls.
99c283839dSLandon J. Fuller * @retval ERANGE If a property value in @p plist would would overflow
100c283839dSLandon J. Fuller * (or underflow) the data type required by @p cls.
101c283839dSLandon J. Fuller * @retval non-zero If serialization otherwise fails, a regular unix error
102c283839dSLandon J. Fuller * code will be returned.
103c283839dSLandon J. Fuller */
104c283839dSLandon J. Fuller int
bhnd_nvram_data_serialize(bhnd_nvram_data_class * cls,bhnd_nvram_plist * props,bhnd_nvram_plist * options,void * outp,size_t * olen)105c283839dSLandon J. Fuller bhnd_nvram_data_serialize(bhnd_nvram_data_class *cls,
106c283839dSLandon J. Fuller bhnd_nvram_plist *props, bhnd_nvram_plist *options, void *outp,
107c283839dSLandon J. Fuller size_t *olen)
108c283839dSLandon J. Fuller {
109c283839dSLandon J. Fuller return (cls->op_serialize(cls, props, options, outp, olen));
110c283839dSLandon J. Fuller }
111c283839dSLandon J. Fuller
112c283839dSLandon J. Fuller /**
11377cb4d3eSLandon J. Fuller * Probe to see if this NVRAM data class class supports the data mapped by the
11477cb4d3eSLandon J. Fuller * given I/O context, returning a BHND_NVRAM_DATA_PROBE probe result.
11577cb4d3eSLandon J. Fuller *
11677cb4d3eSLandon J. Fuller * @param cls The NVRAM class.
11777cb4d3eSLandon J. Fuller * @param io An I/O context mapping the NVRAM data.
11877cb4d3eSLandon J. Fuller *
11977cb4d3eSLandon J. Fuller * @retval 0 if this is the only possible NVRAM data class for @p io.
12077cb4d3eSLandon J. Fuller * @retval negative if the probe succeeds, a negative value should be returned;
12177cb4d3eSLandon J. Fuller * the class returning the highest negative value should be selected to handle
12277cb4d3eSLandon J. Fuller * NVRAM parsing.
12377cb4d3eSLandon J. Fuller * @retval ENXIO If the NVRAM format is not handled by @p cls.
12477cb4d3eSLandon J. Fuller * @retval positive if an error occurs during probing, a regular unix error
12577cb4d3eSLandon J. Fuller * code should be returned.
12677cb4d3eSLandon J. Fuller */
12777cb4d3eSLandon J. Fuller int
bhnd_nvram_data_probe(bhnd_nvram_data_class * cls,struct bhnd_nvram_io * io)12858efe686SLandon J. Fuller bhnd_nvram_data_probe(bhnd_nvram_data_class *cls, struct bhnd_nvram_io *io)
12977cb4d3eSLandon J. Fuller {
13077cb4d3eSLandon J. Fuller return (cls->op_probe(io));
13177cb4d3eSLandon J. Fuller }
13277cb4d3eSLandon J. Fuller
13377cb4d3eSLandon J. Fuller /**
13477cb4d3eSLandon J. Fuller * Probe to see if an NVRAM data class in @p classes supports parsing
13577cb4d3eSLandon J. Fuller * of the data mapped by @p io, returning the parsed data in @p data.
13677cb4d3eSLandon J. Fuller *
13777cb4d3eSLandon J. Fuller * The caller is responsible for deallocating the returned instance via
13877cb4d3eSLandon J. Fuller * bhnd_nvram_data_release().
13977cb4d3eSLandon J. Fuller *
14077cb4d3eSLandon J. Fuller * @param[out] data On success, the parsed NVRAM data instance.
14177cb4d3eSLandon J. Fuller * @param io An I/O context mapping the NVRAM data to be copied and parsed.
14277cb4d3eSLandon J. Fuller * @param classes An array of NVRAM data classes to be probed, or NULL to
14377cb4d3eSLandon J. Fuller * probe the default supported set.
14477cb4d3eSLandon J. Fuller * @param num_classes The number of NVRAM data classes in @p classes.
14577cb4d3eSLandon J. Fuller *
14677cb4d3eSLandon J. Fuller * @retval 0 success
14777cb4d3eSLandon J. Fuller * @retval ENXIO if no class is found capable of parsing @p io.
14877cb4d3eSLandon J. Fuller * @retval non-zero if an error otherwise occurs during allocation,
14977cb4d3eSLandon J. Fuller * initialization, or parsing of the NVRAM data, a regular unix error code
15077cb4d3eSLandon J. Fuller * will be returned.
15177cb4d3eSLandon J. Fuller */
15277cb4d3eSLandon J. Fuller int
bhnd_nvram_data_probe_classes(struct bhnd_nvram_data ** data,struct bhnd_nvram_io * io,bhnd_nvram_data_class * classes[],size_t num_classes)15377cb4d3eSLandon J. Fuller bhnd_nvram_data_probe_classes(struct bhnd_nvram_data **data,
15458efe686SLandon J. Fuller struct bhnd_nvram_io *io, bhnd_nvram_data_class *classes[],
15577cb4d3eSLandon J. Fuller size_t num_classes)
15677cb4d3eSLandon J. Fuller {
15758efe686SLandon J. Fuller bhnd_nvram_data_class *cls;
15877cb4d3eSLandon J. Fuller int error, prio, result;
15977cb4d3eSLandon J. Fuller
16077cb4d3eSLandon J. Fuller cls = NULL;
16177cb4d3eSLandon J. Fuller prio = 0;
16277cb4d3eSLandon J. Fuller *data = NULL;
16377cb4d3eSLandon J. Fuller
16477cb4d3eSLandon J. Fuller /* If class array is NULL, default to our linker set */
16577cb4d3eSLandon J. Fuller if (classes == NULL) {
16677cb4d3eSLandon J. Fuller classes = SET_BEGIN(bhnd_nvram_data_class_set);
16777cb4d3eSLandon J. Fuller num_classes = SET_COUNT(bhnd_nvram_data_class_set);
16877cb4d3eSLandon J. Fuller }
16977cb4d3eSLandon J. Fuller
17077cb4d3eSLandon J. Fuller /* Try to find the best data class capable of parsing io */
17177cb4d3eSLandon J. Fuller for (size_t i = 0; i < num_classes; i++) {
17258efe686SLandon J. Fuller bhnd_nvram_data_class *next_cls;
17377cb4d3eSLandon J. Fuller
17477cb4d3eSLandon J. Fuller next_cls = classes[i];
17577cb4d3eSLandon J. Fuller
17677cb4d3eSLandon J. Fuller /* Try to probe */
17777cb4d3eSLandon J. Fuller result = bhnd_nvram_data_probe(next_cls, io);
17877cb4d3eSLandon J. Fuller
17977cb4d3eSLandon J. Fuller /* The parser did not match if an error was returned */
18077cb4d3eSLandon J. Fuller if (result > 0)
18177cb4d3eSLandon J. Fuller continue;
18277cb4d3eSLandon J. Fuller
18377cb4d3eSLandon J. Fuller /* Lower priority than previous match; keep
18477cb4d3eSLandon J. Fuller * searching */
18577cb4d3eSLandon J. Fuller if (cls != NULL && result <= prio)
18677cb4d3eSLandon J. Fuller continue;
18777cb4d3eSLandon J. Fuller
18877cb4d3eSLandon J. Fuller /* Drop any previously parsed data */
18977cb4d3eSLandon J. Fuller if (*data != NULL) {
19077cb4d3eSLandon J. Fuller bhnd_nvram_data_release(*data);
19177cb4d3eSLandon J. Fuller *data = NULL;
19277cb4d3eSLandon J. Fuller }
19377cb4d3eSLandon J. Fuller
19477cb4d3eSLandon J. Fuller /* If this is a 'maybe' match, attempt actual parsing to
19577cb4d3eSLandon J. Fuller * verify that this does in fact match */
19677cb4d3eSLandon J. Fuller if (result <= BHND_NVRAM_DATA_PROBE_MAYBE) {
19777cb4d3eSLandon J. Fuller /* If parsing fails, keep searching */
19877cb4d3eSLandon J. Fuller error = bhnd_nvram_data_new(next_cls, data, io);
19977cb4d3eSLandon J. Fuller if (error)
20077cb4d3eSLandon J. Fuller continue;
20177cb4d3eSLandon J. Fuller }
20277cb4d3eSLandon J. Fuller
20377cb4d3eSLandon J. Fuller /* Record best new match */
20477cb4d3eSLandon J. Fuller prio = result;
20577cb4d3eSLandon J. Fuller cls = next_cls;
20677cb4d3eSLandon J. Fuller
20777cb4d3eSLandon J. Fuller /* Terminate search immediately on
20877cb4d3eSLandon J. Fuller * BHND_NVRAM_DATA_PROBE_SPECIFIC */
20977cb4d3eSLandon J. Fuller if (result == BHND_NVRAM_DATA_PROBE_SPECIFIC)
21077cb4d3eSLandon J. Fuller break;
21177cb4d3eSLandon J. Fuller }
21277cb4d3eSLandon J. Fuller
21377cb4d3eSLandon J. Fuller /* If no match, return error */
21477cb4d3eSLandon J. Fuller if (cls == NULL)
21577cb4d3eSLandon J. Fuller return (ENXIO);
21677cb4d3eSLandon J. Fuller
21777cb4d3eSLandon J. Fuller /* If the NVRAM data was not parsed above, do so now */
21877cb4d3eSLandon J. Fuller if (*data == NULL) {
21977cb4d3eSLandon J. Fuller if ((error = bhnd_nvram_data_new(cls, data, io)))
22077cb4d3eSLandon J. Fuller return (error);
22177cb4d3eSLandon J. Fuller }
22277cb4d3eSLandon J. Fuller
22377cb4d3eSLandon J. Fuller return (0);
22477cb4d3eSLandon J. Fuller }
22577cb4d3eSLandon J. Fuller
22677cb4d3eSLandon J. Fuller /**
227*591e79bcSLandon J. Fuller * Read a variable directly from @p io and decode as @p type.
228*591e79bcSLandon J. Fuller *
229*591e79bcSLandon J. Fuller * This may be used to perform reading of NVRAM variables during the very
230*591e79bcSLandon J. Fuller * early boot process, prior to the availability of the kernel allocator.
231*591e79bcSLandon J. Fuller *
232*591e79bcSLandon J. Fuller * @param cls An NVRAM class capable of parsing @p io.
233*591e79bcSLandon J. Fuller * @param io NVRAM data to be parsed.
234*591e79bcSLandon J. Fuller * @param name The raw name of the variable to be fetched,
235*591e79bcSLandon J. Fuller * including any device path (/pci/1/1/varname) or
236*591e79bcSLandon J. Fuller * alias prefix (0:varname).
237*591e79bcSLandon J. Fuller * @param[out] buf On success, the requested value will be written
238*591e79bcSLandon J. Fuller * to this buffer. This argment may be NULL if
239*591e79bcSLandon J. Fuller * the value is not desired.
240*591e79bcSLandon J. Fuller * @param[in,out] len The capacity of @p buf. On success, will be set
241*591e79bcSLandon J. Fuller * to the actual size of the requested value.
242*591e79bcSLandon J. Fuller * @param type The data type to be written to @p buf.
243*591e79bcSLandon J. Fuller *
244*591e79bcSLandon J. Fuller * @retval 0 success
245*591e79bcSLandon J. Fuller * @retval ENOMEM If @p buf is non-NULL and a buffer of @p len is too
246*591e79bcSLandon J. Fuller * small to hold the requested value.
247*591e79bcSLandon J. Fuller * @retval ENOENT If @p name is not found in @p io.
248*591e79bcSLandon J. Fuller * @retval EFTYPE If the variable data cannot be coerced to @p type.
249*591e79bcSLandon J. Fuller * @retval ERANGE If value coercion would overflow @p type.
250*591e79bcSLandon J. Fuller * @retval non-zero If parsing @p io otherwise fails, a regular unix error
251*591e79bcSLandon J. Fuller * code will be returned.
252*591e79bcSLandon J. Fuller */
253*591e79bcSLandon J. Fuller int
bhnd_nvram_data_getvar_direct(bhnd_nvram_data_class * cls,struct bhnd_nvram_io * io,const char * name,void * buf,size_t * len,bhnd_nvram_type type)254*591e79bcSLandon J. Fuller bhnd_nvram_data_getvar_direct(bhnd_nvram_data_class *cls,
255*591e79bcSLandon J. Fuller struct bhnd_nvram_io *io, const char *name, void *buf, size_t *len,
256*591e79bcSLandon J. Fuller bhnd_nvram_type type)
257*591e79bcSLandon J. Fuller {
258*591e79bcSLandon J. Fuller return (cls->op_getvar_direct(io, name, buf, len, type));
259*591e79bcSLandon J. Fuller }
260*591e79bcSLandon J. Fuller
261*591e79bcSLandon J. Fuller /**
26277cb4d3eSLandon J. Fuller * Allocate and initialize a new instance of data class @p cls, copying and
26377cb4d3eSLandon J. Fuller * parsing NVRAM data from @p io.
26477cb4d3eSLandon J. Fuller *
26577cb4d3eSLandon J. Fuller * The caller is responsible for releasing the returned parser instance
26677cb4d3eSLandon J. Fuller * reference via bhnd_nvram_data_release().
26777cb4d3eSLandon J. Fuller *
26877cb4d3eSLandon J. Fuller * @param cls If non-NULL, the data class to be allocated. If NULL,
26977cb4d3eSLandon J. Fuller * bhnd_nvram_data_probe_classes() will be used to determine the data format.
27077cb4d3eSLandon J. Fuller * @param[out] nv On success, a pointer to the newly allocated NVRAM data instance.
27177cb4d3eSLandon J. Fuller * @param io An I/O context mapping the NVRAM data to be copied and parsed.
27277cb4d3eSLandon J. Fuller *
27377cb4d3eSLandon J. Fuller * @retval 0 success
27477cb4d3eSLandon J. Fuller * @retval non-zero if an error occurs during allocation or initialization, a
27577cb4d3eSLandon J. Fuller * regular unix error code will be returned.
27677cb4d3eSLandon J. Fuller */
27777cb4d3eSLandon J. Fuller int
bhnd_nvram_data_new(bhnd_nvram_data_class * cls,struct bhnd_nvram_data ** nv,struct bhnd_nvram_io * io)27858efe686SLandon J. Fuller bhnd_nvram_data_new(bhnd_nvram_data_class *cls, struct bhnd_nvram_data **nv,
27958efe686SLandon J. Fuller struct bhnd_nvram_io *io)
28077cb4d3eSLandon J. Fuller {
28177cb4d3eSLandon J. Fuller struct bhnd_nvram_data *data;
28277cb4d3eSLandon J. Fuller int error;
28377cb4d3eSLandon J. Fuller
28477cb4d3eSLandon J. Fuller /* If NULL, try to identify the appropriate class */
28577cb4d3eSLandon J. Fuller if (cls == NULL)
28677cb4d3eSLandon J. Fuller return (bhnd_nvram_data_probe_classes(nv, io, NULL, 0));
28777cb4d3eSLandon J. Fuller
28877cb4d3eSLandon J. Fuller /* Allocate new instance */
28977cb4d3eSLandon J. Fuller BHND_NV_ASSERT(sizeof(struct bhnd_nvram_data) <= cls->size,
29077cb4d3eSLandon J. Fuller ("instance size %zu less than minimum %zu", cls->size,
29177cb4d3eSLandon J. Fuller sizeof(struct bhnd_nvram_data)));
29277cb4d3eSLandon J. Fuller
29377cb4d3eSLandon J. Fuller data = bhnd_nv_calloc(1, cls->size);
29477cb4d3eSLandon J. Fuller data->cls = cls;
29577cb4d3eSLandon J. Fuller refcount_init(&data->refs, 1);
29677cb4d3eSLandon J. Fuller
29777cb4d3eSLandon J. Fuller /* Let the class handle initialization */
29877cb4d3eSLandon J. Fuller if ((error = cls->op_new(data, io))) {
29977cb4d3eSLandon J. Fuller bhnd_nv_free(data);
30077cb4d3eSLandon J. Fuller return (error);
30177cb4d3eSLandon J. Fuller }
30277cb4d3eSLandon J. Fuller
30377cb4d3eSLandon J. Fuller *nv = data;
30477cb4d3eSLandon J. Fuller return (0);
30577cb4d3eSLandon J. Fuller }
30677cb4d3eSLandon J. Fuller
30777cb4d3eSLandon J. Fuller /**
30877cb4d3eSLandon J. Fuller * Retain and return a reference to the given data instance.
30977cb4d3eSLandon J. Fuller *
31077cb4d3eSLandon J. Fuller * @param nv The reference to be retained.
31177cb4d3eSLandon J. Fuller */
31277cb4d3eSLandon J. Fuller struct bhnd_nvram_data *
bhnd_nvram_data_retain(struct bhnd_nvram_data * nv)31377cb4d3eSLandon J. Fuller bhnd_nvram_data_retain(struct bhnd_nvram_data *nv)
31477cb4d3eSLandon J. Fuller {
31577cb4d3eSLandon J. Fuller refcount_acquire(&nv->refs);
31677cb4d3eSLandon J. Fuller return (nv);
31777cb4d3eSLandon J. Fuller }
31877cb4d3eSLandon J. Fuller
31977cb4d3eSLandon J. Fuller /**
32077cb4d3eSLandon J. Fuller * Release a reference to the given data instance.
32177cb4d3eSLandon J. Fuller *
32277cb4d3eSLandon J. Fuller * If this is the last reference, the data instance and its associated
32377cb4d3eSLandon J. Fuller * resources will be freed.
32477cb4d3eSLandon J. Fuller *
32577cb4d3eSLandon J. Fuller * @param nv The reference to be released.
32677cb4d3eSLandon J. Fuller */
32777cb4d3eSLandon J. Fuller void
bhnd_nvram_data_release(struct bhnd_nvram_data * nv)32877cb4d3eSLandon J. Fuller bhnd_nvram_data_release(struct bhnd_nvram_data *nv)
32977cb4d3eSLandon J. Fuller {
33077cb4d3eSLandon J. Fuller if (!refcount_release(&nv->refs))
33177cb4d3eSLandon J. Fuller return;
33277cb4d3eSLandon J. Fuller
33377cb4d3eSLandon J. Fuller /* Free any internal resources */
33477cb4d3eSLandon J. Fuller nv->cls->op_free(nv);
33577cb4d3eSLandon J. Fuller
33677cb4d3eSLandon J. Fuller /* Free the instance allocation */
33777cb4d3eSLandon J. Fuller bhnd_nv_free(nv);
33877cb4d3eSLandon J. Fuller }
33977cb4d3eSLandon J. Fuller
34077cb4d3eSLandon J. Fuller /**
34177cb4d3eSLandon J. Fuller * Return a pointer to @p nv's data class.
34277cb4d3eSLandon J. Fuller *
34377cb4d3eSLandon J. Fuller * @param nv The NVRAM data instance to be queried.
34477cb4d3eSLandon J. Fuller */
34558efe686SLandon J. Fuller bhnd_nvram_data_class *
bhnd_nvram_data_get_class(struct bhnd_nvram_data * nv)34658efe686SLandon J. Fuller bhnd_nvram_data_get_class(struct bhnd_nvram_data *nv)
34777cb4d3eSLandon J. Fuller {
34877cb4d3eSLandon J. Fuller return (nv->cls);
34977cb4d3eSLandon J. Fuller }
35077cb4d3eSLandon J. Fuller
35177cb4d3eSLandon J. Fuller /**
35277cb4d3eSLandon J. Fuller * Return the number of variables in @p nv.
35377cb4d3eSLandon J. Fuller *
35477cb4d3eSLandon J. Fuller * @param nv The NVRAM data to be queried.
35577cb4d3eSLandon J. Fuller */
35677cb4d3eSLandon J. Fuller size_t
bhnd_nvram_data_count(struct bhnd_nvram_data * nv)35777cb4d3eSLandon J. Fuller bhnd_nvram_data_count(struct bhnd_nvram_data *nv)
35877cb4d3eSLandon J. Fuller {
35977cb4d3eSLandon J. Fuller return (nv->cls->op_count(nv));
36077cb4d3eSLandon J. Fuller }
36177cb4d3eSLandon J. Fuller
36277cb4d3eSLandon J. Fuller /**
363a7c43ebdSLandon J. Fuller * Return a borrowed reference to the serialization options for @p nv,
364a7c43ebdSLandon J. Fuller * suitable for use with bhnd_nvram_data_serialize(), or NULL if none.
365a7c43ebdSLandon J. Fuller *
366a7c43ebdSLandon J. Fuller * @param nv The NVRAM data to be queried.
367a7c43ebdSLandon J. Fuller */
368a7c43ebdSLandon J. Fuller bhnd_nvram_plist *
bhnd_nvram_data_options(struct bhnd_nvram_data * nv)369a7c43ebdSLandon J. Fuller bhnd_nvram_data_options(struct bhnd_nvram_data *nv)
370a7c43ebdSLandon J. Fuller {
371a7c43ebdSLandon J. Fuller return (nv->cls->op_options(nv));
372a7c43ebdSLandon J. Fuller }
373a7c43ebdSLandon J. Fuller
374a7c43ebdSLandon J. Fuller /**
37577cb4d3eSLandon J. Fuller * Return the capability flags (@see BHND_NVRAM_DATA_CAP_*) for @p nv.
37677cb4d3eSLandon J. Fuller *
37777cb4d3eSLandon J. Fuller * @param nv The NVRAM data to be queried.
37877cb4d3eSLandon J. Fuller */
37977cb4d3eSLandon J. Fuller uint32_t
bhnd_nvram_data_caps(struct bhnd_nvram_data * nv)38077cb4d3eSLandon J. Fuller bhnd_nvram_data_caps(struct bhnd_nvram_data *nv)
38177cb4d3eSLandon J. Fuller {
38277cb4d3eSLandon J. Fuller return (nv->cls->op_caps(nv));
38377cb4d3eSLandon J. Fuller }
38477cb4d3eSLandon J. Fuller
38577cb4d3eSLandon J. Fuller /**
38677cb4d3eSLandon J. Fuller * Iterate over @p nv, returning the names of subsequent variables.
38777cb4d3eSLandon J. Fuller *
38877cb4d3eSLandon J. Fuller * @param nv The NVRAM data to be iterated.
38977cb4d3eSLandon J. Fuller * @param[in,out] cookiep A pointer to a cookiep value previously returned
39077cb4d3eSLandon J. Fuller * by bhnd_nvram_data_next(), or a NULL value to
39177cb4d3eSLandon J. Fuller * begin iteration.
39277cb4d3eSLandon J. Fuller *
39377cb4d3eSLandon J. Fuller * @return Returns the next variable name, or NULL if there are no more
39477cb4d3eSLandon J. Fuller * variables defined in @p nv.
39577cb4d3eSLandon J. Fuller */
39677cb4d3eSLandon J. Fuller const char *
bhnd_nvram_data_next(struct bhnd_nvram_data * nv,void ** cookiep)39777cb4d3eSLandon J. Fuller bhnd_nvram_data_next(struct bhnd_nvram_data *nv, void **cookiep)
39877cb4d3eSLandon J. Fuller {
39919be09f3SLandon J. Fuller const char *name;
40019be09f3SLandon J. Fuller #ifdef BHND_NV_INVARIANTS
40119be09f3SLandon J. Fuller void *prev = *cookiep;
40219be09f3SLandon J. Fuller #endif
40319be09f3SLandon J. Fuller
40419be09f3SLandon J. Fuller /* Fetch next */
40519be09f3SLandon J. Fuller if ((name = nv->cls->op_next(nv, cookiep)) == NULL)
40619be09f3SLandon J. Fuller return (NULL);
40719be09f3SLandon J. Fuller
40819be09f3SLandon J. Fuller /* Enforce precedence ordering invariant between bhnd_nvram_data_next()
40919be09f3SLandon J. Fuller * and bhnd_nvram_data_getvar_order() */
41019be09f3SLandon J. Fuller #ifdef BHND_NV_INVARIANTS
41119be09f3SLandon J. Fuller if (prev != NULL &&
41219be09f3SLandon J. Fuller bhnd_nvram_data_getvar_order(nv, prev, *cookiep) > 0)
41319be09f3SLandon J. Fuller {
41419be09f3SLandon J. Fuller BHND_NV_PANIC("%s: returned out-of-order entry", __FUNCTION__);
41519be09f3SLandon J. Fuller }
41619be09f3SLandon J. Fuller #endif
41719be09f3SLandon J. Fuller
41819be09f3SLandon J. Fuller return (name);
41977cb4d3eSLandon J. Fuller }
42077cb4d3eSLandon J. Fuller
42177cb4d3eSLandon J. Fuller /**
42277cb4d3eSLandon J. Fuller * Search @p nv for a named variable, returning the variable's opaque reference
42377cb4d3eSLandon J. Fuller * if found, or NULL if unavailable.
42477cb4d3eSLandon J. Fuller *
42577cb4d3eSLandon J. Fuller * The BHND_NVRAM_DATA_CAP_INDEXED capability flag will be returned by
42677cb4d3eSLandon J. Fuller * bhnd_nvram_data_caps() if @p nv supports effecient name-based
42777cb4d3eSLandon J. Fuller * lookups.
42877cb4d3eSLandon J. Fuller *
42977cb4d3eSLandon J. Fuller * @param nv The NVRAM data to search.
43077cb4d3eSLandon J. Fuller * @param name The name to search for.
43177cb4d3eSLandon J. Fuller *
43277cb4d3eSLandon J. Fuller * @retval non-NULL If @p name is found, the opaque cookie value will be
43377cb4d3eSLandon J. Fuller * returned.
43477cb4d3eSLandon J. Fuller * @retval NULL If @p name is not found.
43577cb4d3eSLandon J. Fuller */
43677cb4d3eSLandon J. Fuller void *
bhnd_nvram_data_find(struct bhnd_nvram_data * nv,const char * name)43777cb4d3eSLandon J. Fuller bhnd_nvram_data_find(struct bhnd_nvram_data *nv, const char *name)
43877cb4d3eSLandon J. Fuller {
43977cb4d3eSLandon J. Fuller return (nv->cls->op_find(nv, name));
44077cb4d3eSLandon J. Fuller }
44177cb4d3eSLandon J. Fuller
44277cb4d3eSLandon J. Fuller /**
44377cb4d3eSLandon J. Fuller * A generic implementation of bhnd_nvram_data_find().
44477cb4d3eSLandon J. Fuller *
44577cb4d3eSLandon J. Fuller * This implementation will use bhnd_nvram_data_next() to perform a
44677cb4d3eSLandon J. Fuller * simple O(n) case-insensitve search for @p name.
44777cb4d3eSLandon J. Fuller */
44877cb4d3eSLandon J. Fuller void *
bhnd_nvram_data_generic_find(struct bhnd_nvram_data * nv,const char * name)44977cb4d3eSLandon J. Fuller bhnd_nvram_data_generic_find(struct bhnd_nvram_data *nv, const char *name)
45077cb4d3eSLandon J. Fuller {
45177cb4d3eSLandon J. Fuller const char *next;
45277cb4d3eSLandon J. Fuller void *cookiep;
45377cb4d3eSLandon J. Fuller
45477cb4d3eSLandon J. Fuller cookiep = NULL;
45577cb4d3eSLandon J. Fuller while ((next = bhnd_nvram_data_next(nv, &cookiep))) {
45619be09f3SLandon J. Fuller if (strcmp(name, next) == 0)
45777cb4d3eSLandon J. Fuller return (cookiep);
45877cb4d3eSLandon J. Fuller }
45977cb4d3eSLandon J. Fuller
46077cb4d3eSLandon J. Fuller /* Not found */
46177cb4d3eSLandon J. Fuller return (NULL);
46277cb4d3eSLandon J. Fuller }
46377cb4d3eSLandon J. Fuller
46477cb4d3eSLandon J. Fuller /**
46519be09f3SLandon J. Fuller * Compare the declaration order of two NVRAM variables.
46619be09f3SLandon J. Fuller *
46719be09f3SLandon J. Fuller * Variable declaration order is used to determine the current order of
46819be09f3SLandon J. Fuller * the variables in the source data, as well as to determine the precedence
46919be09f3SLandon J. Fuller * of variable declarations in data sources that define duplicate names.
47019be09f3SLandon J. Fuller *
47119be09f3SLandon J. Fuller * The comparison order will match the order of variables returned via
47219be09f3SLandon J. Fuller * bhnd_nvstore_path_data_next().
47319be09f3SLandon J. Fuller *
47419be09f3SLandon J. Fuller * @param nv The NVRAM data.
47519be09f3SLandon J. Fuller * @param cookiep1 An NVRAM variable cookie previously
47619be09f3SLandon J. Fuller * returned via bhnd_nvram_data_next() or
47719be09f3SLandon J. Fuller * bhnd_nvram_data_find().
47819be09f3SLandon J. Fuller * @param cookiep2 An NVRAM variable cookie previously
47919be09f3SLandon J. Fuller * returned via bhnd_nvram_data_next() or
48019be09f3SLandon J. Fuller * bhnd_nvram_data_find().
48119be09f3SLandon J. Fuller *
48219be09f3SLandon J. Fuller * @retval <= -1 If @p cookiep1 has an earlier declaration order than
48319be09f3SLandon J. Fuller * @p cookiep2.
48419be09f3SLandon J. Fuller * @retval 0 If @p cookiep1 and @p cookiep2 are identical.
48519be09f3SLandon J. Fuller * @retval >= 1 If @p cookiep has a later declaration order than
48619be09f3SLandon J. Fuller * @p cookiep2.
48719be09f3SLandon J. Fuller */
48819be09f3SLandon J. Fuller int
bhnd_nvram_data_getvar_order(struct bhnd_nvram_data * nv,void * cookiep1,void * cookiep2)48919be09f3SLandon J. Fuller bhnd_nvram_data_getvar_order(struct bhnd_nvram_data *nv, void *cookiep1,
49019be09f3SLandon J. Fuller void *cookiep2)
49119be09f3SLandon J. Fuller {
49219be09f3SLandon J. Fuller return (nv->cls->op_getvar_order(nv, cookiep1, cookiep2));
49319be09f3SLandon J. Fuller }
49419be09f3SLandon J. Fuller
49519be09f3SLandon J. Fuller /**
49677cb4d3eSLandon J. Fuller * Read a variable and decode as @p type.
49777cb4d3eSLandon J. Fuller *
49877cb4d3eSLandon J. Fuller * @param nv The NVRAM data.
49977cb4d3eSLandon J. Fuller * @param cookiep An NVRAM variable cookie previously returned
50077cb4d3eSLandon J. Fuller * via bhnd_nvram_data_next() or
50177cb4d3eSLandon J. Fuller * bhnd_nvram_data_find().
50277cb4d3eSLandon J. Fuller * @param[out] buf On success, the requested value will be written
50377cb4d3eSLandon J. Fuller * to this buffer. This argment may be NULL if
50477cb4d3eSLandon J. Fuller * the value is not desired.
50577cb4d3eSLandon J. Fuller * @param[in,out] len The capacity of @p buf. On success, will be set
50677cb4d3eSLandon J. Fuller * to the actual size of the requested value.
50777cb4d3eSLandon J. Fuller * @param type The data type to be written to @p buf.
50877cb4d3eSLandon J. Fuller *
50977cb4d3eSLandon J. Fuller * @retval 0 success
51077cb4d3eSLandon J. Fuller * @retval ENOMEM If @p buf is non-NULL and a buffer of @p len is too
51177cb4d3eSLandon J. Fuller * small to hold the requested value.
51277cb4d3eSLandon J. Fuller * @retval EFTYPE If the variable data cannot be coerced to @p type.
51377cb4d3eSLandon J. Fuller * @retval ERANGE If value coercion would overflow @p type.
51477cb4d3eSLandon J. Fuller */
51577cb4d3eSLandon J. Fuller int
bhnd_nvram_data_getvar(struct bhnd_nvram_data * nv,void * cookiep,void * buf,size_t * len,bhnd_nvram_type type)51677cb4d3eSLandon J. Fuller bhnd_nvram_data_getvar(struct bhnd_nvram_data *nv, void *cookiep, void *buf,
51777cb4d3eSLandon J. Fuller size_t *len, bhnd_nvram_type type)
51877cb4d3eSLandon J. Fuller {
51977cb4d3eSLandon J. Fuller return (nv->cls->op_getvar(nv, cookiep, buf, len, type));
52077cb4d3eSLandon J. Fuller }
52177cb4d3eSLandon J. Fuller
52219be09f3SLandon J. Fuller /*
52319be09f3SLandon J. Fuller * Common bhnd_nvram_data_getvar_ptr() wrapper used by
52419be09f3SLandon J. Fuller * bhnd_nvram_data_generic_rp_getvar() and
52519be09f3SLandon J. Fuller * bhnd_nvram_data_generic_rp_copy_val().
52619be09f3SLandon J. Fuller *
52719be09f3SLandon J. Fuller * If a variable definition for the requested variable is found via
52819be09f3SLandon J. Fuller * bhnd_nvram_find_vardefn(), the definition will be used to populate fmt.
52919be09f3SLandon J. Fuller */
53019be09f3SLandon J. Fuller static const void *
bhnd_nvram_data_getvar_ptr_info(struct bhnd_nvram_data * nv,void * cookiep,size_t * len,bhnd_nvram_type * type,const bhnd_nvram_val_fmt ** fmt)53119be09f3SLandon J. Fuller bhnd_nvram_data_getvar_ptr_info(struct bhnd_nvram_data *nv, void *cookiep,
53219be09f3SLandon J. Fuller size_t *len, bhnd_nvram_type *type, const bhnd_nvram_val_fmt **fmt)
53319be09f3SLandon J. Fuller {
53419be09f3SLandon J. Fuller const struct bhnd_nvram_vardefn *vdefn;
53519be09f3SLandon J. Fuller const char *name;
53619be09f3SLandon J. Fuller const void *vptr;
53719be09f3SLandon J. Fuller
53819be09f3SLandon J. Fuller BHND_NV_ASSERT(bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_READ_PTR,
53919be09f3SLandon J. Fuller ("instance does not advertise READ_PTR support"));
54019be09f3SLandon J. Fuller
54119be09f3SLandon J. Fuller /* Fetch pointer to variable data */
54219be09f3SLandon J. Fuller vptr = bhnd_nvram_data_getvar_ptr(nv, cookiep, len, type);
54319be09f3SLandon J. Fuller if (vptr == NULL)
54419be09f3SLandon J. Fuller return (NULL);
54519be09f3SLandon J. Fuller
54619be09f3SLandon J. Fuller /* Select a default value format implementation */
54719be09f3SLandon J. Fuller
54819be09f3SLandon J. Fuller /* Fetch the reference variable name */
54919be09f3SLandon J. Fuller name = bhnd_nvram_data_getvar_name(nv, cookiep);
55019be09f3SLandon J. Fuller
55119be09f3SLandon J. Fuller /* Trim path prefix, if any; the Broadcom NVRAM format assumes a global
55219be09f3SLandon J. Fuller * namespace for all variable definitions */
55319be09f3SLandon J. Fuller if (bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_DEVPATHS)
55419be09f3SLandon J. Fuller name = bhnd_nvram_trim_path_name(name);
55519be09f3SLandon J. Fuller
55619be09f3SLandon J. Fuller /* Check the variable definition table for a matching entry; if
55719be09f3SLandon J. Fuller * it exists, use it to populate the value format. */
55819be09f3SLandon J. Fuller vdefn = bhnd_nvram_find_vardefn(name);
55919be09f3SLandon J. Fuller if (vdefn != NULL) {
56019be09f3SLandon J. Fuller BHND_NV_ASSERT(vdefn->fmt != NULL,
56119be09f3SLandon J. Fuller ("NULL format for %s", name));
56219be09f3SLandon J. Fuller *fmt = vdefn->fmt;
56319be09f3SLandon J. Fuller } else if (*type == BHND_NVRAM_TYPE_STRING) {
56419be09f3SLandon J. Fuller /* Default to Broadcom-specific string interpretation */
56519be09f3SLandon J. Fuller *fmt = &bhnd_nvram_val_bcm_string_fmt;
56619be09f3SLandon J. Fuller } else {
56719be09f3SLandon J. Fuller /* Fall back on native formatting */
56819be09f3SLandon J. Fuller *fmt = bhnd_nvram_val_default_fmt(*type);
56919be09f3SLandon J. Fuller }
57019be09f3SLandon J. Fuller
57119be09f3SLandon J. Fuller return (vptr);
57219be09f3SLandon J. Fuller }
57358efe686SLandon J. Fuller
57477cb4d3eSLandon J. Fuller /**
57577cb4d3eSLandon J. Fuller * A generic implementation of bhnd_nvram_data_getvar().
57677cb4d3eSLandon J. Fuller *
57777cb4d3eSLandon J. Fuller * This implementation will call bhnd_nvram_data_getvar_ptr() to fetch
57877cb4d3eSLandon J. Fuller * a pointer to the variable data and perform data coercion on behalf
57977cb4d3eSLandon J. Fuller * of the caller.
58077cb4d3eSLandon J. Fuller *
58177cb4d3eSLandon J. Fuller * If a variable definition for the requested variable is available via
58219be09f3SLandon J. Fuller * bhnd_nvram_find_vardefn(), the definition will be used to provide a
58319be09f3SLandon J. Fuller * formatting instance to bhnd_nvram_val_init().
58477cb4d3eSLandon J. Fuller */
58577cb4d3eSLandon J. Fuller int
bhnd_nvram_data_generic_rp_getvar(struct bhnd_nvram_data * nv,void * cookiep,void * outp,size_t * olen,bhnd_nvram_type otype)58677cb4d3eSLandon J. Fuller bhnd_nvram_data_generic_rp_getvar(struct bhnd_nvram_data *nv, void *cookiep,
58777cb4d3eSLandon J. Fuller void *outp, size_t *olen, bhnd_nvram_type otype)
58877cb4d3eSLandon J. Fuller {
58958efe686SLandon J. Fuller bhnd_nvram_val val;
59058efe686SLandon J. Fuller const bhnd_nvram_val_fmt *fmt;
59177cb4d3eSLandon J. Fuller const void *vptr;
59277cb4d3eSLandon J. Fuller bhnd_nvram_type vtype;
59377cb4d3eSLandon J. Fuller size_t vlen;
59477cb4d3eSLandon J. Fuller int error;
59577cb4d3eSLandon J. Fuller
59677cb4d3eSLandon J. Fuller BHND_NV_ASSERT(bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_READ_PTR,
59777cb4d3eSLandon J. Fuller ("instance does not advertise READ_PTR support"));
59877cb4d3eSLandon J. Fuller
59919be09f3SLandon J. Fuller /* Fetch variable data and value format*/
60019be09f3SLandon J. Fuller vptr = bhnd_nvram_data_getvar_ptr_info(nv, cookiep, &vlen, &vtype,
60119be09f3SLandon J. Fuller &fmt);
60277cb4d3eSLandon J. Fuller if (vptr == NULL)
60377cb4d3eSLandon J. Fuller return (EINVAL);
60477cb4d3eSLandon J. Fuller
60577cb4d3eSLandon J. Fuller /* Attempt value coercion */
60677cb4d3eSLandon J. Fuller error = bhnd_nvram_val_init(&val, fmt, vptr, vlen, vtype,
60777cb4d3eSLandon J. Fuller BHND_NVRAM_VAL_BORROW_DATA);
60877cb4d3eSLandon J. Fuller if (error)
60977cb4d3eSLandon J. Fuller return (error);
61077cb4d3eSLandon J. Fuller
61177cb4d3eSLandon J. Fuller error = bhnd_nvram_val_encode(&val, outp, olen, otype);
61277cb4d3eSLandon J. Fuller
61377cb4d3eSLandon J. Fuller /* Clean up */
61477cb4d3eSLandon J. Fuller bhnd_nvram_val_release(&val);
61577cb4d3eSLandon J. Fuller return (error);
61677cb4d3eSLandon J. Fuller }
61777cb4d3eSLandon J. Fuller
61877cb4d3eSLandon J. Fuller /**
61919be09f3SLandon J. Fuller * Return a caller-owned copy of an NVRAM entry's variable data.
62019be09f3SLandon J. Fuller *
62119be09f3SLandon J. Fuller * The caller is responsible for deallocating the returned value via
62219be09f3SLandon J. Fuller * bhnd_nvram_val_release().
62319be09f3SLandon J. Fuller *
62419be09f3SLandon J. Fuller * @param nv The NVRAM data.
62519be09f3SLandon J. Fuller * @param cookiep An NVRAM variable cookie previously returned
62619be09f3SLandon J. Fuller * via bhnd_nvram_data_next() or bhnd_nvram_data_find().
62719be09f3SLandon J. Fuller * @param[out] value On success, the caller-owned value instance.
62819be09f3SLandon J. Fuller *
62919be09f3SLandon J. Fuller * @retval 0 success
63019be09f3SLandon J. Fuller * @retval ENOMEM If allocation fails.
63119be09f3SLandon J. Fuller * @retval non-zero If initialization of the value otherwise fails, a
63219be09f3SLandon J. Fuller * regular unix error code will be returned.
63319be09f3SLandon J. Fuller */
63419be09f3SLandon J. Fuller int
bhnd_nvram_data_copy_val(struct bhnd_nvram_data * nv,void * cookiep,bhnd_nvram_val ** value)63519be09f3SLandon J. Fuller bhnd_nvram_data_copy_val(struct bhnd_nvram_data *nv, void *cookiep,
63619be09f3SLandon J. Fuller bhnd_nvram_val **value)
63719be09f3SLandon J. Fuller {
63819be09f3SLandon J. Fuller return (nv->cls->op_copy_val(nv, cookiep, value));
63919be09f3SLandon J. Fuller }
64019be09f3SLandon J. Fuller
64119be09f3SLandon J. Fuller /**
64219be09f3SLandon J. Fuller * A generic implementation of bhnd_nvram_data_copy_val().
64319be09f3SLandon J. Fuller *
64419be09f3SLandon J. Fuller * This implementation will call bhnd_nvram_data_getvar_ptr() to fetch
64519be09f3SLandon J. Fuller * a pointer to the variable data and perform data coercion on behalf
64619be09f3SLandon J. Fuller * of the caller.
64719be09f3SLandon J. Fuller *
64819be09f3SLandon J. Fuller * If a variable definition for the requested variable is available via
64919be09f3SLandon J. Fuller * bhnd_nvram_find_vardefn(), the definition will be used to provide a
65019be09f3SLandon J. Fuller * formatting instance to bhnd_nvram_val_init().
65119be09f3SLandon J. Fuller */
65219be09f3SLandon J. Fuller int
bhnd_nvram_data_generic_rp_copy_val(struct bhnd_nvram_data * nv,void * cookiep,bhnd_nvram_val ** value)65319be09f3SLandon J. Fuller bhnd_nvram_data_generic_rp_copy_val(struct bhnd_nvram_data *nv,
65419be09f3SLandon J. Fuller void *cookiep, bhnd_nvram_val **value)
65519be09f3SLandon J. Fuller {
65619be09f3SLandon J. Fuller const bhnd_nvram_val_fmt *fmt;
65719be09f3SLandon J. Fuller const void *vptr;
65819be09f3SLandon J. Fuller bhnd_nvram_type vtype;
65919be09f3SLandon J. Fuller size_t vlen;
66019be09f3SLandon J. Fuller
66119be09f3SLandon J. Fuller BHND_NV_ASSERT(bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_READ_PTR,
66219be09f3SLandon J. Fuller ("instance does not advertise READ_PTR support"));
66319be09f3SLandon J. Fuller
66419be09f3SLandon J. Fuller /* Fetch variable data and value format*/
66519be09f3SLandon J. Fuller vptr = bhnd_nvram_data_getvar_ptr_info(nv, cookiep, &vlen, &vtype,
66619be09f3SLandon J. Fuller &fmt);
66719be09f3SLandon J. Fuller if (vptr == NULL)
66819be09f3SLandon J. Fuller return (EINVAL);
66919be09f3SLandon J. Fuller
67019be09f3SLandon J. Fuller /* Allocate and return the new value instance */
67119be09f3SLandon J. Fuller return (bhnd_nvram_val_new(value, fmt, vptr, vlen, vtype,
67219be09f3SLandon J. Fuller BHND_NVRAM_VAL_DYNAMIC));
67319be09f3SLandon J. Fuller }
67419be09f3SLandon J. Fuller
67519be09f3SLandon J. Fuller /**
67677cb4d3eSLandon J. Fuller * If available and supported by the NVRAM data instance, return a reference
67777cb4d3eSLandon J. Fuller * to the internal buffer containing an entry's variable data,
67877cb4d3eSLandon J. Fuller *
67977cb4d3eSLandon J. Fuller * Note that string values may not be NUL terminated.
68077cb4d3eSLandon J. Fuller *
68177cb4d3eSLandon J. Fuller * @param nv The NVRAM data.
68277cb4d3eSLandon J. Fuller * @param cookiep An NVRAM variable cookie previously returned
68377cb4d3eSLandon J. Fuller * via bhnd_nvram_data_next() or
68477cb4d3eSLandon J. Fuller * bhnd_nvram_data_find().
68577cb4d3eSLandon J. Fuller * @param[out] len On success, will be set to the actual size of
68677cb4d3eSLandon J. Fuller * the requested value.
68777cb4d3eSLandon J. Fuller * @param[out] type The data type of the entry data.
68877cb4d3eSLandon J. Fuller *
68977cb4d3eSLandon J. Fuller * @retval non-NULL success
69077cb4d3eSLandon J. Fuller * @retval NULL if direct data access is unsupported by @p nv, or
69177cb4d3eSLandon J. Fuller * unavailable for @p cookiep.
69277cb4d3eSLandon J. Fuller */
69377cb4d3eSLandon J. Fuller const void *
bhnd_nvram_data_getvar_ptr(struct bhnd_nvram_data * nv,void * cookiep,size_t * len,bhnd_nvram_type * type)69477cb4d3eSLandon J. Fuller bhnd_nvram_data_getvar_ptr(struct bhnd_nvram_data *nv, void *cookiep,
69577cb4d3eSLandon J. Fuller size_t *len, bhnd_nvram_type *type)
69677cb4d3eSLandon J. Fuller {
69777cb4d3eSLandon J. Fuller return (nv->cls->op_getvar_ptr(nv, cookiep, len, type));
69877cb4d3eSLandon J. Fuller }
69977cb4d3eSLandon J. Fuller
70077cb4d3eSLandon J. Fuller /**
70177cb4d3eSLandon J. Fuller * Return the variable name associated with a given @p cookiep.
70277cb4d3eSLandon J. Fuller * @param nv The NVRAM data to be iterated.
70377cb4d3eSLandon J. Fuller * @param[in,out] cookiep A pointer to a cookiep value previously returned
70477cb4d3eSLandon J. Fuller * via bhnd_nvram_data_next() or
70577cb4d3eSLandon J. Fuller * bhnd_nvram_data_find().
70677cb4d3eSLandon J. Fuller *
70777cb4d3eSLandon J. Fuller * @return Returns the variable's name.
70877cb4d3eSLandon J. Fuller */
70977cb4d3eSLandon J. Fuller const char *
bhnd_nvram_data_getvar_name(struct bhnd_nvram_data * nv,void * cookiep)71077cb4d3eSLandon J. Fuller bhnd_nvram_data_getvar_name(struct bhnd_nvram_data *nv, void *cookiep)
71177cb4d3eSLandon J. Fuller {
71277cb4d3eSLandon J. Fuller return (nv->cls->op_getvar_name(nv, cookiep));
71377cb4d3eSLandon J. Fuller }
71419be09f3SLandon J. Fuller
71519be09f3SLandon J. Fuller /**
71619be09f3SLandon J. Fuller * Filter a request to set variable @p name with @p value.
71719be09f3SLandon J. Fuller *
71819be09f3SLandon J. Fuller * On success, the caller owns a reference to @p result, and must release
71919be09f3SLandon J. Fuller * any held resources via bhnd_nvram_val_release().
72019be09f3SLandon J. Fuller *
72119be09f3SLandon J. Fuller * @param nv The NVRAM data instance.
72219be09f3SLandon J. Fuller * @param name The name of the variable to be set.
72319be09f3SLandon J. Fuller * @param value The proposed value to be set.
72419be09f3SLandon J. Fuller * @param[out] result On success, a caller-owned reference to the filtered
72519be09f3SLandon J. Fuller * value to be set.
72619be09f3SLandon J. Fuller *
72719be09f3SLandon J. Fuller * @retval 0 success
72819be09f3SLandon J. Fuller * @retval ENOENT if @p name is unrecognized by @p nv.
72919be09f3SLandon J. Fuller * @retval EINVAL if @p name is read-only.
73019be09f3SLandon J. Fuller * @retval EINVAL if @p value cannot be converted to the required value
73119be09f3SLandon J. Fuller * type.
73219be09f3SLandon J. Fuller */
73319be09f3SLandon J. Fuller int
bhnd_nvram_data_filter_setvar(struct bhnd_nvram_data * nv,const char * name,bhnd_nvram_val * value,bhnd_nvram_val ** result)73419be09f3SLandon J. Fuller bhnd_nvram_data_filter_setvar(struct bhnd_nvram_data *nv, const char *name,
73519be09f3SLandon J. Fuller bhnd_nvram_val *value, bhnd_nvram_val **result)
73619be09f3SLandon J. Fuller {
73719be09f3SLandon J. Fuller return (nv->cls->op_filter_setvar(nv, name, value, result));
73819be09f3SLandon J. Fuller }
73919be09f3SLandon J. Fuller
74019be09f3SLandon J. Fuller /**
74119be09f3SLandon J. Fuller * Filter a request to delete variable @p name.
74219be09f3SLandon J. Fuller *
74319be09f3SLandon J. Fuller * @param nv The NVRAM data instance.
74419be09f3SLandon J. Fuller * @param name The name of the variable to be deleted.
74519be09f3SLandon J. Fuller *
74619be09f3SLandon J. Fuller * @retval 0 success
74719be09f3SLandon J. Fuller * @retval ENOENT if @p name is unrecognized by @p nv.
74819be09f3SLandon J. Fuller * @retval EINVAL if @p name is read-only.
74919be09f3SLandon J. Fuller */
75019be09f3SLandon J. Fuller int
bhnd_nvram_data_filter_unsetvar(struct bhnd_nvram_data * nv,const char * name)75119be09f3SLandon J. Fuller bhnd_nvram_data_filter_unsetvar(struct bhnd_nvram_data *nv, const char *name)
75219be09f3SLandon J. Fuller {
75319be09f3SLandon J. Fuller return (nv->cls->op_filter_unsetvar(nv, name));
75419be09f3SLandon J. Fuller }
755