svn commit: r310294 - in head/sys: conf dev/bhnd/nvram modules/bhnd

Landon J. Fuller landonf at FreeBSD.org
Mon Dec 19 20:26:12 UTC 2016


Author: landonf
Date: Mon Dec 19 20:26:10 2016
New Revision: 310294
URL: https://svnweb.freebsd.org/changeset/base/310294

Log:
  bhnd(4): add support for wrapping arbitrary pointers in an NVRAM I/O
  context.
  
  Approved by:	adrian (mentor)
  Differential Revision:	 https://reviews.freebsd.org/D8759

Added:
  head/sys/dev/bhnd/nvram/bhnd_nvram_ioptr.c   (contents, props changed)
Modified:
  head/sys/conf/files
  head/sys/dev/bhnd/nvram/bhnd_nvram_io.h
  head/sys/modules/bhnd/Makefile

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Mon Dec 19 20:23:19 2016	(r310293)
+++ head/sys/conf/files	Mon Dec 19 20:26:10 2016	(r310294)
@@ -1240,6 +1240,7 @@ dev/bhnd/nvram/bhnd_nvram_data_tlv.c	opt
 dev/bhnd/nvram/bhnd_nvram_if.m		optional bhnd
 dev/bhnd/nvram/bhnd_nvram_io.c		optional bhnd
 dev/bhnd/nvram/bhnd_nvram_iobuf.c	optional bhnd
+dev/bhnd/nvram/bhnd_nvram_ioptr.c	optional bhnd
 dev/bhnd/nvram/bhnd_nvram_iores.c	optional bhnd
 dev/bhnd/nvram/bhnd_nvram_plist.c	optional bhnd
 dev/bhnd/nvram/bhnd_nvram_store.c	optional bhnd

Modified: head/sys/dev/bhnd/nvram/bhnd_nvram_io.h
==============================================================================
--- head/sys/dev/bhnd/nvram/bhnd_nvram_io.h	Mon Dec 19 20:23:19 2016	(r310293)
+++ head/sys/dev/bhnd/nvram/bhnd_nvram_io.h	Mon Dec 19 20:26:10 2016	(r310294)
@@ -52,6 +52,9 @@ struct bhnd_nvram_io	*bhnd_nvram_iobuf_c
 struct bhnd_nvram_io	*bhnd_nvram_iobuf_copy_range(struct bhnd_nvram_io *src,
 			     size_t offset, size_t size);
 
+struct bhnd_nvram_io	*bhnd_nvram_ioptr_new(const void *ptr, size_t size,
+			     size_t capacity, uint32_t flags);
+
 #ifdef _KERNEL
 struct bhnd_nvram_io	*bhnd_nvram_iores_new(struct bhnd_resource *r,
 			     bus_size_t offset, bus_size_t size,
@@ -76,4 +79,12 @@ int			 bhnd_nvram_io_write_ptr(struct bh
 
 void			 bhnd_nvram_io_free(struct bhnd_nvram_io *io);
 
+/**
+ * bhnd_nvram_ioptr flags
+ */
+enum {
+	BHND_NVRAM_IOPTR_RDONLY	= (1<<0),	/**< read-only */
+	BHND_NVRAM_IOPTR_RDWR	= (1<<1),	/**< read/write */
+};
+
 #endif /* _BHND_NVRAM_BHND_NVRAM_IO_H_ */

Added: head/sys/dev/bhnd/nvram/bhnd_nvram_ioptr.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/bhnd/nvram/bhnd_nvram_ioptr.c	Mon Dec 19 20:26:10 2016	(r310294)
@@ -0,0 +1,228 @@
+/*-
+ * Copyright (c) 2016 Landon Fuller <landonf at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifdef _KERNEL
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+#else /* !_KERNEL */
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#endif /* _KERNEL */
+
+#include "bhnd_nvram_private.h"
+
+#include "bhnd_nvram_io.h"
+#include "bhnd_nvram_iovar.h"
+
+/**
+ * Memory-backed NVRAM I/O context.
+ *
+ * ioptr instances are gauranteed to provide persistent references to its
+ * backing contigious memory via bhnd_nvram_io_read_ptr() and
+ * bhnd_nvram_io_write_ptr().
+ */
+struct bhnd_nvram_ioptr {
+	struct bhnd_nvram_io	 io;		/**< common I/O instance state */
+	void			*ptr;		/**< backing memory */
+	size_t			 size;		/**< size at @p ptr */
+	size_t			 capacity;	/**< capacity at @p ptr */
+	uint32_t		 flags;		/**< flags (see BHND_NVRAM_IOPTR_*) */
+};
+
+BHND_NVRAM_IOPS_DEFN(ioptr)
+
+/**
+ * Allocate and return a new I/O context, mapping @p size bytes at @p ptr.
+ 
+ * The caller is responsible for deallocating the returned I/O context via
+ * bhnd_nvram_io_free().
+ *
+ * @param	ptr		The pointer to be mapped by the returned I/O
+ *				context. Must remain valid for the lifetime of
+ *				the returned I/O context.
+ * @param	size		The total number of bytes mapped at @p ptr.
+ * @param	capacity	The maximum number of bytes that may be mapped
+ *				at @p ptr via bhnd_nvram_ioptr_setsize().
+ * @param	flags		Access flags (see BHND_NVRAM_IOPTR_*).
+ *
+ * @retval	bhnd_nvram_io	success.
+ * @retval	NULL		allocation failed.
+ * @retval	NULL		the requested @p capacity is less than @p size.
+ */
+struct bhnd_nvram_io *
+bhnd_nvram_ioptr_new(const void *ptr, size_t size, size_t capacity,
+    uint32_t flags)
+{
+	struct bhnd_nvram_ioptr	*ioptr;
+
+	/* Sanity check the capacity */
+	if (size > capacity)
+		return (NULL);
+	
+	/* Allocate I/O context */
+	ioptr = bhnd_nv_malloc(sizeof(*ioptr));
+	if (ioptr == NULL)
+		return (NULL);
+	
+	ioptr->io.iops = &bhnd_nvram_ioptr_ops;
+	ioptr->ptr = __DECONST(void *, ptr);
+	ioptr->size = size;
+	ioptr->capacity = capacity;
+	ioptr->flags = flags;
+
+	return (&ioptr->io);
+}
+
+static void
+bhnd_nvram_ioptr_free(struct bhnd_nvram_io *io)
+{	
+	bhnd_nv_free(io);
+}
+
+static size_t
+bhnd_nvram_ioptr_getsize(struct bhnd_nvram_io *io)
+{
+	struct bhnd_nvram_ioptr	*ioptr = (struct bhnd_nvram_ioptr *)io;
+	return (ioptr->size);
+}
+
+static int
+bhnd_nvram_ioptr_setsize(struct bhnd_nvram_io *io, size_t size)
+{
+	struct bhnd_nvram_ioptr	*ioptr = (struct bhnd_nvram_ioptr *)io;
+
+	/* Must be writable */
+	if (!(ioptr->flags & BHND_NVRAM_IOPTR_RDWR))
+		return (ENODEV);
+	
+	/* Can't exceed the actual capacity */
+	if (size > ioptr->capacity)
+		return (ENXIO);
+	
+	ioptr->size = size;
+	return (0);
+}
+
+/* Common ioptr_(read|write)_ptr implementation */
+static int
+bhnd_nvram_ioptr_ptr(struct bhnd_nvram_ioptr *ioptr, size_t offset, void **ptr,
+		     size_t nbytes, size_t *navail)
+{
+	size_t avail;
+	
+	/* Verify offset+nbytes fall within the buffer range */
+	if (offset > ioptr->size)
+		return (ENXIO);
+	
+	avail = ioptr->size - offset;
+	if (avail < nbytes)
+		return (ENXIO);
+	
+	/* Valid I/O range, provide a pointer to the buffer and the
+	 * total count of available bytes */
+	*ptr = ((uint8_t *)ioptr->ptr) + offset;
+	if (navail != NULL)
+		*navail = avail;
+	
+	return (0);
+}
+
+static int
+bhnd_nvram_ioptr_read_ptr(struct bhnd_nvram_io *io, size_t offset,
+			  const void **ptr, size_t nbytes, size_t *navail)
+{
+	struct bhnd_nvram_ioptr	*ioptr;
+	void			*writep;
+	int			 error;
+	
+	ioptr = (struct bhnd_nvram_ioptr *) io;
+	
+	/* Return a pointer into our backing buffer */
+	error = bhnd_nvram_ioptr_ptr(ioptr, offset, &writep, nbytes, navail);
+	if (error)
+		return (error);
+	
+	*ptr = writep;
+	
+	return (0);
+}
+
+static int
+bhnd_nvram_ioptr_write_ptr(struct bhnd_nvram_io *io, size_t offset,
+			   void **ptr, size_t nbytes, size_t *navail)
+{
+	struct bhnd_nvram_ioptr	*ioptr;
+	
+	ioptr = (struct bhnd_nvram_ioptr *) io;
+
+	/* Must be writable */
+	if (!(ioptr->flags & BHND_NVRAM_IOPTR_RDWR))
+		return (ENODEV);
+	
+	/* Return a pointer into our backing buffer */
+	return (bhnd_nvram_ioptr_ptr(ioptr, offset, ptr, nbytes, navail));
+}
+
+static int
+bhnd_nvram_ioptr_read(struct bhnd_nvram_io *io, size_t offset, void *buffer,
+		      size_t nbytes)
+{
+	const void	*ptr;
+	int		 error;
+	
+	/* Try to fetch a direct pointer for at least nbytes */
+	if ((error = bhnd_nvram_io_read_ptr(io, offset, &ptr, nbytes, NULL)))
+		return (error);
+	
+	/* Copy out the requested data */
+	memcpy(buffer, ptr, nbytes);
+	return (0);
+}
+
+static int
+bhnd_nvram_ioptr_write(struct bhnd_nvram_io *io, size_t offset,
+		       void *buffer, size_t nbytes)
+{
+	void	*ptr;
+	int	 error;
+	
+	/* Try to fetch a direct pointer for at least nbytes */
+	if ((error = bhnd_nvram_io_write_ptr(io, offset, &ptr, nbytes, NULL)))
+		return (error);
+	
+	/* Copy in the provided data */
+	memcpy(ptr, buffer, nbytes);
+	return (0);
+}

Modified: head/sys/modules/bhnd/Makefile
==============================================================================
--- head/sys/modules/bhnd/Makefile	Mon Dec 19 20:23:19 2016	(r310293)
+++ head/sys/modules/bhnd/Makefile	Mon Dec 19 20:26:10 2016	(r310294)
@@ -35,6 +35,7 @@ SRCS+=	bhnd_nvram_data.c \
 	bhnd_nvram_data_tlv.c \
 	bhnd_nvram_io.c \
 	bhnd_nvram_iobuf.c \
+	bhnd_nvram_ioptr.c \
 	bhnd_nvram_iores.c \
 	bhnd_nvram_plist.c \
 	bhnd_nvram_store.c \


More information about the svn-src-head mailing list