From owner-svn-src-all@FreeBSD.ORG Mon Apr 28 18:06:13 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 7A6AFC2D; Mon, 28 Apr 2014 18:06:13 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::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 656D41CDC; Mon, 28 Apr 2014 18:06:13 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s3SI6DDo065868; Mon, 28 Apr 2014 18:06:13 GMT (envelope-from marcel@svn.freebsd.org) Received: (from marcel@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s3SI6BkI065857; Mon, 28 Apr 2014 18:06:11 GMT (envelope-from marcel@svn.freebsd.org) Message-Id: <201404281806.s3SI6BkI065857@svn.freebsd.org> From: Marcel Moolenaar Date: Mon, 28 Apr 2014 18:06:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r265056 - in head/tools/bus_space: . C Python X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 28 Apr 2014 18:06:13 -0000 Author: marcel Date: Mon Apr 28 18:06:11 2014 New Revision: 265056 URL: http://svnweb.freebsd.org/changeset/base/265056 Log: Add a C libary and a Python module that implements an API similar to bus_space(9) and that uses the proto(4) driver for talking to hardware. If the I/O resource is a memory mapped I/O resource, then mmap(2) will be attempted to avoid read(2)/write(2) overhead. Sponsored by: Juniper Networks, Inc. Added: head/tools/bus_space/ head/tools/bus_space/C/ head/tools/bus_space/C/Makefile (contents, props changed) head/tools/bus_space/C/lang.c (contents, props changed) head/tools/bus_space/C/libbus_space.h (contents, props changed) head/tools/bus_space/Makefile (contents, props changed) head/tools/bus_space/Makefile.inc (contents, props changed) head/tools/bus_space/Python/ head/tools/bus_space/Python/Makefile (contents, props changed) head/tools/bus_space/Python/lang.c (contents, props changed) head/tools/bus_space/bus_space.c (contents, props changed) head/tools/bus_space/bus_space.h (contents, props changed) Added: head/tools/bus_space/C/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/bus_space/C/Makefile Mon Apr 28 18:06:11 2014 (r265056) @@ -0,0 +1,9 @@ +# $FreeBSD$ + +LIB= bus_space +SHLIB_MAJOR= 0 +SRCS= lang.c + +CFLAGS+= -I${.CURDIR}/.. + +.include Added: head/tools/bus_space/C/lang.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/bus_space/C/lang.c Mon Apr 28 18:06:11 2014 (r265056) @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 2014 Marcel Moolenaar + * 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. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, 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 DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include "bus_space.h" +#include "libbus_space.h" + +int +bus_space_read_1(int rid, long ofs) +{ + uint8_t val; + + return ((!bs_read(rid, ofs, &val, sizeof(val))) ? -1 : (int)val); +} + +int +bus_space_read_2(int rid, long ofs) +{ + uint16_t val; + + return ((!bs_read(rid, ofs, &val, sizeof(val))) ? -1 : (int)val); +} + +int64_t +bus_space_read_4(int rid, long ofs) +{ + uint32_t val; + + return ((!bs_read(rid, ofs, &val, sizeof(val))) ? -1 : (int64_t)val); +} + +int +bus_space_write_1(int rid, long ofs, uint8_t val) +{ + + return ((!bs_write(rid, ofs, &val, sizeof(val))) ? errno : 0); +} + +int +bus_space_write_2(int rid, long ofs, uint16_t val) +{ + + return ((!bs_write(rid, ofs, &val, sizeof(val))) ? errno : 0); +} + +int +bus_space_write_4(int rid, long ofs, uint32_t val) +{ + + return ((!bs_write(rid, ofs, &val, sizeof(val))) ? errno : 0); +} + +int +bus_space_map(const char *dev) +{ + + return (bs_map(dev)); +} + +int +bus_space_unmap(int rid) +{ + + return ((!bs_unmap(rid)) ? errno : 0); +} + +int +bus_space_subregion(int rid, long ofs, long sz) +{ + + return (bs_subregion(rid, ofs, sz)); +} Added: head/tools/bus_space/C/libbus_space.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/bus_space/C/libbus_space.h Mon Apr 28 18:06:11 2014 (r265056) @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2014 Marcel Moolenaar + * 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. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, 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 DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _LIBBUS_SPACE_H_ +#define _LIBBUS_SPACE_H_ + +int bus_space_map(const char *dev); +int bus_space_read_1(int rid, long ofs); +int bus_space_read_2(int rid, long ofs); +int64_t bus_space_read_4(int rid, long ofs); +int bus_space_subregion(int rid, long ofs, long sz); +int bus_space_unmap(int rid); +int bus_space_write_1(int rid, long ofs, uint8_t val); +int bus_space_write_2(int rid, long ofs, uint16_t val); +int bus_space_write_4(int rid, long ofs, uint32_t val); + +#endif /* _LIBBUS_SPACE_H_ */ Added: head/tools/bus_space/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/bus_space/Makefile Mon Apr 28 18:06:11 2014 (r265056) @@ -0,0 +1,7 @@ +# $FreeBSD$ + +SUBDIR= \ + C \ + Python + +.include Added: head/tools/bus_space/Makefile.inc ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/bus_space/Makefile.inc Mon Apr 28 18:06:11 2014 (r265056) @@ -0,0 +1,4 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/.. +SRCS+= bus_space.c Added: head/tools/bus_space/Python/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/bus_space/Python/Makefile Mon Apr 28 18:06:11 2014 (r265056) @@ -0,0 +1,9 @@ +# $FreeBSD$ + +SHLIB_NAME= bus_space.so +SRCS= lang.c + +CFLAGS+= -I${.CURDIR}/.. -I/usr/local/include/python2.7 +LDFLAGS+= -L/usr/local/lib -lpython2.7 + +.include Added: head/tools/bus_space/Python/lang.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/bus_space/Python/lang.c Mon Apr 28 18:06:11 2014 (r265056) @@ -0,0 +1,200 @@ +/*- + * Copyright (c) 2014 Marcel Moolenaar + * 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. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, 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 DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#include "bus_space.h" + +static PyObject * +bus_read_1(PyObject *self, PyObject *args) +{ + long ofs; + int rid; + uint8_t val; + + if (!PyArg_ParseTuple(args, "il", &rid, &ofs)) + return (NULL); + if (!bs_read(rid, ofs, &val, sizeof(val))) { + PyErr_SetString(PyExc_IOError, strerror(errno)); + return (NULL); + } + return (Py_BuildValue("B", val)); +} + +static PyObject * +bus_read_2(PyObject *self, PyObject *args) +{ + long ofs; + int rid; + uint16_t val; + + if (!PyArg_ParseTuple(args, "il", &rid, &ofs)) + return (NULL); + if (!bs_read(rid, ofs, &val, sizeof(val))) { + PyErr_SetString(PyExc_IOError, strerror(errno)); + return (NULL); + } + return (Py_BuildValue("H", val)); +} + +static PyObject * +bus_read_4(PyObject *self, PyObject *args) +{ + long ofs; + int rid; + uint32_t val; + + if (!PyArg_ParseTuple(args, "il", &rid, &ofs)) + return (NULL); + if (!bs_read(rid, ofs, &val, sizeof(val))) { + PyErr_SetString(PyExc_IOError, strerror(errno)); + return (NULL); + } + return (Py_BuildValue("I", val)); +} + +static PyObject * +bus_write_1(PyObject *self, PyObject *args) +{ + long ofs; + int rid; + uint8_t val; + + if (!PyArg_ParseTuple(args, "ilB", &rid, &ofs, &val)) + return (NULL); + if (!bs_write(rid, ofs, &val, sizeof(val))) { + PyErr_SetString(PyExc_IOError, strerror(errno)); + return (NULL); + } + Py_RETURN_NONE; +} + +static PyObject * +bus_write_2(PyObject *self, PyObject *args) +{ + long ofs; + int rid; + uint16_t val; + + if (!PyArg_ParseTuple(args, "ilH", &rid, &ofs, &val)) + return (NULL); + if (!bs_write(rid, ofs, &val, sizeof(val))) { + PyErr_SetString(PyExc_IOError, strerror(errno)); + return (NULL); + } + Py_RETURN_NONE; +} + +static PyObject * +bus_write_4(PyObject *self, PyObject *args) +{ + long ofs; + int rid; + uint32_t val; + + if (!PyArg_ParseTuple(args, "ilI", &rid, &ofs, &val)) + return (NULL); + if (!bs_write(rid, ofs, &val, sizeof(val))) { + PyErr_SetString(PyExc_IOError, strerror(errno)); + return (NULL); + } + Py_RETURN_NONE; +} + +static PyObject * +bus_map(PyObject *self, PyObject *args) +{ + char *dev; + int rid; + + if (!PyArg_ParseTuple(args, "s", &dev)) + return (NULL); + rid = bs_map(dev); + if (rid == -1) { + PyErr_SetString(PyExc_IOError, strerror(errno)); + return (NULL); + } + return (Py_BuildValue("i", rid)); +} + +static PyObject * +bus_unmap(PyObject *self, PyObject *args) +{ + int rid; + + if (!PyArg_ParseTuple(args, "i", &rid)) + return (NULL); + if (!bs_unmap(rid)) { + PyErr_SetString(PyExc_IOError, strerror(errno)); + return (NULL); + } + Py_RETURN_NONE; +} + +static PyObject * +bus_subregion(PyObject *self, PyObject *args) +{ + long ofs, sz; + int rid0, rid; + + if (!PyArg_ParseTuple(args, "ill", &rid0, &ofs, &sz)) + return (NULL); + rid = bs_subregion(rid0, ofs, sz); + if (rid == -1) { + PyErr_SetString(PyExc_IOError, strerror(errno)); + return (NULL); + } + return (Py_BuildValue("i", rid)); +} + +static PyMethodDef bus_space_methods[] = { + { "read_1", bus_read_1, METH_VARARGS, "Read a 1-byte data item." }, + { "read_2", bus_read_2, METH_VARARGS, "Read a 2-byte data item." }, + { "read_4", bus_read_4, METH_VARARGS, "Read a 4-byte data item." }, + + { "write_1", bus_write_1, METH_VARARGS, "Write a 1-byte data item." }, + { "write_2", bus_write_2, METH_VARARGS, "Write a 2-byte data item." }, + { "write_4", bus_write_4, METH_VARARGS, "Write a 4-byte data item." }, + + { "map", bus_map, METH_VARARGS, + "Return a resource ID for a device file created by proto(4)" }, + { "unmap", bus_unmap, METH_VARARGS, + "Free a resource ID" }, + { "subregion", bus_subregion, METH_VARARGS, + "Return a resource ID for a subregion of another resource ID" }, + + { NULL, NULL, 0, NULL } +}; + +PyMODINIT_FUNC +initbus_space(void) +{ + + Py_InitModule("bus_space", bus_space_methods); +} Added: head/tools/bus_space/bus_space.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/bus_space/bus_space.c Mon Apr 28 18:06:11 2014 (r265056) @@ -0,0 +1,263 @@ +/*- + * Copyright (c) 2014 Marcel Moolenaar + * 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. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, 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 DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include "bus_space.h" + +#include "../../sys/dev/proto/proto_dev.h" + +struct resource { + int rid; + int fd; + long addr; + long size; + off_t ofs; + caddr_t ptr; +}; + +static struct resource *ridtbl = NULL; +static int nrids = 0; + +static int +rid_alloc(void) +{ + void *newtbl; + int rid; + + for (rid = 0; rid < nrids; rid++) { + if (ridtbl[rid].fd == -1) + break; + } + if (rid == nrids) { + nrids++; + newtbl = realloc(ridtbl, sizeof(struct resource) * nrids); + if (newtbl == NULL) { + nrids--; + return (-1); + } else + ridtbl = newtbl; + } + ridtbl[rid].fd = INT_MAX; + return (rid); +} + +static struct resource * +rid_lookup(int rid) +{ + struct resource *r; + + if (rid < 0 || rid >= nrids) { + errno = EINVAL; + return (NULL); + } + r = ridtbl + rid; + if (r->fd == -1) { + errno = ENXIO; + return (NULL); + } + return (r); +} + +int +bs_map(const char *dev) +{ + struct proto_ioc_region region; + struct resource *r; + int rid; + + rid = rid_alloc(); + if (rid == -1) + return (-1); + r = rid_lookup(rid); + if (r == NULL) + return (-1); + r->fd = open(dev, O_RDWR); + if (r->fd == -1) + return (-1); + r->rid = -1; + if (ioctl(r->fd, PROTO_IOC_REGION, ®ion) == -1) { + close(r->fd); + r->fd = -1; + return (-1); + } + r->addr = region.address; + r->size = region.size; + r->ofs = 0; + r->ptr = mmap(NULL, r->size, PROT_READ | PROT_WRITE, + MAP_NOCORE | MAP_SHARED, r->fd, r->ofs); + return (rid); +} + +int +bs_read(int rid, off_t ofs, void *buf, ssize_t bufsz) +{ + struct resource *r; + volatile void *ptr; + off_t o; + ssize_t s; + + r = rid_lookup(rid); + if (r == NULL) + return (0); + if (ofs < 0 || ofs > r->size - bufsz) { + errno = ESPIPE; + return (0); + } + ofs += r->ofs; + if (r->ptr != MAP_FAILED) { + ptr = r->ptr + ofs; + switch (bufsz) { + case 1: + *((uint8_t *)buf) = *((volatile uint8_t *)ptr); + break; + case 2: + *((uint16_t *)buf) = *((volatile uint16_t *)ptr); + break; + case 4: + *((uint32_t *)buf) = *((volatile uint32_t *)ptr); + break; + default: + errno = EIO; + return (0); + } + } else { + o = lseek(r->fd, ofs, SEEK_SET); + if (o != ofs) + return (0); + s = read(r->fd, buf, bufsz); + if (s != bufsz) + return (0); + } + return (1); +} + +int +bs_subregion(int rid0, long ofs, long sz) +{ + struct resource *r; + void *ptr0; + long addr0, ofs0; + int fd0, rid; + + r = rid_lookup(rid0); + if (r == NULL) + return (-1); + if (ofs < 0 || sz < 1) { + errno = EINVAL; + return (-1); + } + if (ofs + sz > r->size) { + errno = ENOSPC; + return (-1); + } + fd0 = r->fd; + addr0 = r->addr; + ofs0 = r->ofs; + ptr0 = r->ptr; + rid = rid_alloc(); + if (rid == -1) + return (-1); + r = rid_lookup(rid); + if (r == NULL) + return (-1); + r->rid = rid0; + r->fd = fd0; + r->addr = addr0 + ofs; + r->size = sz; + r->ofs = ofs0 + ofs; + r->ptr = ptr0; + return (rid); +} + +int +bs_unmap(int rid) +{ + struct resource *r; + + r = rid_lookup(rid); + if (r == NULL) + return (0); + if (r->rid == -1) { + if (r->ptr != MAP_FAILED) + munmap(r->ptr, r->size); + close(r->fd); + } + r->fd = -1; + return (1); +} + +int +bs_write(int rid, off_t ofs, void *buf, ssize_t bufsz) +{ + struct resource *r; + volatile void *ptr; + off_t o; + ssize_t s; + + r = rid_lookup(rid); + if (r == NULL) + return (0); + if (ofs < 0 || ofs > r->size - bufsz) { + errno = ESPIPE; + return (0); + } + ofs += r->ofs; + if (r->ptr != MAP_FAILED) { + ptr = r->ptr + ofs; + switch (bufsz) { + case 1: + *((volatile uint8_t *)ptr) = *((uint8_t *)buf); + break; + case 2: + *((volatile uint16_t *)ptr) = *((uint16_t *)buf); + break; + case 4: + *((volatile uint32_t *)ptr) = *((uint32_t *)buf); + break; + default: + errno = EIO; + return (0); + } + } else { + o = lseek(r->fd, ofs, SEEK_SET); + if (o != ofs) + return (0); + s = write(r->fd, buf, bufsz); + if (s != bufsz) + return (0); + } + return (1); +} Added: head/tools/bus_space/bus_space.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/bus_space/bus_space.h Mon Apr 28 18:06:11 2014 (r265056) @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2014 Marcel Moolenaar + * 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. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, 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 DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _TOOLS_BUS_SPACE_H_ +#define _TOOLS_BUS_SPACE_H_ + +int bs_map(const char *dev); +int bs_read(int rid, off_t ofs, void *buf, ssize_t bufsz); +int bs_subregion(int rid0, long ofs, long sz); +int bs_unmap(int rid); +int bs_write(int rid, off_t ofs, void *buf, ssize_t bufsz); + +#endif /* _TOOLS_BUS_SPACE_H_ */