diff options
author | jake <jake@FreeBSD.org> | 2003-06-19 01:40:11 +0000 |
---|---|---|
committer | jake <jake@FreeBSD.org> | 2003-06-19 01:40:11 +0000 |
commit | f342d6c6f8a5eda9b78bd4fb21c6affa9227e652 (patch) | |
tree | 303affc319a30c0073e72190ade8b40c56c57b85 /sys/dev/ofw | |
parent | a81d7fdac76035cdd1a7cedd1187294b1688f7c0 (diff) | |
download | FreeBSD-src-f342d6c6f8a5eda9b78bd4fb21c6affa9227e652.zip FreeBSD-src-f342d6c6f8a5eda9b78bd4fb21c6affa9227e652.tar.gz |
Add a solaris compatible ofw interface for third party software that
expects one to use. Only the functions used by XFree86 are actually
implemented.
Glanced at by: tmm
Diffstat (limited to 'sys/dev/ofw')
-rw-r--r-- | sys/dev/ofw/openpromio.c | 218 | ||||
-rw-r--r-- | sys/dev/ofw/openpromio.h | 46 |
2 files changed, 264 insertions, 0 deletions
diff --git a/sys/dev/ofw/openpromio.c b/sys/dev/ofw/openpromio.c new file mode 100644 index 0000000..c2aa81f --- /dev/null +++ b/sys/dev/ofw/openpromio.c @@ -0,0 +1,218 @@ +/*- + * Copyright (c) 2003 Jake Burkholder. + * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/conf.h> +#include <sys/errno.h> +#include <sys/fcntl.h> +#include <sys/ioccom.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/module.h> + +#include <dev/ofw/openfirm.h> +#include <dev/ofw/openpromio.h> + +/* + * This provides a solaris compatible character device interface to + * openfirmware. It exists entirely for compatibility with software + * like X11, and only the features that are actually needed for that + * are implemented. The interface sucks too much to actually use, + * new code should use the /dev/openfirm device. + */ + +static d_open_t openprom_open; +static d_close_t openprom_close; +static d_ioctl_t openprom_ioctl; + +static int openprom_modevent(module_t mode, int type, void *data); +static int openprom_node_valid(phandle_t node); +static int openprom_node_search(phandle_t root, phandle_t node); + +static struct cdevsw openprom_cdevsw = { + .d_open = openprom_open, + .d_close = openprom_close, + .d_ioctl = openprom_ioctl, + .d_name = "openprom", +}; + +static int openprom_is_open; +static dev_t openprom_dev; +static phandle_t openprom_node; + +static int +openprom_open(dev_t dev, int oflags, int devtype, struct thread *td) +{ + + if (openprom_is_open != 0) + return (EBUSY); + openprom_is_open = 1; + return (0); +} + +static int +openprom_close(dev_t dev, int fflag, int devtype, struct thread *td) +{ + + openprom_is_open = 0; + return (0); +} + +static int +openprom_ioctl(dev_t dev, u_long cmd, caddr_t data, int flags, + struct thread *td) +{ + struct openpromio *oprom; + phandle_t node; + uint32_t len; + size_t done; + int proplen; + char *prop; + char *buf; + int error; + + error = 0; + oprom = *(void **)data; + switch (cmd) { + case OPROMCHILD: + case OPROMNEXT: + error = copyin(&oprom->oprom_size, &len, sizeof(len)); + if (error != 0) + break; + if (len != sizeof(node)) { + error = EINVAL; + break; + } + error = copyin(&oprom->oprom_array, &node, sizeof(node)); + if (error != 0) + break; + error = openprom_node_valid(node); + if (error != 0) + break; + switch (cmd) { + case OPROMCHILD: + node = OF_child(node); + break; + case OPROMNEXT: + node = OF_peer(node); + break; + } + error = copyout(&node, &oprom->oprom_array, sizeof(node)); + if (error != 0) + break; + openprom_node = node; + break; + case OPROMGETPROP: + case OPROMNXTPROP: + error = copyin(&oprom->oprom_size, &len, sizeof(len)); + if (error != 0) + break; + if (len > OPROMMAXPARAM) { + error = EINVAL; + break; + } + prop = malloc(len, M_TEMP, M_WAITOK | M_ZERO); + error = copyinstr(&oprom->oprom_array, prop, len, &done); + if (error != 0) + break; + buf = malloc(OPROMMAXPARAM, M_TEMP, M_WAITOK | M_ZERO); + node = openprom_node; + switch (cmd) { + case OPROMGETPROP: + proplen = OF_getproplen(node, prop); + if (proplen > OPROMMAXPARAM) { + error = EINVAL; + break; + } + error = OF_getprop(node, prop, buf, proplen); + break; + case OPROMNXTPROP: + error = OF_nextprop(node, prop, buf); + proplen = strlen(buf); + break; + } + if (error != -1) { + error = copyout(&proplen, &oprom->oprom_size, + sizeof(proplen)); + if (error == 0) + error = copyout(buf, &oprom->oprom_array, + proplen + 1); + } else + error = EINVAL; + free(prop, M_TEMP); + free(buf, M_TEMP); + break; + default: + error = ENOIOCTL; + break; + } + return (error); +} + +static int +openprom_node_valid(phandle_t node) +{ + + if (node == 0) + return (0); + return (openprom_node_search(OF_peer(0), node)); +} + +static int +openprom_node_search(phandle_t root, phandle_t node) +{ + phandle_t child; + + if (root == node) + return (0); + for (child = OF_child(root); child != 0 && child != -1; + child = OF_peer(child)) + if (openprom_node_search(child, node) == 0) + return (0); + return (EINVAL); +} + +static int +openprom_modevent(module_t mode, int type, void *data) +{ + + switch (type) { + case MOD_LOAD: + openprom_dev = make_dev(&openprom_cdevsw, 0, UID_ROOT, + GID_WHEEL, 0600, "openprom"); + return (0); + case MOD_UNLOAD: + destroy_dev(openprom_dev); + return (0); + default: + return (0); + } +} + +DEV_MODULE(openprom, openprom_modevent, NULL); diff --git a/sys/dev/ofw/openpromio.h b/sys/dev/ofw/openpromio.h new file mode 100644 index 0000000..5233d29 --- /dev/null +++ b/sys/dev/ofw/openpromio.h @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2003 Jake Burkholder. + * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 _DEV_OFW_OPENPROMIO_H_ +#define _DEV_OFW_OPENPROMIO_H_ + +#include <sys/ioccom.h> + +struct openpromio { + uint32_t oprom_size; + char oprom_array[]; +}; + +#define OPROMNEXT _IO('O', 1) +#define OPROMCHILD _IO('O', 2) +#define OPROMGETPROP _IO('O', 3) +#define OPROMNXTPROP _IO('O', 4) + +#define OPROMMAXPARAM 4096 + +#endif |