diff options
Diffstat (limited to 'sys/dev/acpica')
-rw-r--r-- | sys/dev/acpica/acpi.c | 4 | ||||
-rw-r--r-- | sys/dev/acpica/acpi_pci.c | 68 | ||||
-rw-r--r-- | sys/dev/acpica/acpi_pcivar.h | 38 | ||||
-rw-r--r-- | sys/dev/acpica/acpivar.h | 2 |
4 files changed, 80 insertions, 32 deletions
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 6f5a11f..32a07dd 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -31,6 +31,8 @@ __FBSDID("$FreeBSD$"); #include "opt_acpi.h" +#include "opt_device_numa.h" + #include <sys/param.h> #include <sys/kernel.h> #include <sys/proc.h> @@ -1083,7 +1085,7 @@ acpi_hint_device_unit(device_t acdev, device_t child, const char *name, int acpi_parse_pxm(device_t dev, int *domain) { -#if MAXMEMDOM > 1 +#ifdef DEVICE_NUMA ACPI_HANDLE h; int d, pxm; diff --git a/sys/dev/acpica/acpi_pci.c b/sys/dev/acpica/acpi_pci.c index 9509f82..1dee131 100644 --- a/sys/dev/acpica/acpi_pci.c +++ b/sys/dev/acpica/acpi_pci.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include <contrib/dev/acpica/include/accommon.h> #include <dev/acpica/acpivar.h> +#include <dev/acpica/acpi_pcivar.h> #include <sys/pciio.h> #include <dev/pci/pcireg.h> @@ -70,6 +71,7 @@ CTASSERT(ACPI_STATE_D2 == PCI_POWERSTATE_D2); CTASSERT(ACPI_STATE_D3 == PCI_POWERSTATE_D3); static int acpi_pci_attach(device_t dev); +static void acpi_pci_child_deleted(device_t dev, device_t child); static int acpi_pci_child_location_str_method(device_t cbdev, device_t child, char *buf, size_t buflen); static int acpi_pci_probe(device_t dev); @@ -97,11 +99,13 @@ static device_method_t acpi_pci_methods[] = { /* Bus interface */ DEVMETHOD(bus_read_ivar, acpi_pci_read_ivar), DEVMETHOD(bus_write_ivar, acpi_pci_write_ivar), + DEVMETHOD(bus_child_deleted, acpi_pci_child_deleted), DEVMETHOD(bus_child_location_str, acpi_pci_child_location_str_method), DEVMETHOD(bus_get_dma_tag, acpi_pci_get_dma_tag), DEVMETHOD(bus_get_domain, acpi_get_domain), /* PCI interface */ + DEVMETHOD(pci_child_added, acpi_pci_child_added), DEVMETHOD(pci_set_powerstate, acpi_pci_set_powerstate_method), #ifdef PCI_IOV DEVMETHOD(pci_create_iov_child, acpi_pci_create_iov_child), @@ -153,6 +157,16 @@ acpi_pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value) return (pci_write_ivar(dev, child, which, value)); } +static void +acpi_pci_child_deleted(device_t dev, device_t child) +{ + struct acpi_pci_devinfo *dinfo = device_get_ivars(child); + + if (acpi_get_device(dinfo->ap_handle) == child) + AcpiDetachData(dinfo->ap_handle, acpi_fake_objhandler); + pci_child_deleted(dev, child); +} + static int acpi_pci_child_location_str_method(device_t cbdev, device_t child, char *buf, size_t buflen) @@ -259,31 +273,35 @@ acpi_pci_save_handle(ACPI_HANDLE handle, UINT32 level, void *context, void **status) { struct acpi_pci_devinfo *dinfo; - device_t *devlist; - int devcount, i, func, slot; + device_t child; + int func, slot; UINT32 address; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + child = context; if (ACPI_FAILURE(acpi_GetInteger(handle, "_ADR", &address))) return_ACPI_STATUS (AE_OK); slot = ACPI_ADR_PCI_SLOT(address); func = ACPI_ADR_PCI_FUNC(address); - if (device_get_children((device_t)context, &devlist, &devcount) != 0) - return_ACPI_STATUS (AE_OK); - for (i = 0; i < devcount; i++) { - dinfo = device_get_ivars(devlist[i]); - if (dinfo->ap_dinfo.cfg.func == func && - dinfo->ap_dinfo.cfg.slot == slot) { - dinfo->ap_handle = handle; - acpi_pci_update_device(handle, devlist[i]); - break; - } + dinfo = device_get_ivars(child); + if (dinfo->ap_dinfo.cfg.func == func && + dinfo->ap_dinfo.cfg.slot == slot) { + dinfo->ap_handle = handle; + acpi_pci_update_device(handle, child); + return_ACPI_STATUS (AE_CTRL_TERMINATE); } - free(devlist, M_TEMP); return_ACPI_STATUS (AE_OK); } +void +acpi_pci_child_added(device_t dev, device_t child) +{ + + AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1, + acpi_pci_save_handle, NULL, child, NULL); +} + static int acpi_pci_probe(device_t dev) { @@ -313,18 +331,18 @@ acpi_pci_attach(device_t dev) busno = pcib_get_bus(dev); /* - * First, PCI devices are added as in the normal PCI bus driver. - * Afterwards, the ACPI namespace under the bridge driver is - * walked to save ACPI handles to all the devices that appear in - * the ACPI namespace as immediate descendants of the bridge. + * PCI devices are added via the bus scan in the normal PCI + * bus driver. As each device is added, the + * acpi_pci_child_added() callback walks the ACPI namespace + * under the bridge driver to save ACPI handles to all the + * devices that appear in the ACPI namespace as immediate + * descendants of the bridge. * * XXX: Sometimes PCI devices show up in the ACPI namespace that * pci_add_children() doesn't find. We currently just ignore * these devices. */ pci_add_children(dev, domain, busno, sizeof(struct acpi_pci_devinfo)); - AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1, - acpi_pci_save_handle, NULL, dev, NULL); return (bus_generic_attach(dev)); } @@ -359,17 +377,9 @@ static device_t acpi_pci_create_iov_child(device_t bus, device_t pf, uint16_t rid, uint16_t vid, uint16_t did) { - struct acpi_pci_devinfo *dinfo; - device_t vf; - - vf = pci_add_iov_child(bus, pf, sizeof(struct acpi_pci_devinfo), rid, - vid, did); - if (vf == NULL) - return (NULL); - dinfo = device_get_ivars(vf); - dinfo->ap_handle = NULL; - return (vf); + return (pci_add_iov_child(bus, pf, sizeof(struct acpi_pci_devinfo), rid, + vid, did)); } #endif diff --git a/sys/dev/acpica/acpi_pcivar.h b/sys/dev/acpica/acpi_pcivar.h new file mode 100644 index 0000000..a720cc2 --- /dev/null +++ b/sys/dev/acpica/acpi_pcivar.h @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2016 John Baldwin <jhb@FreeBSD.org> + * 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 _ACPI_PCIVAR_H_ +#define _ACPI_PCIVAR_H_ + +#ifdef _KERNEL + +void acpi_pci_child_added(device_t dev, device_t child); + +#endif + +#endif /* !_ACPI_PCIVAR_H_ */ diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h index 4df83d5..3ee7ab3 100644 --- a/sys/dev/acpica/acpivar.h +++ b/sys/dev/acpica/acpivar.h @@ -502,9 +502,7 @@ SYSCTL_DECL(_debug_acpi); * * Returns the VM domain ID if found, or -1 if not found / invalid. */ -#if MAXMEMDOM > 1 extern int acpi_map_pxm_to_vm_domainid(int pxm); -#endif extern int acpi_get_domain(device_t dev, device_t child, int *domain); extern int acpi_parse_pxm(device_t dev, int *domain); |