Module Name: src Committed By: thorpej Date: Wed May 12 23:22:33 UTC 2021
Modified Files: src/sys/arch/arm/acpi: acpi_platform.c src/sys/arch/evbarm/conf: files.fdt src/sys/arch/macppc/conf: files.macppc src/sys/arch/ofppc/conf: files.ofppc src/sys/arch/sparc64/conf: files.sparc64 src/sys/arch/sparc64/sparc64: autoconf.c src/sys/arch/x86/acpi: acpi_machdep.c src/sys/dev/acpi: acpi.c acpi_pci.c acpivar.h src/sys/dev/ofw: files.ofw src/sys/dev/pci: pci.c pcivar.h Added Files: src/sys/dev/ofw: ofw_pci_subr.c Log Message: - Define a device call for PCI bus instances to fetch a direct child's device handle given the device's device/function #s (extracted from a pcitag_t). Use it to associate the handle with the child device at config_found() time. - Implement this device call for ACPI and OpenFirmware. - Enable the OpenFirmware variant for evbarm FDT, macppc, ofppc, sparc64. - Obsolete acpi_device_register(); it is no longer needed. - Obsolete setting the OpenFirmware handle in PCI devices in the sparc64 device_register(); it is no longer needed. To generate a diff of this commit: cvs rdiff -u -r1.25 -r1.26 src/sys/arch/arm/acpi/acpi_platform.c cvs rdiff -u -r1.7 -r1.8 src/sys/arch/evbarm/conf/files.fdt cvs rdiff -u -r1.117 -r1.118 src/sys/arch/macppc/conf/files.macppc cvs rdiff -u -r1.47 -r1.48 src/sys/arch/ofppc/conf/files.ofppc cvs rdiff -u -r1.165 -r1.166 src/sys/arch/sparc64/conf/files.sparc64 cvs rdiff -u -r1.230 -r1.231 src/sys/arch/sparc64/sparc64/autoconf.c cvs rdiff -u -r1.31 -r1.32 src/sys/arch/x86/acpi/acpi_machdep.c cvs rdiff -u -r1.291 -r1.292 src/sys/dev/acpi/acpi.c cvs rdiff -u -r1.30 -r1.31 src/sys/dev/acpi/acpi_pci.c cvs rdiff -u -r1.85 -r1.86 src/sys/dev/acpi/acpivar.h cvs rdiff -u -r1.16 -r1.17 src/sys/dev/ofw/files.ofw cvs rdiff -u -r0 -r1.1 src/sys/dev/ofw/ofw_pci_subr.c cvs rdiff -u -r1.159 -r1.160 src/sys/dev/pci/pci.c cvs rdiff -u -r1.114 -r1.115 src/sys/dev/pci/pcivar.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/arch/arm/acpi/acpi_platform.c diff -u src/sys/arch/arm/acpi/acpi_platform.c:1.25 src/sys/arch/arm/acpi/acpi_platform.c:1.26 --- src/sys/arch/arm/acpi/acpi_platform.c:1.25 Sat Apr 24 23:36:25 2021 +++ src/sys/arch/arm/acpi/acpi_platform.c Wed May 12 23:22:32 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_platform.c,v 1.25 2021/04/24 23:36:25 thorpej Exp $ */ +/* $NetBSD: acpi_platform.c,v 1.26 2021/05/12 23:22:32 thorpej Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include "opt_multiprocessor.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_platform.c,v 1.25 2021/04/24 23:36:25 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_platform.c,v 1.26 2021/05/12 23:22:32 thorpej Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -287,8 +287,6 @@ acpi_platform_init_attach_args(struct fd static void acpi_platform_device_register(device_t self, void *aux) { - acpi_device_register(self, aux); - #if NCOM > 0 prop_dictionary_t prop = device_properties(self); ACPI_STATUS rv; Index: src/sys/arch/evbarm/conf/files.fdt diff -u src/sys/arch/evbarm/conf/files.fdt:1.7 src/sys/arch/evbarm/conf/files.fdt:1.8 --- src/sys/arch/evbarm/conf/files.fdt:1.7 Sat Dec 12 09:27:31 2020 +++ src/sys/arch/evbarm/conf/files.fdt Wed May 12 23:22:32 2021 @@ -1,9 +1,10 @@ -# $NetBSD: files.fdt,v 1.7 2020/12/12 09:27:31 skrll Exp $ +# $NetBSD: files.fdt,v 1.8 2021/05/12 23:22:32 thorpej Exp $ # # FDT-based kernel configuration info # file arch/evbarm/fdt/fdt_dma_machdep.c fdt file arch/evbarm/fdt/fdt_machdep.c fdt +file dev/ofw/ofw_pci_subr.c fdt & pci include "arch/arm/fdt/files.fdt" Index: src/sys/arch/macppc/conf/files.macppc diff -u src/sys/arch/macppc/conf/files.macppc:1.117 src/sys/arch/macppc/conf/files.macppc:1.118 --- src/sys/arch/macppc/conf/files.macppc:1.117 Sat May 1 15:12:25 2021 +++ src/sys/arch/macppc/conf/files.macppc Wed May 12 23:22:33 2021 @@ -1,4 +1,4 @@ -# $NetBSD: files.macppc,v 1.117 2021/05/01 15:12:25 thorpej Exp $ +# $NetBSD: files.macppc,v 1.118 2021/05/12 23:22:33 thorpej Exp $ # # macppc-specific configuration info @@ -93,6 +93,7 @@ include "dev/isa/files.isa" include "dev/pci/files.pci" include "dev/pci/files.agp" file arch/macppc/pci/pci_machdep.c pci +file dev/ofw/ofw_pci_subr.c pci file arch/macppc/pci/agp_machdep.c agp file arch/powerpc/pci/pciconf_indirect.c pci file arch/powerpc/pci/pci_machdep_common.c pci Index: src/sys/arch/ofppc/conf/files.ofppc diff -u src/sys/arch/ofppc/conf/files.ofppc:1.47 src/sys/arch/ofppc/conf/files.ofppc:1.48 --- src/sys/arch/ofppc/conf/files.ofppc:1.47 Mon Dec 18 15:53:39 2017 +++ src/sys/arch/ofppc/conf/files.ofppc Wed May 12 23:22:33 2021 @@ -1,4 +1,4 @@ -# $NetBSD: files.ofppc,v 1.47 2017/12/18 15:53:39 skrll Exp $ +# $NetBSD: files.ofppc,v 1.48 2021/05/12 23:22:33 thorpej Exp $ # # NetBSD/ofppc configuration info # @@ -77,6 +77,7 @@ file arch/powerpc/pci/pciconf_ofmethod.c file arch/powerpc/pci/pci_machdep_common.c pci file arch/powerpc/pci/pci_machdep_ofw.c pci file arch/powerpc/pci/pci_module.c pci & modular +file dev/ofw/ofw_pci_subr.c pci device ofwpci: pcibus attach ofwpci at mainbus Index: src/sys/arch/sparc64/conf/files.sparc64 diff -u src/sys/arch/sparc64/conf/files.sparc64:1.165 src/sys/arch/sparc64/conf/files.sparc64:1.166 --- src/sys/arch/sparc64/conf/files.sparc64:1.165 Sun Apr 25 13:22:49 2021 +++ src/sys/arch/sparc64/conf/files.sparc64 Wed May 12 23:22:33 2021 @@ -1,4 +1,4 @@ -# $NetBSD: files.sparc64,v 1.165 2021/04/25 13:22:49 thorpej Exp $ +# $NetBSD: files.sparc64,v 1.166 2021/05/12 23:22:33 thorpej Exp $ # @(#)files.sparc64 8.1 (Berkeley) 7/19/93 # sparc64-specific configuration info @@ -44,6 +44,7 @@ file arch/sparc64/dev/schizo.c schizo file arch/sparc64/dev/pyro.c pyro file arch/sparc64/dev/vpci.c vpci file arch/sparc64/dev/pci_machdep.c psycho | schizo | pyro | vpci +file dev/ofw/ofw_pci_subr.c pci device jbusi2c: i2cexec, i2c_bitbang, i2cbus attach jbusi2c at mainbus Index: src/sys/arch/sparc64/sparc64/autoconf.c diff -u src/sys/arch/sparc64/sparc64/autoconf.c:1.230 src/sys/arch/sparc64/sparc64/autoconf.c:1.231 --- src/sys/arch/sparc64/sparc64/autoconf.c:1.230 Tue May 11 03:43:30 2021 +++ src/sys/arch/sparc64/sparc64/autoconf.c Wed May 12 23:22:33 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: autoconf.c,v 1.230 2021/05/11 03:43:30 thorpej Exp $ */ +/* $NetBSD: autoconf.c,v 1.231 2021/05/12 23:22:33 thorpej Exp $ */ /* * Copyright (c) 1996 @@ -48,7 +48,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.230 2021/05/11 03:43:30 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.231 2021/05/12 23:22:33 thorpej Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -1025,18 +1025,6 @@ device_register(device_t dev, void *aux) * Ignore mainbus0 itself, it certainly is not a boot * device. */ - } else if (device_is_a(busdev, "pci")) { - struct pci_attach_args *pa = aux; - - /* - * XXX PCI devices don't currently get their devhandles - * set when the PCI layer attaches them, so we need to - * do it here. (It's not just us; ACPI has the same - * problem...) - */ - ofnode = (int)PCITAG_NODE(pa->pa_tag); - devhandle = devhandle_from_of(ofnode); - device_set_handle(dev, devhandle); } else if (device_is_a(busdev, "iic")) { struct i2c_attach_args *ia = aux; Index: src/sys/arch/x86/acpi/acpi_machdep.c diff -u src/sys/arch/x86/acpi/acpi_machdep.c:1.31 src/sys/arch/x86/acpi/acpi_machdep.c:1.32 --- src/sys/arch/x86/acpi/acpi_machdep.c:1.31 Thu Feb 4 23:54:48 2021 +++ src/sys/arch/x86/acpi/acpi_machdep.c Wed May 12 23:22:33 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_machdep.c,v 1.31 2021/02/04 23:54:48 thorpej Exp $ */ +/* $NetBSD: acpi_machdep.c,v 1.32 2021/05/12 23:22:33 thorpej Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.31 2021/02/04 23:54:48 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.32 2021/05/12 23:22:33 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -603,8 +603,6 @@ device_acpi_register(device_t dev, void if (parent == NULL) return; - acpi_device_register(dev, aux); - device_is_vga = device_is_a(dev, "vga") || device_is_a(dev, "genfb"); device_is_pci = device_is_a(parent, "pci"); device_is_isa = device_is_a(parent, "isa"); Index: src/sys/dev/acpi/acpi.c diff -u src/sys/dev/acpi/acpi.c:1.291 src/sys/dev/acpi/acpi.c:1.292 --- src/sys/dev/acpi/acpi.c:1.291 Sat Apr 24 23:36:52 2021 +++ src/sys/dev/acpi/acpi.c Wed May 12 23:22:33 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi.c,v 1.291 2021/04/24 23:36:52 thorpej Exp $ */ +/* $NetBSD: acpi.c,v 1.292 2021/05/12 23:22:33 thorpej Exp $ */ /*- * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc. @@ -100,7 +100,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.291 2021/04/24 23:36:52 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.292 2021/05/12 23:22:33 thorpej Exp $"); #include "pci.h" #include "opt_acpi.h" @@ -1146,43 +1146,6 @@ acpi_print(void *aux, const char *pnp) } /* - * acpi_device_register -- - * Called by the platform device_register() routine when - * attaching devices. - */ -void -acpi_device_register(device_t dev, void *v) -{ - /* All we do here is set the devhandle in the device_t. */ - device_t parent = device_parent(dev); - ACPI_HANDLE hdl = NULL; - - if (device_is_a(parent, "pci")) { - const struct pci_attach_args *pa = v; - struct acpi_devnode *ad; - u_int segment; - -#ifdef __HAVE_PCI_GET_SEGMENT - segment = pci_get_segment(pa->pa_pc); -#else - segment = 0; -#endif /* __HAVE_PCI_GET_SEGMENT */ - - ad = acpi_pcidev_find(segment, - pa->pa_bus, pa->pa_device, pa->pa_function); - if (ad == NULL || (hdl = ad->ad_handle) == NULL) { - aprint_debug_dev(dev, "no matching ACPI node\n"); - return; - } - } else { - return; - } - KASSERT(hdl != NULL); - - device_set_handle(dev, devhandle_from_acpi(hdl)); -} - -/* * Notify. */ static void Index: src/sys/dev/acpi/acpi_pci.c diff -u src/sys/dev/acpi/acpi_pci.c:1.30 src/sys/dev/acpi/acpi_pci.c:1.31 --- src/sys/dev/acpi/acpi_pci.c:1.30 Thu Jan 14 14:37:17 2021 +++ src/sys/dev/acpi/acpi_pci.c Wed May 12 23:22:33 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_pci.c,v 1.30 2021/01/14 14:37:17 thorpej Exp $ */ +/* $NetBSD: acpi_pci.c,v 1.31 2021/05/12 23:22:33 thorpej Exp $ */ /* * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc. @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_pci.c,v 1.30 2021/01/14 14:37:17 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_pci.c,v 1.31 2021/05/12 23:22:33 thorpej Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -542,3 +542,39 @@ acpi_pci_ignore_boot_config(ACPI_HANDLE return ret; } + +/* + * acpi_pci_bus_get_child_devhandle: + * + * Implements the "pci-bus-get-child-devhandle" device call for + * ACPI device handles + */ +static int +acpi_pci_bus_get_child_devhandle(device_t dev, devhandle_t call_handle, void *v) +{ + struct pci_bus_get_child_devhandle_args *args = v; + struct acpi_devnode *ad; + ACPI_HANDLE hdl; + int b, d, f; + u_int segment; + +#ifdef __HAVE_PCI_GET_SEGMENT + segment = pci_get_segment(args->pc); +#else + segment = 0; +#endif /* __HAVE_PCI_GET_SEGMENT */ + + pci_decompose_tag(args->pc, args->tag, &b, &d, &f); + + ad = acpi_pcidev_find(segment, b, d, f); + + if (ad != NULL && (hdl = ad->ad_handle) != NULL) { + /* Found it! */ + args->devhandle = devhandle_from_acpi(hdl); + return 0; + } + + return ENODEV; +} +ACPI_DEVICE_CALL_REGISTER("pci-bus-get-child-devhandle", + acpi_pci_bus_get_child_devhandle) Index: src/sys/dev/acpi/acpivar.h diff -u src/sys/dev/acpi/acpivar.h:1.85 src/sys/dev/acpi/acpivar.h:1.86 --- src/sys/dev/acpi/acpivar.h:1.85 Thu Feb 4 21:39:00 2021 +++ src/sys/dev/acpi/acpivar.h Wed May 12 23:22:33 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: acpivar.h,v 1.85 2021/02/04 21:39:00 thorpej Exp $ */ +/* $NetBSD: acpivar.h,v 1.86 2021/05/12 23:22:33 thorpej Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. @@ -319,7 +319,6 @@ const struct device_compatible_entry * const struct device_compatible_entry *); bool acpi_device_present(ACPI_HANDLE); -void acpi_device_register(device_t, void *); int acpi_reset(void); Index: src/sys/dev/ofw/files.ofw diff -u src/sys/dev/ofw/files.ofw:1.16 src/sys/dev/ofw/files.ofw:1.17 --- src/sys/dev/ofw/files.ofw:1.16 Thu Feb 4 20:19:09 2021 +++ src/sys/dev/ofw/files.ofw Wed May 12 23:22:33 2021 @@ -1,4 +1,4 @@ -# $NetBSD: files.ofw,v 1.16 2021/02/04 20:19:09 thorpej Exp $ +# $NetBSD: files.ofw,v 1.17 2021/05/12 23:22:33 thorpej Exp $ # # First cut on Openfirmware interface # @@ -17,6 +17,9 @@ file dev/ofw/ofw_i2c_subr.c ofbus | ope file dev/ofw/ofw_network_subr.c of_network_dev file dev/ofw/ofw_spi_subr.c ofbus | openfirm | ofw_subr +# Let individual ports pull this in, as necessary. +#file dev/ofw/ofw_pci_subr.c ofbus | openfirm | ofw_subr + # Generic disk support device ofdisk: disk attach ofdisk at ofbus Index: src/sys/dev/pci/pci.c diff -u src/sys/dev/pci/pci.c:1.159 src/sys/dev/pci/pci.c:1.160 --- src/sys/dev/pci/pci.c:1.159 Sat Apr 24 23:36:57 2021 +++ src/sys/dev/pci/pci.c Wed May 12 23:22:33 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: pci.c,v 1.159 2021/04/24 23:36:57 thorpej Exp $ */ +/* $NetBSD: pci.c,v 1.160 2021/05/12 23:22:33 thorpej Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.159 2021/04/24 23:36:57 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.160 2021/05/12 23:22:33 thorpej Exp $"); #ifdef _KERNEL_OPT #include "opt_pci.h" @@ -267,6 +267,27 @@ pciprint(void *aux, const char *pnp) return UNCONF; } +static devhandle_t +pci_bus_get_child_devhandle(struct pci_softc *sc, pcitag_t tag) +{ + struct pci_bus_get_child_devhandle_args args = { + .pc = sc->sc_pc, + .tag = tag, + }; + + 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. + * Return an invalid handle. + */ + devhandle_invalidate(&args.devhandle); + } + + return args.devhandle; +} + int pci_probe_device(struct pci_softc *sc, pcitag_t tag, int (*match)(const struct pci_attach_args *), @@ -415,6 +436,8 @@ pci_probe_device(struct pci_softc *sc, p } pa.pa_intrline = PCI_INTERRUPT_LINE(intr); + devhandle_t devhandle = pci_bus_get_child_devhandle(sc, pa.pa_tag); + #ifdef __HAVE_PCI_MSI_MSIX if (pci_get_ht_capability(pc, tag, PCI_HT_CAP_MSIMAP, &off, &cap)) { /* @@ -464,6 +487,7 @@ pci_probe_device(struct pci_softc *sc, p c->c_dev = config_found(sc->sc_dev, &pa, pciprint, CFARG_SUBMATCH, config_stdsubmatch, CFARG_LOCATORS, locs, + CFARG_DEVHANDLE, devhandle, CFARG_EOL); ret = (c->c_dev != NULL); Index: src/sys/dev/pci/pcivar.h diff -u src/sys/dev/pci/pcivar.h:1.114 src/sys/dev/pci/pcivar.h:1.115 --- src/sys/dev/pci/pcivar.h:1.114 Wed Jan 27 05:00:16 2021 +++ src/sys/dev/pci/pcivar.h Wed May 12 23:22:33 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: pcivar.h,v 1.114 2021/01/27 05:00:16 thorpej Exp $ */ +/* $NetBSD: pcivar.h,v 1.115 2021/05/12 23:22:33 thorpej Exp $ */ /* * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. @@ -277,6 +277,31 @@ 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; Added files: Index: src/sys/dev/ofw/ofw_pci_subr.c diff -u /dev/null src/sys/dev/ofw/ofw_pci_subr.c:1.1 --- /dev/null Wed May 12 23:22:34 2021 +++ src/sys/dev/ofw/ofw_pci_subr.c Wed May 12 23:22:33 2021 @@ -0,0 +1,86 @@ +/* $NetBSD: ofw_pci_subr.c,v 1.1 2021/05/12 23:22:33 thorpej Exp $ */ + +/*- + * 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. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: ofw_pci_subr.c,v 1.1 2021/05/12 23:22:33 thorpej Exp $"); + +#include <sys/types.h> +#include <sys/device.h> +#include <sys/endian.h> +#include <sys/errno.h> + +#include <dev/pci/pcivar.h> + +#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_pci.h> + +static int +ofw_pci_bus_get_child_devhandle(device_t dev, devhandle_t call_handle, void *v) +{ + struct pci_bus_get_child_devhandle_args *args = v; + int phandle = devhandle_to_of(call_handle); + struct ofw_pci_register opr; + int d, f, len; + uint32_t phys_hi; + + /* + * No need to compare the bus number; we are searching + * only direct children of the specified node. Skipping + * the bus number comparison allows us to dodge a slight + * difference between the OpenFirmware and FDT PCI bindings + * as it relates to PCI-PCI bridges. + */ + + pci_decompose_tag(args->pc, args->tag, NULL, &d, &f); + + for (phandle = OF_child(phandle); phandle != 0; + phandle = OF_peer(phandle)) { + len = OF_getprop(phandle, "reg", &opr, sizeof(opr)); + if (len < sizeof(opr)) { + continue; + } + + phys_hi = be32toh(opr.phys_hi); + + if (d != OFW_PCI_PHYS_HI_DEVICE(phys_hi) || + f != OFW_PCI_PHYS_HI_FUNCTION(phys_hi)) { + continue; + } + + /* Found it! */ + args->devhandle = devhandle_from_of(phandle); + return 0; + } + + return ENODEV; +} +OF_DEVICE_CALL_REGISTER("pci-bus-get-child-devhandle", + ofw_pci_bus_get_child_devhandle)