1098ca2bdSWarner Losh /*- 228bf1fadSJohn Baldwin * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 328bf1fadSJohn Baldwin * Copyright (c) 2000, Michael Smith <msmith@freebsd.org> 428bf1fadSJohn Baldwin * Copyright (c) 2000, BSDi 528bf1fadSJohn Baldwin * All rights reserved. 628bf1fadSJohn Baldwin * 728bf1fadSJohn Baldwin * Redistribution and use in source and binary forms, with or without 828bf1fadSJohn Baldwin * modification, are permitted provided that the following conditions 928bf1fadSJohn Baldwin * are met: 1028bf1fadSJohn Baldwin * 1. Redistributions of source code must retain the above copyright 1128bf1fadSJohn Baldwin * notice unmodified, this list of conditions, and the following 1228bf1fadSJohn Baldwin * disclaimer. 1328bf1fadSJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright 1428bf1fadSJohn Baldwin * notice, this list of conditions and the following disclaimer in the 1528bf1fadSJohn Baldwin * documentation and/or other materials provided with the distribution. 1628bf1fadSJohn Baldwin * 1728bf1fadSJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1828bf1fadSJohn Baldwin * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1928bf1fadSJohn Baldwin * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2028bf1fadSJohn Baldwin * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2128bf1fadSJohn Baldwin * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2228bf1fadSJohn Baldwin * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2328bf1fadSJohn Baldwin * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2428bf1fadSJohn Baldwin * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2528bf1fadSJohn Baldwin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2628bf1fadSJohn Baldwin * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2728bf1fadSJohn Baldwin */ 2828bf1fadSJohn Baldwin 29aad970f1SDavid E. O'Brien #include <sys/cdefs.h> 30aad970f1SDavid E. O'Brien __FBSDID("$FreeBSD$"); 31aad970f1SDavid E. O'Brien 3286be9f0dSKonstantin Belousov #include "opt_acpi.h" 3386be9f0dSKonstantin Belousov 3428bf1fadSJohn Baldwin #include <sys/param.h> 3528bf1fadSJohn Baldwin #include <sys/systm.h> 3628bf1fadSJohn Baldwin #include <sys/bus.h> 3728bf1fadSJohn Baldwin #include <sys/kernel.h> 3828bf1fadSJohn Baldwin #include <sys/malloc.h> 3928bf1fadSJohn Baldwin #include <sys/module.h> 4028bf1fadSJohn Baldwin 41129d3046SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 42129d3046SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 43129d3046SJung-uk Kim 4428bf1fadSJohn Baldwin #include <dev/acpica/acpivar.h> 45*65252317SJohn Baldwin #include <dev/acpica/acpi_pcivar.h> 4628bf1fadSJohn Baldwin 4728bf1fadSJohn Baldwin #include <sys/pciio.h> 4828bf1fadSJohn Baldwin #include <dev/pci/pcireg.h> 4928bf1fadSJohn Baldwin #include <dev/pci/pcivar.h> 5028bf1fadSJohn Baldwin #include <dev/pci/pci_private.h> 5128bf1fadSJohn Baldwin 5228bf1fadSJohn Baldwin #include "pcib_if.h" 5328bf1fadSJohn Baldwin #include "pci_if.h" 5428bf1fadSJohn Baldwin 555acd0218SNate Lawson /* Hooks for the ACPI CA debugging infrastructure. */ 5628bf1fadSJohn Baldwin #define _COMPONENT ACPI_BUS 5728bf1fadSJohn Baldwin ACPI_MODULE_NAME("PCI") 5828bf1fadSJohn Baldwin 5928bf1fadSJohn Baldwin struct acpi_pci_devinfo { 6028bf1fadSJohn Baldwin struct pci_devinfo ap_dinfo; 6128bf1fadSJohn Baldwin ACPI_HANDLE ap_handle; 62d4b9ff91SNate Lawson int ap_flags; 6328bf1fadSJohn Baldwin }; 6428bf1fadSJohn Baldwin 65f4e6d08dSNate Lawson ACPI_SERIAL_DECL(pci_powerstate, "ACPI PCI power methods"); 66f4e6d08dSNate Lawson 67a811035eSNate Lawson /* Be sure that ACPI and PCI power states are equivalent. */ 68a811035eSNate Lawson CTASSERT(ACPI_STATE_D0 == PCI_POWERSTATE_D0); 69a811035eSNate Lawson CTASSERT(ACPI_STATE_D1 == PCI_POWERSTATE_D1); 70a811035eSNate Lawson CTASSERT(ACPI_STATE_D2 == PCI_POWERSTATE_D2); 71a811035eSNate Lawson CTASSERT(ACPI_STATE_D3 == PCI_POWERSTATE_D3); 72a811035eSNate Lawson 7328bf1fadSJohn Baldwin static int acpi_pci_attach(device_t dev); 74496dfa89SJohn Baldwin static void acpi_pci_child_deleted(device_t dev, device_t child); 75cd284d7aSTakanori Watanabe static int acpi_pci_child_location_str_method(device_t cbdev, 76cd284d7aSTakanori Watanabe device_t child, char *buf, size_t buflen); 7781bb99d2SJohn Baldwin static int acpi_pci_probe(device_t dev); 7881bb99d2SJohn Baldwin static int acpi_pci_read_ivar(device_t dev, device_t child, int which, 7981bb99d2SJohn Baldwin uintptr_t *result); 80d4b9ff91SNate Lawson static int acpi_pci_write_ivar(device_t dev, device_t child, int which, 81d4b9ff91SNate Lawson uintptr_t value); 8228bf1fadSJohn Baldwin static ACPI_STATUS acpi_pci_save_handle(ACPI_HANDLE handle, UINT32 level, 8328bf1fadSJohn Baldwin void *context, void **status); 8481bb99d2SJohn Baldwin static int acpi_pci_set_powerstate_method(device_t dev, device_t child, 8581bb99d2SJohn Baldwin int state); 8681bb99d2SJohn Baldwin static void acpi_pci_update_device(ACPI_HANDLE handle, device_t pci_child); 8786be9f0dSKonstantin Belousov static bus_dma_tag_t acpi_pci_get_dma_tag(device_t bus, device_t child); 8828bf1fadSJohn Baldwin 899bfb1e36SRyan Stone #ifdef PCI_IOV 909bfb1e36SRyan Stone static device_t acpi_pci_create_iov_child(device_t bus, device_t pf, 919bfb1e36SRyan Stone uint16_t rid, uint16_t vid, uint16_t did); 929bfb1e36SRyan Stone #endif 939bfb1e36SRyan Stone 9428bf1fadSJohn Baldwin static device_method_t acpi_pci_methods[] = { 9528bf1fadSJohn Baldwin /* Device interface */ 9628bf1fadSJohn Baldwin DEVMETHOD(device_probe, acpi_pci_probe), 9728bf1fadSJohn Baldwin DEVMETHOD(device_attach, acpi_pci_attach), 9828bf1fadSJohn Baldwin 9928bf1fadSJohn Baldwin /* Bus interface */ 10028bf1fadSJohn Baldwin DEVMETHOD(bus_read_ivar, acpi_pci_read_ivar), 101d4b9ff91SNate Lawson DEVMETHOD(bus_write_ivar, acpi_pci_write_ivar), 102496dfa89SJohn Baldwin DEVMETHOD(bus_child_deleted, acpi_pci_child_deleted), 103cd284d7aSTakanori Watanabe DEVMETHOD(bus_child_location_str, acpi_pci_child_location_str_method), 10486be9f0dSKonstantin Belousov DEVMETHOD(bus_get_dma_tag, acpi_pci_get_dma_tag), 105ffcf962dSAdrian Chadd DEVMETHOD(bus_get_domain, acpi_get_domain), 10628bf1fadSJohn Baldwin 10728bf1fadSJohn Baldwin /* PCI interface */ 108*65252317SJohn Baldwin DEVMETHOD(pci_child_added, acpi_pci_child_added), 1095233e9ffSJohn Baldwin DEVMETHOD(pci_set_powerstate, acpi_pci_set_powerstate_method), 1109bfb1e36SRyan Stone #ifdef PCI_IOV 1119bfb1e36SRyan Stone DEVMETHOD(pci_create_iov_child, acpi_pci_create_iov_child), 1129bfb1e36SRyan Stone #endif 11328bf1fadSJohn Baldwin 11461bfd867SSofian Brabez DEVMETHOD_END 11528bf1fadSJohn Baldwin }; 11628bf1fadSJohn Baldwin 11714450110SJohn Baldwin static devclass_t pci_devclass; 11828bf1fadSJohn Baldwin 1191b1596a3SJohn Baldwin DEFINE_CLASS_1(pci, acpi_pci_driver, acpi_pci_methods, sizeof(struct pci_softc), 1201b1596a3SJohn Baldwin pci_driver); 12128bf1fadSJohn Baldwin DRIVER_MODULE(acpi_pci, pcib, acpi_pci_driver, pci_devclass, 0, 0); 12264278df5SNate Lawson MODULE_DEPEND(acpi_pci, acpi, 1, 1, 1); 12328bf1fadSJohn Baldwin MODULE_DEPEND(acpi_pci, pci, 1, 1, 1); 12464278df5SNate Lawson MODULE_VERSION(acpi_pci, 1); 12528bf1fadSJohn Baldwin 12628bf1fadSJohn Baldwin static int 12728bf1fadSJohn Baldwin acpi_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 12828bf1fadSJohn Baldwin { 12928bf1fadSJohn Baldwin struct acpi_pci_devinfo *dinfo; 13028bf1fadSJohn Baldwin 131d4b9ff91SNate Lawson dinfo = device_get_ivars(child); 13228bf1fadSJohn Baldwin switch (which) { 13328bf1fadSJohn Baldwin case ACPI_IVAR_HANDLE: 13428bf1fadSJohn Baldwin *result = (uintptr_t)dinfo->ap_handle; 13528bf1fadSJohn Baldwin return (0); 136d4b9ff91SNate Lawson case ACPI_IVAR_FLAGS: 137d4b9ff91SNate Lawson *result = (uintptr_t)dinfo->ap_flags; 138d4b9ff91SNate Lawson return (0); 13928bf1fadSJohn Baldwin } 14028bf1fadSJohn Baldwin return (pci_read_ivar(dev, child, which, result)); 14128bf1fadSJohn Baldwin } 14228bf1fadSJohn Baldwin 143cd284d7aSTakanori Watanabe static int 144d4b9ff91SNate Lawson acpi_pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 145d4b9ff91SNate Lawson { 146d4b9ff91SNate Lawson struct acpi_pci_devinfo *dinfo; 147d4b9ff91SNate Lawson 148d4b9ff91SNate Lawson dinfo = device_get_ivars(child); 149d4b9ff91SNate Lawson switch (which) { 150d4b9ff91SNate Lawson case ACPI_IVAR_HANDLE: 151d4b9ff91SNate Lawson dinfo->ap_handle = (ACPI_HANDLE)value; 152d4b9ff91SNate Lawson return (0); 153d4b9ff91SNate Lawson case ACPI_IVAR_FLAGS: 154d4b9ff91SNate Lawson dinfo->ap_flags = (int)value; 155d4b9ff91SNate Lawson return (0); 156d4b9ff91SNate Lawson } 157d4b9ff91SNate Lawson return (pci_write_ivar(dev, child, which, value)); 158d4b9ff91SNate Lawson } 159d4b9ff91SNate Lawson 160496dfa89SJohn Baldwin static void 161496dfa89SJohn Baldwin acpi_pci_child_deleted(device_t dev, device_t child) 162496dfa89SJohn Baldwin { 163496dfa89SJohn Baldwin struct acpi_pci_devinfo *dinfo = device_get_ivars(child); 164496dfa89SJohn Baldwin 165496dfa89SJohn Baldwin if (acpi_get_device(dinfo->ap_handle) == child) 166496dfa89SJohn Baldwin AcpiDetachData(dinfo->ap_handle, acpi_fake_objhandler); 167496dfa89SJohn Baldwin pci_child_deleted(dev, child); 168496dfa89SJohn Baldwin } 169496dfa89SJohn Baldwin 170d4b9ff91SNate Lawson static int 171cd284d7aSTakanori Watanabe acpi_pci_child_location_str_method(device_t cbdev, device_t child, char *buf, 172cd284d7aSTakanori Watanabe size_t buflen) 173cd284d7aSTakanori Watanabe { 174cd284d7aSTakanori Watanabe struct acpi_pci_devinfo *dinfo = device_get_ivars(child); 1759cf5a6aaSAdrian Chadd int pxm; 1769cf5a6aaSAdrian Chadd char buf2[32]; 17763600cc3SNate Lawson 178cd284d7aSTakanori Watanabe pci_child_location_str_method(cbdev, child, buf, buflen); 179cd284d7aSTakanori Watanabe 180cd284d7aSTakanori Watanabe if (dinfo->ap_handle) { 1818c4c207dSTakanori Watanabe strlcat(buf, " handle=", buflen); 182cd284d7aSTakanori Watanabe strlcat(buf, acpi_name(dinfo->ap_handle), buflen); 1839cf5a6aaSAdrian Chadd 1849cf5a6aaSAdrian Chadd if (ACPI_SUCCESS(acpi_GetInteger(dinfo->ap_handle, "_PXM", &pxm))) { 1859cf5a6aaSAdrian Chadd snprintf(buf2, 32, " _PXM=%d", pxm); 1869cf5a6aaSAdrian Chadd strlcat(buf, buf2, buflen); 1879cf5a6aaSAdrian Chadd } 188cd284d7aSTakanori Watanabe } 189cd284d7aSTakanori Watanabe return (0); 190cd284d7aSTakanori Watanabe } 191cd284d7aSTakanori Watanabe 19228bf1fadSJohn Baldwin /* 19328bf1fadSJohn Baldwin * PCI power manangement 19428bf1fadSJohn Baldwin */ 19528bf1fadSJohn Baldwin static int 19628bf1fadSJohn Baldwin acpi_pci_set_powerstate_method(device_t dev, device_t child, int state) 19728bf1fadSJohn Baldwin { 198916dc0e2SNate Lawson ACPI_HANDLE h; 1995233e9ffSJohn Baldwin ACPI_STATUS status; 200a811035eSNate Lawson int old_state, error; 2015233e9ffSJohn Baldwin 202f4e6d08dSNate Lawson error = 0; 203a811035eSNate Lawson if (state < ACPI_STATE_D0 || state > ACPI_STATE_D3) 2045233e9ffSJohn Baldwin return (EINVAL); 20528bf1fadSJohn Baldwin 2065233e9ffSJohn Baldwin /* 2075233e9ffSJohn Baldwin * We set the state using PCI Power Management outside of setting 2085233e9ffSJohn Baldwin * the ACPI state. This means that when powering down a device, we 2095233e9ffSJohn Baldwin * first shut it down using PCI, and then using ACPI, which lets ACPI 2105233e9ffSJohn Baldwin * try to power down any Power Resources that are now no longer used. 2115233e9ffSJohn Baldwin * When powering up a device, we let ACPI set the state first so that 2125233e9ffSJohn Baldwin * it can enable any needed Power Resources before changing the PCI 2135233e9ffSJohn Baldwin * power state. 2145233e9ffSJohn Baldwin */ 215f4e6d08dSNate Lawson ACPI_SERIAL_BEGIN(pci_powerstate); 2165233e9ffSJohn Baldwin old_state = pci_get_powerstate(child); 217f3e0b109SJung-uk Kim if (old_state < state && pci_do_power_suspend) { 2185233e9ffSJohn Baldwin error = pci_set_powerstate_method(dev, child, state); 2195233e9ffSJohn Baldwin if (error) 220f4e6d08dSNate Lawson goto out; 22128bf1fadSJohn Baldwin } 2221f36889fSNate Lawson h = acpi_get_handle(child); 223a811035eSNate Lawson status = acpi_pwr_switch_consumer(h, state); 224a7a3177fSJung-uk Kim if (ACPI_SUCCESS(status)) { 225a7a3177fSJung-uk Kim if (bootverbose) 226a7a3177fSJung-uk Kim device_printf(dev, "set ACPI power state D%d on %s\n", 227a7a3177fSJung-uk Kim state, acpi_name(h)); 228a7a3177fSJung-uk Kim } else if (status != AE_NOT_FOUND) 2295233e9ffSJohn Baldwin device_printf(dev, 230a7a3177fSJung-uk Kim "failed to set ACPI power state D%d on %s: %s\n", 231a811035eSNate Lawson state, acpi_name(h), AcpiFormatException(status)); 232edc0cb7dSJung-uk Kim if (old_state > state && pci_do_power_resume) 233f4e6d08dSNate Lawson error = pci_set_powerstate_method(dev, child, state); 234f4e6d08dSNate Lawson 235f4e6d08dSNate Lawson out: 236f4e6d08dSNate Lawson ACPI_SERIAL_END(pci_powerstate); 237f4e6d08dSNate Lawson return (error); 2385233e9ffSJohn Baldwin } 23928bf1fadSJohn Baldwin 24081bb99d2SJohn Baldwin static void 24181bb99d2SJohn Baldwin acpi_pci_update_device(ACPI_HANDLE handle, device_t pci_child) 24281bb99d2SJohn Baldwin { 24381bb99d2SJohn Baldwin ACPI_STATUS status; 24481bb99d2SJohn Baldwin device_t child; 24581bb99d2SJohn Baldwin 24681bb99d2SJohn Baldwin /* 247183c8af3SJohn Baldwin * Occasionally a PCI device may show up as an ACPI device 248183c8af3SJohn Baldwin * with a _HID. (For example, the TabletPC TC1000 has a 249183c8af3SJohn Baldwin * second PCI-ISA bridge that has a _HID for an 250183c8af3SJohn Baldwin * acpi_sysresource device.) In that case, leave ACPI-CA's 251183c8af3SJohn Baldwin * device data pointing at the ACPI-enumerated device. 25281bb99d2SJohn Baldwin */ 25381bb99d2SJohn Baldwin child = acpi_get_device(handle); 25481bb99d2SJohn Baldwin if (child != NULL) { 25581bb99d2SJohn Baldwin KASSERT(device_get_parent(child) == 25681bb99d2SJohn Baldwin devclass_get_device(devclass_find("acpi"), 0), 25781bb99d2SJohn Baldwin ("%s: child (%s)'s parent is not acpi0", __func__, 25881bb99d2SJohn Baldwin acpi_name(handle))); 259183c8af3SJohn Baldwin return; 26081bb99d2SJohn Baldwin } 26181bb99d2SJohn Baldwin 26281bb99d2SJohn Baldwin /* 26381bb99d2SJohn Baldwin * Update ACPI-CA to use the PCI enumerated device_t for this handle. 26481bb99d2SJohn Baldwin */ 26530d577a0SNate Lawson status = AcpiAttachData(handle, acpi_fake_objhandler, pci_child); 26681bb99d2SJohn Baldwin if (ACPI_FAILURE(status)) 26781bb99d2SJohn Baldwin printf("WARNING: Unable to attach object data to %s - %s\n", 26881bb99d2SJohn Baldwin acpi_name(handle), AcpiFormatException(status)); 26981bb99d2SJohn Baldwin } 27081bb99d2SJohn Baldwin 27128bf1fadSJohn Baldwin static ACPI_STATUS 27228bf1fadSJohn Baldwin acpi_pci_save_handle(ACPI_HANDLE handle, UINT32 level, void *context, 27328bf1fadSJohn Baldwin void **status) 27428bf1fadSJohn Baldwin { 27528bf1fadSJohn Baldwin struct acpi_pci_devinfo *dinfo; 276*65252317SJohn Baldwin device_t child; 277*65252317SJohn Baldwin int func, slot; 27828bf1fadSJohn Baldwin UINT32 address; 27928bf1fadSJohn Baldwin 28028bf1fadSJohn Baldwin ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 28128bf1fadSJohn Baldwin 282*65252317SJohn Baldwin child = context; 283c310653eSNate Lawson if (ACPI_FAILURE(acpi_GetInteger(handle, "_ADR", &address))) 28428bf1fadSJohn Baldwin return_ACPI_STATUS (AE_OK); 285e0a93586SJohn Baldwin slot = ACPI_ADR_PCI_SLOT(address); 286e0a93586SJohn Baldwin func = ACPI_ADR_PCI_FUNC(address); 287*65252317SJohn Baldwin dinfo = device_get_ivars(child); 28828bf1fadSJohn Baldwin if (dinfo->ap_dinfo.cfg.func == func && 28928bf1fadSJohn Baldwin dinfo->ap_dinfo.cfg.slot == slot) { 29028bf1fadSJohn Baldwin dinfo->ap_handle = handle; 291*65252317SJohn Baldwin acpi_pci_update_device(handle, child); 292*65252317SJohn Baldwin return_ACPI_STATUS (AE_CTRL_TERMINATE); 29328bf1fadSJohn Baldwin } 29428bf1fadSJohn Baldwin return_ACPI_STATUS (AE_OK); 29528bf1fadSJohn Baldwin } 29628bf1fadSJohn Baldwin 297*65252317SJohn Baldwin void 298*65252317SJohn Baldwin acpi_pci_child_added(device_t dev, device_t child) 299*65252317SJohn Baldwin { 300*65252317SJohn Baldwin 301*65252317SJohn Baldwin AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1, 302*65252317SJohn Baldwin acpi_pci_save_handle, NULL, child, NULL); 303*65252317SJohn Baldwin } 304*65252317SJohn Baldwin 30528bf1fadSJohn Baldwin static int 30628bf1fadSJohn Baldwin acpi_pci_probe(device_t dev) 30728bf1fadSJohn Baldwin { 30828bf1fadSJohn Baldwin 30928bf1fadSJohn Baldwin if (acpi_get_handle(dev) == NULL) 31028bf1fadSJohn Baldwin return (ENXIO); 3115acd0218SNate Lawson device_set_desc(dev, "ACPI PCI bus"); 31244e06d15SRoger Pau Monné return (BUS_PROBE_DEFAULT); 31328bf1fadSJohn Baldwin } 31428bf1fadSJohn Baldwin 31528bf1fadSJohn Baldwin static int 31628bf1fadSJohn Baldwin acpi_pci_attach(device_t dev) 31728bf1fadSJohn Baldwin { 3181b1596a3SJohn Baldwin int busno, domain, error; 3191b1596a3SJohn Baldwin 3201b1596a3SJohn Baldwin error = pci_attach_common(dev); 3211b1596a3SJohn Baldwin if (error) 3221b1596a3SJohn Baldwin return (error); 32328bf1fadSJohn Baldwin 32428bf1fadSJohn Baldwin /* 32528bf1fadSJohn Baldwin * Since there can be multiple independantly numbered PCI 32670bc2d3fSJohn Baldwin * busses on systems with multiple PCI domains, we can't use 32770bc2d3fSJohn Baldwin * the unit number to decide which bus we are probing. We ask 32855aaf894SMarius Strobl * the parent pcib what our domain and bus numbers are. 32928bf1fadSJohn Baldwin */ 33055aaf894SMarius Strobl domain = pcib_get_domain(dev); 33128bf1fadSJohn Baldwin busno = pcib_get_bus(dev); 33228bf1fadSJohn Baldwin 33328bf1fadSJohn Baldwin /* 334*65252317SJohn Baldwin * PCI devices are added via the bus scan in the normal PCI 335*65252317SJohn Baldwin * bus driver. As each device is added, the 336*65252317SJohn Baldwin * acpi_pci_child_added() callback walks the ACPI namespace 337*65252317SJohn Baldwin * under the bridge driver to save ACPI handles to all the 338*65252317SJohn Baldwin * devices that appear in the ACPI namespace as immediate 339*65252317SJohn Baldwin * descendants of the bridge. 34028bf1fadSJohn Baldwin * 34128bf1fadSJohn Baldwin * XXX: Sometimes PCI devices show up in the ACPI namespace that 34228bf1fadSJohn Baldwin * pci_add_children() doesn't find. We currently just ignore 34328bf1fadSJohn Baldwin * these devices. 34428bf1fadSJohn Baldwin */ 34555aaf894SMarius Strobl pci_add_children(dev, domain, busno, sizeof(struct acpi_pci_devinfo)); 34628bf1fadSJohn Baldwin 34728bf1fadSJohn Baldwin return (bus_generic_attach(dev)); 34828bf1fadSJohn Baldwin } 34986be9f0dSKonstantin Belousov 35086be9f0dSKonstantin Belousov #ifdef ACPI_DMAR 35186be9f0dSKonstantin Belousov bus_dma_tag_t dmar_get_dma_tag(device_t dev, device_t child); 35286be9f0dSKonstantin Belousov static bus_dma_tag_t 35386be9f0dSKonstantin Belousov acpi_pci_get_dma_tag(device_t bus, device_t child) 35486be9f0dSKonstantin Belousov { 35586be9f0dSKonstantin Belousov bus_dma_tag_t tag; 35686be9f0dSKonstantin Belousov 35786be9f0dSKonstantin Belousov if (device_get_parent(child) == bus) { 35886be9f0dSKonstantin Belousov /* try dmar and return if it works */ 35986be9f0dSKonstantin Belousov tag = dmar_get_dma_tag(bus, child); 36086be9f0dSKonstantin Belousov } else 36186be9f0dSKonstantin Belousov tag = NULL; 36286be9f0dSKonstantin Belousov if (tag == NULL) 36386be9f0dSKonstantin Belousov tag = pci_get_dma_tag(bus, child); 36486be9f0dSKonstantin Belousov return (tag); 36586be9f0dSKonstantin Belousov } 36686be9f0dSKonstantin Belousov #else 36786be9f0dSKonstantin Belousov static bus_dma_tag_t 36886be9f0dSKonstantin Belousov acpi_pci_get_dma_tag(device_t bus, device_t child) 36986be9f0dSKonstantin Belousov { 37086be9f0dSKonstantin Belousov 37186be9f0dSKonstantin Belousov return (pci_get_dma_tag(bus, child)); 37286be9f0dSKonstantin Belousov } 37386be9f0dSKonstantin Belousov #endif 3749bfb1e36SRyan Stone 3759bfb1e36SRyan Stone #ifdef PCI_IOV 3769bfb1e36SRyan Stone static device_t 3779bfb1e36SRyan Stone acpi_pci_create_iov_child(device_t bus, device_t pf, uint16_t rid, uint16_t vid, 3789bfb1e36SRyan Stone uint16_t did) 3799bfb1e36SRyan Stone { 3809bfb1e36SRyan Stone 381*65252317SJohn Baldwin return (pci_add_iov_child(bus, pf, sizeof(struct acpi_pci_devinfo), rid, 382*65252317SJohn Baldwin vid, did)); 3839bfb1e36SRyan Stone } 3849bfb1e36SRyan Stone #endif 3859bfb1e36SRyan Stone 386