1318136Ssephe/*- 2318136Ssephe * Copyright (c) 2017 Microsoft Corp. 3318136Ssephe * All rights reserved. 4318136Ssephe * 5318136Ssephe * Redistribution and use in source and binary forms, with or without 6318136Ssephe * modification, are permitted provided that the following conditions 7318136Ssephe * are met: 8318136Ssephe * 1. Redistributions of source code must retain the above copyright 9318136Ssephe * notice unmodified, this list of conditions, and the following 10318136Ssephe * disclaimer. 11318136Ssephe * 2. Redistributions in binary form must reproduce the above copyright 12318136Ssephe * notice, this list of conditions and the following disclaimer in the 13318136Ssephe * documentation and/or other materials provided with the distribution. 14318136Ssephe * 15318136Ssephe * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16318136Ssephe * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17318136Ssephe * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18318136Ssephe * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19318136Ssephe * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20318136Ssephe * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21318136Ssephe * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22318136Ssephe * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23318136Ssephe * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24318136Ssephe * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25318136Ssephe */ 26318136Ssephe 27318136Ssephe#include <sys/cdefs.h> 28318136Ssephe__FBSDID("$FreeBSD: stable/11/sys/dev/acpica/acpi_container.c 318392 2017-05-17 01:48:44Z sephe $"); 29318136Ssephe 30318136Ssephe#include <sys/param.h> 31318136Ssephe#include <sys/kernel.h> 32318136Ssephe#include <sys/bus.h> 33318136Ssephe#include <sys/module.h> 34318136Ssephe 35318136Ssephe#include <contrib/dev/acpica/include/acpi.h> 36318136Ssephe#include <dev/acpica/acpivar.h> 37318136Ssephe 38318136Ssephe#include "pcib_if.h" 39318136Ssephe 40318136SsepheACPI_MODULE_NAME("CONTAINER") 41318136Ssephe 42318136Ssephestatic int acpi_syscont_probe(device_t); 43318136Ssephestatic int acpi_syscont_attach(device_t); 44318136Ssephestatic int acpi_syscont_detach(device_t); 45318136Ssephestatic int acpi_syscont_alloc_msi(device_t, device_t, 46318136Ssephe int count, int maxcount, int *irqs); 47318136Ssephestatic int acpi_syscont_release_msi(device_t bus, device_t dev, 48318136Ssephe int count, int *irqs); 49318136Ssephestatic int acpi_syscont_alloc_msix(device_t bus, device_t dev, 50318136Ssephe int *irq); 51318136Ssephestatic int acpi_syscont_release_msix(device_t bus, device_t dev, 52318136Ssephe int irq); 53318136Ssephestatic int acpi_syscont_map_msi(device_t bus, device_t dev, 54318136Ssephe int irq, uint64_t *addr, uint32_t *data); 55318136Ssephe 56318136Ssephestatic device_method_t acpi_syscont_methods[] = { 57318136Ssephe /* Device interface */ 58318136Ssephe DEVMETHOD(device_probe, acpi_syscont_probe), 59318136Ssephe DEVMETHOD(device_attach, acpi_syscont_attach), 60318136Ssephe DEVMETHOD(device_detach, acpi_syscont_detach), 61318136Ssephe 62318136Ssephe /* Bus interface */ 63318136Ssephe DEVMETHOD(bus_add_child, bus_generic_add_child), 64318136Ssephe DEVMETHOD(bus_print_child, bus_generic_print_child), 65318136Ssephe DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), 66318136Ssephe DEVMETHOD(bus_release_resource, bus_generic_release_resource), 67318136Ssephe DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 68318136Ssephe DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 69318136Ssephe DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 70318136Ssephe DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 71318136Ssephe#if __FreeBSD_version >= 1100000 72318136Ssephe DEVMETHOD(bus_get_cpus, bus_generic_get_cpus), 73318136Ssephe#endif 74318136Ssephe 75318136Ssephe /* pcib interface */ 76318136Ssephe DEVMETHOD(pcib_alloc_msi, acpi_syscont_alloc_msi), 77318136Ssephe DEVMETHOD(pcib_release_msi, acpi_syscont_release_msi), 78318136Ssephe DEVMETHOD(pcib_alloc_msix, acpi_syscont_alloc_msix), 79318136Ssephe DEVMETHOD(pcib_release_msix, acpi_syscont_release_msix), 80318136Ssephe DEVMETHOD(pcib_map_msi, acpi_syscont_map_msi), 81318136Ssephe 82318136Ssephe DEVMETHOD_END 83318136Ssephe}; 84318136Ssephe 85318136Ssephestatic driver_t acpi_syscont_driver = { 86318136Ssephe "acpi_syscontainer", 87318136Ssephe acpi_syscont_methods, 88318136Ssephe 0, 89318136Ssephe}; 90318136Ssephe 91318136Ssephestatic devclass_t acpi_syscont_devclass; 92318136Ssephe 93318136SsepheDRIVER_MODULE(acpi_syscontainer, acpi, acpi_syscont_driver, 94318136Ssephe acpi_syscont_devclass, NULL, NULL); 95318136SsepheMODULE_DEPEND(acpi_syscontainer, acpi, 1, 1, 1); 96318136Ssephe 97318136Ssephestatic int 98318136Ssepheacpi_syscont_probe(device_t dev) 99318136Ssephe{ 100318136Ssephe static char *syscont_ids[] = { "ACPI0004", "PNP0A05", "PNP0A06", NULL }; 101318136Ssephe 102318136Ssephe if (acpi_disabled("syscontainer") || 103318136Ssephe ACPI_ID_PROBE(device_get_parent(dev), dev, syscont_ids) == NULL) 104318136Ssephe return (ENXIO); 105318136Ssephe 106318136Ssephe device_set_desc(dev, "System Container"); 107318136Ssephe return (BUS_PROBE_DEFAULT); 108318136Ssephe} 109318136Ssephe 110318136Ssephestatic int 111318136Ssepheacpi_syscont_attach(device_t dev) 112318136Ssephe{ 113318136Ssephe 114318136Ssephe bus_generic_probe(dev); 115318136Ssephe return (bus_generic_attach(dev)); 116318136Ssephe} 117318136Ssephe 118318136Ssephestatic int 119318136Ssepheacpi_syscont_detach(device_t dev) 120318136Ssephe{ 121318136Ssephe 122318136Ssephe return (bus_generic_detach(dev)); 123318136Ssephe} 124318136Ssephe 125318136Ssephestatic int 126318136Ssepheacpi_syscont_alloc_msi(device_t bus, device_t dev, int count, int maxcount, 127318136Ssephe int *irqs) 128318136Ssephe{ 129318136Ssephe device_t parent = device_get_parent(bus); 130318136Ssephe 131318136Ssephe return (PCIB_ALLOC_MSI(device_get_parent(parent), dev, count, maxcount, 132318136Ssephe irqs)); 133318136Ssephe} 134318136Ssephe 135318136Ssephestatic int 136318136Ssepheacpi_syscont_release_msi(device_t bus, device_t dev, int count, int *irqs) 137318136Ssephe{ 138318136Ssephe device_t parent = device_get_parent(bus); 139318136Ssephe 140318136Ssephe return (PCIB_RELEASE_MSI(device_get_parent(parent), dev, count, irqs)); 141318136Ssephe} 142318136Ssephe 143318136Ssephestatic int 144318136Ssepheacpi_syscont_alloc_msix(device_t bus, device_t dev, int *irq) 145318136Ssephe{ 146318136Ssephe device_t parent = device_get_parent(bus); 147318136Ssephe 148318136Ssephe return (PCIB_ALLOC_MSIX(device_get_parent(parent), dev, irq)); 149318136Ssephe} 150318136Ssephe 151318136Ssephestatic int 152318136Ssepheacpi_syscont_release_msix(device_t bus, device_t dev, int irq) 153318136Ssephe{ 154318136Ssephe device_t parent = device_get_parent(bus); 155318136Ssephe 156318136Ssephe return (PCIB_RELEASE_MSIX(device_get_parent(parent), dev, irq)); 157318136Ssephe} 158318136Ssephe 159318136Ssephestatic int 160318136Ssepheacpi_syscont_map_msi(device_t bus, device_t dev, int irq, uint64_t *addr, 161318136Ssephe uint32_t *data) 162318136Ssephe{ 163318136Ssephe device_t parent = device_get_parent(bus); 164318136Ssephe 165318136Ssephe return (PCIB_MAP_MSI(device_get_parent(parent), dev, irq, addr, data)); 166318136Ssephe} 167