コード例 #1
0
ファイル: bhnd_nvram_subr.c プロジェクト: kwitaszczyk/freebsd
/**
 * Iterate over all strings in the @p inp string array.
 *
 * @param	inp	The string array to be iterated. This must be a buffer
 *			of one or more NUL-terminated strings --
 *			@see BHND_NVRAM_TYPE_STRING_ARRAY.
 * @param	ilen	The size, in bytes, of @p inp, including any
 *			terminating NUL character(s).
 * @param	prev	The value previously returned by
 *			bhnd_nvram_string_array_next(), or NULL to begin
 *			iteration.
 *
 * @retval non-NULL	A reference to the next NUL-terminated string
 * @retval NULL		If the end of the string array is reached.
 */
const char *
bhnd_nvram_string_array_next(const char *inp, size_t ilen, const char *prev)
{
	size_t nremain, plen;

	if (ilen == 0)
		return (NULL);

	if (prev == NULL)
		return (inp);

	/* Advance to next value */
	BHND_NV_ASSERT(prev >= inp, ("invalid prev pointer"));
	BHND_NV_ASSERT(prev < (inp+ilen), ("invalid prev pointer"));

	nremain = ilen - (size_t)(prev - inp);
	plen = strnlen(prev, nremain);
	nremain -= plen;

	/* Only a trailing NUL remains? */
	if (nremain <= 1)
		return (NULL);

	return (prev + plen + 1);
}
コード例 #2
0
ファイル: bhnd_nvram_subr.c プロジェクト: kwitaszczyk/freebsd
/**
 * Return true if @p type is a signed integer type, false otherwise.
 * 
 * Will return false for all array types.
 * 
 * @param type The type to query.
 */
bool
bhnd_nvram_is_signed_type(bhnd_nvram_type type)
{
	switch (type) {
	case BHND_NVRAM_TYPE_INT8:
	case BHND_NVRAM_TYPE_INT16:
	case BHND_NVRAM_TYPE_INT32:
	case BHND_NVRAM_TYPE_INT64:
		BHND_NV_ASSERT(bhnd_nvram_is_int_type(type), ("non-int type?"));
		return (true);

	case BHND_NVRAM_TYPE_CHAR:
	case BHND_NVRAM_TYPE_UINT8:
	case BHND_NVRAM_TYPE_UINT16:
	case BHND_NVRAM_TYPE_UINT32:
	case BHND_NVRAM_TYPE_UINT64:
	case BHND_NVRAM_TYPE_STRING:
	case BHND_NVRAM_TYPE_UINT8_ARRAY:
	case BHND_NVRAM_TYPE_UINT16_ARRAY:
	case BHND_NVRAM_TYPE_UINT32_ARRAY:
	case BHND_NVRAM_TYPE_UINT64_ARRAY:
	case BHND_NVRAM_TYPE_INT8_ARRAY:
	case BHND_NVRAM_TYPE_INT16_ARRAY:
	case BHND_NVRAM_TYPE_INT32_ARRAY:
	case BHND_NVRAM_TYPE_INT64_ARRAY:
	case BHND_NVRAM_TYPE_CHAR_ARRAY:
	case BHND_NVRAM_TYPE_STRING_ARRAY:
		return (false);
	}

	/* Quiesce gcc4.2 */
	BHND_NV_PANIC("bhnd nvram type %u unknown", type);
}
コード例 #3
0
/**
 * A generic implementation of bhnd_nvram_data_getvar().
 * 
 * This implementation will call bhnd_nvram_data_getvar_ptr() to fetch
 * a pointer to the variable data and perform data coercion on behalf
 * of the caller.
 *
 * If a variable definition for the requested variable is available via
 * bhnd_nvram_find_vardefn(), the definition will be used to provide a
 * formatting instance to bhnd_nvram_val_init().
 */
int
bhnd_nvram_data_generic_rp_getvar(struct bhnd_nvram_data *nv, void *cookiep,
    void *outp, size_t *olen, bhnd_nvram_type otype)
{
	bhnd_nvram_val			 val;
	const bhnd_nvram_val_fmt	*fmt;
	const void			*vptr;
	bhnd_nvram_type			 vtype;
	size_t				 vlen;
	int				 error;

	BHND_NV_ASSERT(bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_READ_PTR,
	    ("instance does not advertise READ_PTR support"));

	/* Fetch variable data and value format*/
	vptr = bhnd_nvram_data_getvar_ptr_info(nv, cookiep, &vlen, &vtype,
	    &fmt);
	if (vptr == NULL)
		return (EINVAL);

	/* Attempt value coercion */
	error = bhnd_nvram_val_init(&val, fmt, vptr, vlen, vtype,
	    BHND_NVRAM_VAL_BORROW_DATA);
	if (error)
		return (error);

	error = bhnd_nvram_val_encode(&val, outp, olen, otype);

	/* Clean up */
	bhnd_nvram_val_release(&val);
	return (error);
}
コード例 #4
0
/**
 * Allocate and initialize a new instance of data class @p cls, copying and
 * parsing NVRAM data from @p io.
 *
 * The caller is responsible for releasing the returned parser instance
 * reference via bhnd_nvram_data_release().
 * 
 * @param cls If non-NULL, the data class to be allocated. If NULL,
 * bhnd_nvram_data_probe_classes() will be used to determine the data format.
 * @param[out] nv On success, a pointer to the newly allocated NVRAM data instance.
 * @param io An I/O context mapping the NVRAM data to be copied and parsed.
 * 
 * @retval 0 success
 * @retval non-zero if an error occurs during allocation or initialization, a
 * regular unix error code will be returned.
 */
int
bhnd_nvram_data_new(bhnd_nvram_data_class *cls, struct bhnd_nvram_data **nv,
    struct bhnd_nvram_io *io)
{
	struct bhnd_nvram_data	*data;
	int			 error;

	/* If NULL, try to identify the appropriate class */
	if (cls == NULL)
		return (bhnd_nvram_data_probe_classes(nv, io, NULL, 0));

	/* Allocate new instance */
	BHND_NV_ASSERT(sizeof(struct bhnd_nvram_data) <= cls->size,
	    ("instance size %zu less than minimum %zu", cls->size,
	     sizeof(struct bhnd_nvram_data)));

	data = bhnd_nv_calloc(1, cls->size);
	data->cls = cls;
	refcount_init(&data->refs, 1);

	/* Let the class handle initialization */
	if ((error = cls->op_new(data, io))) {
		bhnd_nv_free(data);
		return (error);
	}

	*nv = data;
	return (0);
}
コード例 #5
0
/*
 * Common bhnd_nvram_data_getvar_ptr() wrapper used by
 * bhnd_nvram_data_generic_rp_getvar() and
 * bhnd_nvram_data_generic_rp_copy_val().
 *
 * If a variable definition for the requested variable is found via
 * bhnd_nvram_find_vardefn(), the definition will be used to populate fmt.
 */
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)
{
	const struct bhnd_nvram_vardefn	*vdefn;
	const char			*name;
	const void			*vptr;

	BHND_NV_ASSERT(bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_READ_PTR,
	    ("instance does not advertise READ_PTR support"));

	/* Fetch pointer to variable data */
	vptr = bhnd_nvram_data_getvar_ptr(nv, cookiep, len, type);
	if (vptr == NULL)
		return (NULL);

	/* Select a default value format implementation */


	/* Fetch the reference variable name */
	name = bhnd_nvram_data_getvar_name(nv, cookiep);

	/* Trim path prefix, if any; the Broadcom NVRAM format assumes a global
	 * namespace for all variable definitions */
	if (bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_DEVPATHS)
		name = bhnd_nvram_trim_path_name(name);

	/* Check the variable definition table for a matching entry; if
	 * it exists, use it to populate the value format. */
	vdefn = bhnd_nvram_find_vardefn(name);
	if (vdefn != NULL) {
		BHND_NV_ASSERT(vdefn->fmt != NULL,
		    ("NULL format for %s", name));
		*fmt = vdefn->fmt;
	} else if (*type == BHND_NVRAM_TYPE_STRING) {
		/* Default to Broadcom-specific string interpretation */
		*fmt = &bhnd_nvram_val_bcm_string_fmt;
	} else {
		/* Fall back on native formatting */
		*fmt = bhnd_nvram_val_default_fmt(*type);
	}

	return (vptr);
}
コード例 #6
0
ファイル: bhnd_nvram_subr.c プロジェクト: kwitaszczyk/freebsd
/**
 * Return the variable ID for a variable definition.
 * 
 * @param defn Variable definition previously returned by
 * bhnd_nvram_find_vardefn() or bhnd_nvram_get_vardefn().
 */
size_t
bhnd_nvram_get_vardefn_id(const struct bhnd_nvram_vardefn *defn)
{
	BHND_NV_ASSERT(
	    defn >= bhnd_nvram_vardefns &&
	    defn <= &bhnd_nvram_vardefns[bhnd_nvram_num_vardefns-1],
	    ("invalid variable definition pointer %p", defn));

	return (defn - bhnd_nvram_vardefns);
}
コード例 #7
0
/**
 * A generic implementation of bhnd_nvram_data_copy_val().
 * 
 * This implementation will call bhnd_nvram_data_getvar_ptr() to fetch
 * a pointer to the variable data and perform data coercion on behalf
 * of the caller.
 *
 * If a variable definition for the requested variable is available via
 * bhnd_nvram_find_vardefn(), the definition will be used to provide a
 * formatting instance to bhnd_nvram_val_init().
 */
int
bhnd_nvram_data_generic_rp_copy_val(struct bhnd_nvram_data *nv,
    void *cookiep, bhnd_nvram_val **value)
{
	const bhnd_nvram_val_fmt	*fmt;
	const void			*vptr;
	bhnd_nvram_type			 vtype;
	size_t				 vlen;

	BHND_NV_ASSERT(bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_READ_PTR,
	    ("instance does not advertise READ_PTR support"));

	/* Fetch variable data and value format*/
	vptr = bhnd_nvram_data_getvar_ptr_info(nv, cookiep, &vlen, &vtype,
	    &fmt);
	if (vptr == NULL)
		return (EINVAL);

	/* Allocate and return the new value instance */
	return (bhnd_nvram_val_new(value, fmt, vptr, vlen, vtype,
	    BHND_NVRAM_VAL_DYNAMIC));
}
コード例 #8
0
ファイル: bhnd_nvram_subr.c プロジェクト: kwitaszczyk/freebsd
/**
 * Calculate the number of elements represented by a value of @p len bytes
 * with @p type.
 *
 * @param	type	The value type.
 * @param	data	The actual data to be queried, or NULL if unknown.
 * @param	len	The length in bytes of @p data, or if @p data is NULL,
 *			the expected length in bytes.
 * @param[out]	nelem	On success, the number of elements. If @p type is not
 *			a fixed width type (e.g. BHND_NVRAM_TYPE_STRING_ARRAY),
 *			and @p data is NULL, an @p nelem value of 0 will be
 *			returned.
 *
 * @retval 0		success
 * @retval EFTYPE	if @p type is not an array type, and @p len is not
 *			equal to the size of a single element of @p type.
 * @retval EFAULT	if @p len is not correctly aligned for elements of
 *			@p type.
 */
int
bhnd_nvram_value_nelem(bhnd_nvram_type type, const void *data, size_t len,
    size_t *nelem)
{
	bhnd_nvram_type	base_type;
	size_t		base_size;

	/* Length must be aligned to the element size */
	base_type = bhnd_nvram_base_type(type);
	base_size = bhnd_nvram_value_size(base_type, NULL, 0, 1);
	if (base_size != 0 && len % base_size != 0)
		return (EFAULT);

	switch (type) {
	case BHND_NVRAM_TYPE_STRING:
	case BHND_NVRAM_TYPE_STRING_ARRAY: {
		const char	*p;
		size_t		 nleft;

		/* Cannot determine the element count without parsing
		 * the actual data */
		if (data == NULL) {
			*nelem = 0;
			return (0);
		}

		/* Iterate over the NUL-terminated strings to calculate
		 * total element count */
		p = data;
		nleft = len;
		*nelem = 0;
		while (nleft > 0) {
			size_t slen;

			/* Increment element count */
			(*nelem)++;

			/* If not a string array, data must not contain more
			 * than one entry. */
			if (!bhnd_nvram_is_array_type(type) && *nelem > 1)
				return (EFTYPE);

			/* Determine string length */
			slen = strnlen(p, nleft);
			nleft -= slen;
	
			/* Advance input */
			p += slen;

			/* Account for trailing NUL, if we haven't hit the end
			 * of the input */
			if (nleft > 0) {
				nleft--;
				p++;
			}
		}

		return (0);
	}
	case BHND_NVRAM_TYPE_INT8:
	case BHND_NVRAM_TYPE_UINT8:
	case BHND_NVRAM_TYPE_CHAR:
	case BHND_NVRAM_TYPE_INT16:
	case BHND_NVRAM_TYPE_UINT16:
	case BHND_NVRAM_TYPE_INT32:
	case BHND_NVRAM_TYPE_UINT32:
	case BHND_NVRAM_TYPE_INT64:
	case BHND_NVRAM_TYPE_UINT64:
		/* Length must be equal to the size of exactly one
		 * element (arrays can represent zero elements -- non-array
		 * types cannot) */
		if (len != base_size)
			return (EFTYPE);
		*nelem = 1;
		return (0);

	case BHND_NVRAM_TYPE_UINT8_ARRAY:
	case BHND_NVRAM_TYPE_UINT16_ARRAY:
	case BHND_NVRAM_TYPE_UINT32_ARRAY:
	case BHND_NVRAM_TYPE_UINT64_ARRAY:
	case BHND_NVRAM_TYPE_INT8_ARRAY:
	case BHND_NVRAM_TYPE_INT16_ARRAY:
	case BHND_NVRAM_TYPE_INT32_ARRAY:
	case BHND_NVRAM_TYPE_INT64_ARRAY:
	case BHND_NVRAM_TYPE_CHAR_ARRAY:
		BHND_NV_ASSERT(base_size != 0, ("invalid base size"));
		*nelem = len / base_size;
		return (0);
	}

	/* Quiesce gcc4.2 */
	BHND_NV_PANIC("bhnd nvram type %u unknown", type);
}