Module Name: src Committed By: thorpej Date: Fri Feb 5 17:17:59 UTC 2021
Modified Files: src/sys/dev/ofw: ofw_subr.c openfirm.h Log Message: OpenFirmware device handle implementation. To generate a diff of this commit: cvs rdiff -u -r1.56 -r1.57 src/sys/dev/ofw/ofw_subr.c cvs rdiff -u -r1.44 -r1.45 src/sys/dev/ofw/openfirm.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ofw/ofw_subr.c diff -u src/sys/dev/ofw/ofw_subr.c:1.56 src/sys/dev/ofw/ofw_subr.c:1.57 --- src/sys/dev/ofw/ofw_subr.c:1.56 Thu Feb 4 20:19:09 2021 +++ src/sys/dev/ofw/ofw_subr.c Fri Feb 5 17:17:59 2021 @@ -1,4 +1,30 @@ -/* $NetBSD: ofw_subr.c,v 1.56 2021/02/04 20:19:09 thorpej Exp $ */ +/* $NetBSD: ofw_subr.c,v 1.57 2021/02/05 17:17:59 thorpej Exp $ */ + +/* + * Copyright (c) 2021 The NetBSD Foundation, Inc. + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ /* * Copyright 1998 @@ -34,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ofw_subr.c,v 1.56 2021/02/04 20:19:09 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ofw_subr.c,v 1.57 2021/02/05 17:17:59 thorpej Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -46,6 +72,68 @@ __KERNEL_RCSID(0, "$NetBSD: ofw_subr.c,v #define OFW_PATH_BUF_SIZE 512 /* + * OpenFirmware device handle support. + */ + +static device_call_t +of_devhandle_lookup_device_call(devhandle_t handle, const char *name, + devhandle_t *call_handlep) +{ + __link_set_decl(of_device_calls, struct device_call_descriptor); + struct device_call_descriptor * const *desc; + + __link_set_foreach(desc, of_device_calls) { + if (strcmp((*desc)->name, name) == 0) { + return (*desc)->call; + } + } + return NULL; +} + +static const struct devhandle_impl of_devhandle_impl = { + .type = DEVHANDLE_TYPE_OF, + .lookup_device_call = of_devhandle_lookup_device_call, +}; + +devhandle_t +devhandle_from_of(int phandle) +{ + devhandle_t handle = { + .impl = &of_devhandle_impl, + .integer = phandle, + }; + + return handle; +} + +int +devhandle_to_of(devhandle_t const handle) +{ + KASSERT(devhandle_type(handle) == DEVHANDLE_TYPE_OF); + + return handle.integer; +} + +static int +of_device_enumerate_children(device_t dev, devhandle_t call_handle, void *v) +{ + struct device_enumerate_children_args *args = v; + int phandle = devhandle_to_of(call_handle); + int child; + + for (child = OF_child(phandle); child != 0; child = OF_peer(child)) { + if (!args->callback(dev, devhandle_from_of(child), + args->callback_arg)) { + break; + } + } + + return 0; +} +OF_DEVICE_CALL_REGISTER("device-enumerate-children", + of_device_enumerate_children) + +/* * int of_decode_int(p) * * This routine converts OFW encoded-int datums @@ -429,6 +517,45 @@ of_get_mode_string(char *buffer, int len return buffer; } +void +of_device_register(device_t dev, int phandle) +{ + + /* All we do here is set the devhandle in the device_t. */ + device_set_handle(dev, devhandle_from_of(phandle)); +} + +/* + * of_device_from_phandle -- + * + * Return a device_t associated with the specified phandle. + * + * This is expected to be used rarely, so we don't care if + * it's fast. Also, it can only find devices that have + * gone through of_device_register() (obviously). + */ +device_t +of_device_from_phandle(int phandle) +{ + devhandle_t devhandle; + deviter_t di; + device_t dev; + + for (dev = deviter_first(&di, DEVITER_F_ROOT_FIRST); + dev != NULL; + dev = deviter_next(&di)) { + devhandle = device_handle(dev); + if (devhandle_type(devhandle) == DEVHANDLE_TYPE_OF) { + if (devhandle_to_of(devhandle) == phandle) { + /* Found it! */ + break; + } + } + } + deviter_release(&di); + return dev; +} + /* * Returns true if the specified property is present. */ Index: src/sys/dev/ofw/openfirm.h diff -u src/sys/dev/ofw/openfirm.h:1.44 src/sys/dev/ofw/openfirm.h:1.45 --- src/sys/dev/ofw/openfirm.h:1.44 Wed Jan 27 04:55:42 2021 +++ src/sys/dev/ofw/openfirm.h Fri Feb 5 17:17:59 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: openfirm.h,v 1.44 2021/01/27 04:55:42 thorpej Exp $ */ +/* $NetBSD: openfirm.h,v 1.45 2021/02/05 17:17:59 thorpej Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -34,6 +34,7 @@ #ifndef _OPENFIRM_H_ #define _OPENFIRM_H_ +#include <sys/device.h> #include <prop/proplib.h> /* @@ -105,6 +106,12 @@ int openfirmware(void *); */ struct device_compatible_entry; +devhandle_t devhandle_from_of(int); +int devhandle_to_of(devhandle_t); + +#define OF_DEVICE_CALL_REGISTER(_n_, _c_) \ + DEVICE_CALL_REGISTER(of_device_calls, _n_, _c_) + int of_compatible(int, const char * const *); int of_compatible_match(int, const struct device_compatible_entry *); const struct device_compatible_entry * @@ -116,6 +123,8 @@ int of_find_bycompat(int, const char *); int of_getnode_byname(int, const char *); bool of_to_uint32_prop(prop_dictionary_t, int, const char *, const char *); bool of_to_dataprop(prop_dictionary_t, int, const char *, const char *); +void of_device_register(device_t, int); +device_t of_device_from_phandle(int); int *of_network_decode_media(int, int *, int *); char *of_get_mode_string(char *, int);