The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/bhnd/nvram/bhnd_nvram_data.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.