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-all
mailing list