From owner-svn-src-head@freebsd.org Mon Dec 19 20:26:12 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 437AAC8888F; Mon, 19 Dec 2016 20:26:12 +0000 (UTC) (envelope-from landonf@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1B4EB17DC; Mon, 19 Dec 2016 20:26:12 +0000 (UTC) (envelope-from landonf@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uBJKQBos056480; Mon, 19 Dec 2016 20:26:11 GMT (envelope-from landonf@FreeBSD.org) Received: (from landonf@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uBJKQAHj056476; Mon, 19 Dec 2016 20:26:10 GMT (envelope-from landonf@FreeBSD.org) Message-Id: <201612192026.uBJKQAHj056476@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: landonf set sender to landonf@FreeBSD.org using -f From: "Landon J. Fuller" Date: Mon, 19 Dec 2016 20:26:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r310294 - in head/sys: conf dev/bhnd/nvram modules/bhnd X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Dec 2016 20:26:12 -0000 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 + * 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 +__FBSDID("$FreeBSD$"); + +#ifdef _KERNEL +#include +#include +#include +#else /* !_KERNEL */ +#include +#include +#include +#include +#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 \