Index: arch/sparc/sparc/promlib.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/promlib.c,v retrieving revision 1.48 diff -u -p -r1.48 promlib.c --- arch/sparc/sparc/promlib.c 10 May 2021 13:59:30 -0000 1.48 +++ arch/sparc/sparc/promlib.c 14 Sep 2021 01:18:36 -0000 @@ -276,7 +276,7 @@ obp_device_enumerate_children(device_t d return 0; } -OBP_DEVICE_CALL_REGISTER("device-enumerate-children", +OBP_DEVICE_CALL_REGISTER(DEVICE_ENUMERATE_CHILDREN_STR, obp_device_enumerate_children) #endif /* ! _STANDALONE */ Index: dev/acpi/acpi_pci.c =================================================================== RCS file: /cvsroot/src/sys/dev/acpi/acpi_pci.c,v retrieving revision 1.31 diff -u -p -r1.31 acpi_pci.c --- dev/acpi/acpi_pci.c 12 May 2021 23:22:33 -0000 1.31 +++ dev/acpi/acpi_pci.c 14 Sep 2021 01:18:37 -0000 @@ -41,6 +41,8 @@ __KERNEL_RCSID(0, "$NetBSD: acpi_pci.c,v #include #include +#include + #include #include #include @@ -576,5 +578,5 @@ acpi_pci_bus_get_child_devhandle(device_ return ENODEV; } -ACPI_DEVICE_CALL_REGISTER("pci-bus-get-child-devhandle", +ACPI_DEVICE_CALL_REGISTER(PCI_BUS_GET_CHILD_DEVHANDLE_STR, acpi_pci_bus_get_child_devhandle) Index: dev/acpi/acpi_util.c =================================================================== RCS file: /cvsroot/src/sys/dev/acpi/acpi_util.c,v retrieving revision 1.25 diff -u -p -r1.25 acpi_util.c --- dev/acpi/acpi_util.c 9 Aug 2021 20:49:09 -0000 1.25 +++ dev/acpi/acpi_util.c 14 Sep 2021 01:18:37 -0000 @@ -75,6 +75,8 @@ __KERNEL_RCSID(0, "$NetBSD: acpi_util.c, #include #include +#include + #include #define _COMPONENT ACPI_BUS_COMPONENT @@ -153,7 +155,7 @@ acpi_device_enumerate_children(device_t return 0; } -ACPI_DEVICE_CALL_REGISTER("device-enumerate-children", +ACPI_DEVICE_CALL_REGISTER(DEVICE_ENUMERATE_CHILDREN_STR, acpi_device_enumerate_children) /* Index: dev/ofw/ofw_pci_subr.c =================================================================== RCS file: /cvsroot/src/sys/dev/ofw/ofw_pci_subr.c,v retrieving revision 1.1 diff -u -p -r1.1 ofw_pci_subr.c --- dev/ofw/ofw_pci_subr.c 12 May 2021 23:22:33 -0000 1.1 +++ dev/ofw/ofw_pci_subr.c 14 Sep 2021 01:18:37 -0000 @@ -38,6 +38,7 @@ __KERNEL_RCSID(0, "$NetBSD: ofw_pci_subr #include #include +#include #include #include @@ -82,5 +83,5 @@ ofw_pci_bus_get_child_devhandle(device_t return ENODEV; } -OF_DEVICE_CALL_REGISTER("pci-bus-get-child-devhandle", +OF_DEVICE_CALL_REGISTER(PCI_BUS_GET_CHILD_DEVHANDLE_STR, ofw_pci_bus_get_child_devhandle) Index: dev/ofw/ofw_subr.c =================================================================== RCS file: /cvsroot/src/sys/dev/ofw/ofw_subr.c,v retrieving revision 1.58 diff -u -p -r1.58 ofw_subr.c --- dev/ofw/ofw_subr.c 24 Apr 2021 23:36:57 -0000 1.58 +++ dev/ofw/ofw_subr.c 14 Sep 2021 01:18:37 -0000 @@ -66,6 +66,9 @@ __KERNEL_RCSID(0, "$NetBSD: ofw_subr.c,v #include #include #include + +#include + #include #define OFW_MAX_STACK_BUF_SIZE 256 @@ -130,7 +133,7 @@ of_device_enumerate_children(device_t de return 0; } -OF_DEVICE_CALL_REGISTER("device-enumerate-children", +OF_DEVICE_CALL_REGISTER(DEVICE_ENUMERATE_CHILDREN_STR, of_device_enumerate_children) /* Index: dev/pci/Makefile =================================================================== RCS file: /cvsroot/src/sys/dev/pci/Makefile,v retrieving revision 1.15 diff -u -p -r1.15 Makefile --- dev/pci/Makefile 12 Dec 2018 07:04:05 -0000 1.15 +++ dev/pci/Makefile 14 Sep 2021 01:18:37 -0000 @@ -9,4 +9,10 @@ INCS= amrreg.h amrio.h mlyio.h mlyreg.h pcidevs.h pcidevs_data.h pciio.h pcireg.h \ tgareg.h twereg.h tweio.h +pci_calls.h: ${.CURDIR}/pci_calls + echo "${TOOL_AWK} -f ${.CURDIR}/../../kern/gendevcalls.awk \ + ${.CURDIR}/pci_calls > ${.CURDIR}/pci_calls.h" + ${TOOL_AWK} -f ${.CURDIR}/../../kern/gendevcalls.awk \ + ${.CURDIR}/pci_calls > ${.CURDIR}/pci_calls.h + .include Index: dev/pci/pci.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/pci.c,v retrieving revision 1.161 diff -u -p -r1.161 pci.c --- dev/pci/pci.c 7 Aug 2021 16:19:14 -0000 1.161 +++ dev/pci/pci.c 14 Sep 2021 01:18:37 -0000 @@ -53,6 +53,8 @@ __KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.16 #include #include +#include + #include #include "locators.h" @@ -275,8 +277,7 @@ pci_bus_get_child_devhandle(struct pci_s .tag = tag, }; - if (device_call(sc->sc_dev, "pci-bus-get-child-devhandle", - &args) != 0) { + if (device_call(sc->sc_dev, PCI_BUS_GET_CHILD_DEVHANDLE(&args)) != 0) { /* * The call is either not supported or the requested * device was not found in the platform device tree. Index: dev/pci/pci_calls =================================================================== RCS file: dev/pci/pci_calls diff -N dev/pci/pci_calls --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dev/pci/pci_calls 14 Sep 2021 01:18:37 -0000 @@ -0,0 +1,60 @@ +$NetBSD$ + +/*- + * Copyright (c) 2021 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * 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. + */ + +/* + * Device calls used by the PCI subsystem. + */ + +subsystem pci; + +/* + * pci-bus-get-child-devhandle + * + * Retrieve the devhandle for the PCI device represented by 'tag' + * in the PCI segment represented by 'pc'. The PCI bus's device_t + * is the one that's passed in the call, and the device whose handle + * is being requested must be a direct child of that bus, otherwise + * behavior is undefined. + * + * Call returns 0 if successful, or an error code upon failure: + * + * ENOTSUP The device handle implementation for the + * PCI bus does not support this device call. + * + * ENODEV The PCI device represented by the pcitag_t + * was not found in a bus-scoped search of the + * platform device tree. + */ +pci-bus-get-child-devhandle { + pci_chipset_tag_t pc; /* IN */ + pcitag_t tag; /* IN */ + devhandle_t devhandle; /* OUT */ +}; Index: dev/pci/pci_calls.h =================================================================== RCS file: dev/pci/pci_calls.h diff -N dev/pci/pci_calls.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dev/pci/pci_calls.h 14 Sep 2021 01:18:37 -0000 @@ -0,0 +1,86 @@ +/* $NetBSD$ */ + +/* + * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + * + * generated from: + * NetBSD + */ + +/*- + * Copyright (c) 2021 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * 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. + */ + +/* + * Device calls used by the PCI subsystem. + */ + +#ifndef _PCI_CALLS_H_ +#define _PCI_CALLS_H_ + +/* + * pci-bus-get-child-devhandle + * + * Retrieve the devhandle for the PCI device represented by 'tag' + * in the PCI segment represented by 'pc'. The PCI bus's device_t + * is the one that's passed in the call, and the device whose handle + * is being requested must be a direct child of that bus, otherwise + * behavior is undefined. + * + * Call returns 0 if successful, or an error code upon failure: + * + * ENOTSUP The device handle implementation for the + * PCI bus does not support this device call. + * + * ENODEV The PCI device represented by the pcitag_t + * was not found in a bus-scoped search of the + * platform device tree. + */ +struct pci_bus_get_child_devhandle_args { + pci_chipset_tag_t pc; /* IN */ + pcitag_t tag; /* IN */ + devhandle_t devhandle; /* OUT */ +}; + +union pci_bus_get_child_devhandle_binding { + struct device_call_generic generic; + struct { + const char *name; + struct pci_bus_get_child_devhandle_args *args; + } binding; +}; + +#define PCI_BUS_GET_CHILD_DEVHANDLE_STR "pci-bus-get-child-devhandle" + +#define PCI_BUS_GET_CHILD_DEVHANDLE(_args_) \ + &((const union pci_bus_get_child_devhandle_binding){ \ + .binding.name = "pci-bus-get-child-devhandle", \ + .binding.args = (_args_), \ + }) + +#endif /* _PCI_CALLS_H_ */ Index: dev/pci/pcivar.h =================================================================== RCS file: /cvsroot/src/sys/dev/pci/pcivar.h,v retrieving revision 1.115 diff -u -p -r1.115 pcivar.h --- dev/pci/pcivar.h 12 May 2021 23:22:33 -0000 1.115 +++ dev/pci/pcivar.h 14 Sep 2021 01:18:37 -0000 @@ -277,31 +277,6 @@ struct pci_softc { #define PCI_SC_DEVICESC(d, f) sc_devices[(d) * 8 + (f)] }; -/* - * pci-bus-get-child-devhandle device call - * - * Called to get the device handle for a device, represented - * by the pcitag_t with the PCI segment represented by the - * pci_chipset_tag_t. The PCI bus's device_t is the one - * passed to device_call(), and the device whose handle is - * being requested must be a direct child of that bus, - * otherwise the behavior is undefined. - * - * Call returns 0 if successful, or an error code upon failure: - * - * ENOTSUP The device handle implementation for the - * PCI bus does not support this device call. - * - * ENODEV The PCI device represented by the pcitag_t - * was not found in a bus-scoped search of the - * platform device tree. - */ -struct pci_bus_get_child_devhandle_args { - pci_chipset_tag_t pc; /* IN */ - pcitag_t tag; /* IN */ - devhandle_t devhandle; /* OUT */ -}; - extern struct cfdriver pci_cd; extern bool pci_mapreg_map_enable_decode; Index: kern/device_calls =================================================================== RCS file: kern/device_calls diff -N kern/device_calls --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ kern/device_calls 14 Sep 2021 01:18:37 -0000 @@ -0,0 +1,50 @@ +$NetBSD$ + +/*- + * Copyright (c) 2021 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * 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. + */ + +/* + * Device calls used by the device autoconfiguration subsystem + */ + +subsystem device; + +/* + * device-enumerate-children + * + * Enumerates the direct children of a device, invoking the callback for + * each one. The callback is passed the devhandle_t corresponding to the + * child device, as well as a user-supplied argument. If the callback + * returns true, then enumeration continues. If the callback returns false, + * enumeration is stopped. + */ +device-enumerate-children { + bool (*callback)(device_t, devhandle_t, void *); + void * callback_arg; +}; Index: kern/gendevcalls.awk =================================================================== RCS file: kern/gendevcalls.awk diff -N kern/gendevcalls.awk --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ kern/gendevcalls.awk 14 Sep 2021 01:18:37 -0000 @@ -0,0 +1,205 @@ +#! /usr/bin/awk -f +# $NetBSD$ +# +# Copyright (c) 2021 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jason R. Thorpe. +# +# 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. +# + +# +# Parses a device call definition file and produces argument and +# binding structures. +# + +function emit_binding(field) { + printf("union %s_binding {\n", call_name_ub) + printf("\tstruct device_call_generic generic;\n") + if (field != "") { + printf("\tstruct {\n") + printf("\t\tconst char *name;\n") + printf("\t\tstruct %s_args *args;\n", call_name_ub) + printf("\t} %s;\n", field); + } + printf("};\n") +} + +function emit_name_macro() { + printf("\n") + printf("#define %s_STR \"%s\"\n", call_name_ub_uc, call_name) +} + +function emit_invoke_macro(field, marg, carg) { + printf("\n") + printf("#define %s%s \\\n", call_name_ub_uc, marg) + printf("\t&((const union %s_binding){ \\\n", call_name_ub) + printf("\t\t.%s.name = \"%s\", \\\n", field, call_name) + printf("\t\t.%s.args = %s, \\\n", field, carg) + printf("\t})\n") +} + +function start_decl(arg) { + if (state == "expecting-subsystem") { + print "must declare a subsystem before declaring a call " \ + "at line " NR \ + > "/dev/stderr" + exit 1 + } + + if (state != "expecting-decl-start") { + print "unexpected start of declaration at line " NR \ + > "/dev/stderr" + exit 1 + } + + call_name = arg + + if (index(call_name, call_name_prefix) != 1) { + printf("method name '%s' at line %d must begin with '%s'\n", \ + call_name, NR, call_name_prefix) \ + > "/dev/stderr" + exit 1 + } + + call_name_ub = arg + gsub("\-", "_", call_name_ub) + call_name_ub_uc = toupper(call_name_ub) +} + +NR == 1 { + VERSION = $0 + gsub("\\$", "", VERSION) + gsub(/ $/, "", VERSION) + + printf("/*\t$NetBSD" "$\t*/\n\n") + printf("/*\n") + printf(" * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.\n") + printf(" *\n") + printf(" * generated from:\n") + printf(" *\t%s\n", VERSION) + printf(" */\n") + + subsystem = "" + state = "expecting-subsystem" + + next +} +# +# Subystem declaration. We use this to generate header file guards, +# as well as to sanity-check the method names when they are declared. +# +state == "expecting-subsystem" && \ +/^subsystem[ \t]+[a-zA-Z]+[a-zA-Z0-9\-]*[ \t]*;[ \t]*$/ { + subsystem = $2 + + # strip the trailing ; + gsub(";$", "", subsystem) + + subsystem_ub = subsystem + gsub("\-", "_", subsystem_ub) + subsystem_ub_uc = toupper(subsystem_ub) + + # now tack on a trailing - for sanity checking method + # names later. + call_name_prefix = subsystem "-" + + # Emit the leading header guard. + printf("#ifndef _%s_CALLS_H_\n", subsystem_ub_uc) + printf("#define _%s_CALLS_H_\n", subsystem_ub_uc) + + state = "expecting-decl-start" + + next +} +# +# Beginning of a call-with-arguments declaration. Gather up the various +# forms of the method name and emit the beginning of the structure declaration. +# +/^[a-zA-Z]+[a-zA-Z0-9\-]*[ \t]+{[ \t]*$/ { + start_decl($1) + + # Emit the args structure declaration. + printf("struct %s_args {\n", call_name_ub) + + state = "expecting-decl-end" + + next +} +# +# A call-without-arguments declaration. +# +/^[a-zA-Z]+[a-zA-Z0-9\-]*[ \t]*;[ \t]*$/ { + # strip the trailing ; + call_name = $1 + gsub(";$", "", call_name) + + start_decl(call_name) + + emit_binding("") + emit_name_macro() + emit_invoke_macro("generic", "", "NULL") + + next +} +# +# End of a declaration. Wrap up the structure declaration and emit +# the binding information. +# +/^}[ \t]*;[ \t]*$/ { + if (state != "expecting-decl-end") { + print "unexpected end of declaration at line " NR \ + > "/dev/stderr" + exit 1 + } + + # Terminate the args structure declaration. + printf("};\n") + + printf("\n") + emit_binding("binding") + emit_name_macro() + emit_invoke_macro("binding", "(_args_)", "(_args_)") + + state = "expecting-decl-start" + + next +} +# +# Default action is to simply emit the line as it exists in the source +# file. +# +{ + print $0 +} +END { + if (state != "expecting-decl-start") { + print "unexpected end of file at line " NR \ + > "/dev/stderr" + exit 1 + } + + # Emit the trailing header guard. + printf("\n#endif /* _%s_CALLS_H_ */\n", subsystem_ub_uc) +} Index: kern/subr_device.c =================================================================== RCS file: /cvsroot/src/sys/kern/subr_device.c,v retrieving revision 1.8 diff -u -p -r1.8 subr_device.c --- kern/subr_device.c 7 Aug 2021 18:16:42 -0000 1.8 +++ kern/subr_device.c 14 Sep 2021 01:18:37 -0000 @@ -33,6 +33,8 @@ __KERNEL_RCSID(0, "$NetBSD: subr_device. #include #include +#include + /* Root device. */ device_t root_device; @@ -285,17 +287,17 @@ device_handle(device_t dev) } int -device_call(device_t dev, const char *name, void *arg) +device_call_generic(device_t dev, const struct device_call_generic *gen) { devhandle_t handle = device_handle(dev); device_call_t call; devhandle_t call_handle; - call = devhandle_lookup_device_call(handle, name, &call_handle); + call = devhandle_lookup_device_call(handle, gen->name, &call_handle); if (call == NULL) { return ENOTSUP; } - return call(dev, call_handle, arg); + return call(dev, call_handle, gen->args); } int @@ -308,5 +310,5 @@ device_enumerate_children(device_t dev, .callback_arg = callback_arg, }; - return device_call(dev, "device-enumerate-children", &args); + return device_call(dev, DEVICE_ENUMERATE_CHILDREN(&args)); } Index: sys/Makefile =================================================================== RCS file: /cvsroot/src/sys/sys/Makefile,v retrieving revision 1.176 diff -u -p -r1.176 Makefile --- sys/Makefile 14 Aug 2020 00:53:16 -0000 1.176 +++ sys/Makefile 14 Sep 2021 01:18:37 -0000 @@ -70,4 +70,10 @@ INCSYMLINKS+= ../soundcard.h ${INCSDIR}/ namei: namei.src gennameih.awk ${TOOL_AWK} -f gennameih.awk < namei.src +device_calls.h: ${.CURDIR}/../kern/device_calls + echo "${TOOL_AWK} -f ${.CURDIR}/../kern/gendevcalls.awk \ + ${.CURDIR}/../kern/device_calls > ${.CURDIR}/device_calls.h" + ${TOOL_AWK} -f ${.CURDIR}/../kern/gendevcalls.awk \ + ${.CURDIR}/../kern/device_calls > ${.CURDIR}/device_calls.h + .include Index: sys/device.h =================================================================== RCS file: /cvsroot/src/sys/sys/device.h,v retrieving revision 1.174 diff -u -p -r1.174 device.h --- sys/device.h 15 Aug 2021 22:08:01 -0000 1.174 +++ sys/device.h 14 Sep 2021 01:18:37 -0000 @@ -791,21 +791,20 @@ device_t shutdown_next(struct shutdown_s * the device autoconfiguration subsystem. It is the responsibility * of each device tree back end to implement these calls. * - * device-enumerate-children - * - * Enumerates the direct children of a device, invoking the - * callback for each one. The callback is passed the devhandle_t - * corresponding to the child device, as well as a user-supplied - * argument. If the callback returns true, then enumeration - * continues. If the callback returns false, enumeration is stopped. + * We define a generic interface; individual device calls feature + * type checking of the argument structure. The argument structures + * and the call binding data are automatically generated from device + * call interface descriptions by gendevcalls.awk. */ - -struct device_enumerate_children_args { - bool (*callback)(device_t, devhandle_t, void *); - void * callback_arg; +struct device_call_generic { + const char *name; + void *args; }; -int device_call(device_t, const char *, void *); +int device_call_generic(device_t, const struct device_call_generic *); + +#define device_call(dev, call) \ + device_call_generic((dev), &(call)->generic) #endif /* _KERNEL */ Index: sys/device_calls.h =================================================================== RCS file: sys/device_calls.h diff -N sys/device_calls.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/device_calls.h 14 Sep 2021 01:18:37 -0000 @@ -0,0 +1,76 @@ +/* $NetBSD$ */ + +/* + * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. + * + * generated from: + * NetBSD + */ + +/*- + * Copyright (c) 2021 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * 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. + */ + +/* + * Device calls used by the device autoconfiguration subsystem + */ + +#ifndef _DEVICE_CALLS_H_ +#define _DEVICE_CALLS_H_ + +/* + * device-enumerate-children + * + * Enumerates the direct children of a device, invoking the callback for + * each one. The callback is passed the devhandle_t corresponding to the + * child device, as well as a user-supplied argument. If the callback + * returns true, then enumeration continues. If the callback returns false, + * enumeration is stopped. + */ +struct device_enumerate_children_args { + bool (*callback)(device_t, devhandle_t, void *); + void * callback_arg; +}; + +union device_enumerate_children_binding { + struct device_call_generic generic; + struct { + const char *name; + struct device_enumerate_children_args *args; + } binding; +}; + +#define DEVICE_ENUMERATE_CHILDREN_STR "device-enumerate-children" + +#define DEVICE_ENUMERATE_CHILDREN(_args_) \ + &((const union device_enumerate_children_binding){ \ + .binding.name = "device-enumerate-children", \ + .binding.args = (_args_), \ + }) + +#endif /* _DEVICE_CALLS_H_ */