[BACK]Return to acpi.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / acpi

Annotation of src/sys/dev/acpi/acpi.c, Revision 1.271.2.2

1.271.2.2! martin      1: /*     $NetBSD$        */
1.50      mycroft     2:
                      3: /*-
1.101     ad          4:  * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
1.50      mycroft     5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Charles M. Hannum of By Noon Software, Inc.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     20:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     21:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     22:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     23:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     24:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     25:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     26:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     27:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     28:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     29:  * POSSIBILITY OF SUCH DAMAGE.
                     30:  */
1.1       thorpej    31:
                     32: /*
1.212     jruoho     33:  * Copyright (c) 2003 Wasabi Systems, Inc.
                     34:  * All rights reserved.
                     35:  *
                     36:  * Written by Frank van der Linden for Wasabi Systems, Inc.
                     37:  *
                     38:  * Redistribution and use in source and binary forms, with or without
                     39:  * modification, are permitted provided that the following conditions
                     40:  * are met:
                     41:  * 1. Redistributions of source code must retain the above copyright
                     42:  *    notice, this list of conditions and the following disclaimer.
                     43:  * 2. Redistributions in binary form must reproduce the above copyright
                     44:  *    notice, this list of conditions and the following disclaimer in the
                     45:  *    documentation and/or other materials provided with the distribution.
                     46:  * 3. All advertising materials mentioning features or use of this software
                     47:  *    must display the following acknowledgement:
                     48:  *      This product includes software developed for the NetBSD Project by
                     49:  *      Wasabi Systems, Inc.
                     50:  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
                     51:  *    or promote products derived from this software without specific prior
                     52:  *    written permission.
                     53:  *
                     54:  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
                     55:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     56:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     57:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
                     58:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     59:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     60:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     61:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     62:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     63:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     64:  * POSSIBILITY OF SUCH DAMAGE.
                     65:  */
                     66:
                     67: /*
1.34      thorpej    68:  * Copyright 2001, 2003 Wasabi Systems, Inc.
1.1       thorpej    69:  * All rights reserved.
                     70:  *
                     71:  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
                     72:  *
                     73:  * Redistribution and use in source and binary forms, with or without
                     74:  * modification, are permitted provided that the following conditions
                     75:  * are met:
                     76:  * 1. Redistributions of source code must retain the above copyright
                     77:  *    notice, this list of conditions and the following disclaimer.
                     78:  * 2. Redistributions in binary form must reproduce the above copyright
                     79:  *    notice, this list of conditions and the following disclaimer in the
                     80:  *    documentation and/or other materials provided with the distribution.
                     81:  * 3. All advertising materials mentioning features or use of this software
                     82:  *    must display the following acknowledgement:
                     83:  *     This product includes software developed for the NetBSD Project by
                     84:  *     Wasabi Systems, Inc.
                     85:  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
                     86:  *    or promote products derived from this software without specific prior
                     87:  *    written permission.
                     88:  *
                     89:  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
                     90:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     91:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     92:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
                     93:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     94:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     95:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     96:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     97:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     98:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     99:  * POSSIBILITY OF SUCH DAMAGE.
                    100:  */
                    101:
1.5       lukem     102: #include <sys/cdefs.h>
1.271.2.2! martin    103: __KERNEL_RCSID(0, "$NetBSD$");
1.27      christos  104:
1.267     maya      105: #include "pci.h"
1.27      christos  106: #include "opt_acpi.h"
1.73      sekiya    107: #include "opt_pcifixup.h"
1.1       thorpej   108:
                    109: #include <sys/param.h>
                    110: #include <sys/device.h>
1.155     jruoho    111: #include <sys/kernel.h>
1.239     jruoho    112: #include <sys/kmem.h>
1.1       thorpej   113: #include <sys/malloc.h>
1.197     pgoyette  114: #include <sys/module.h>
1.100     xtraeme   115: #include <sys/mutex.h>
1.78      cube      116: #include <sys/sysctl.h>
1.155     jruoho    117: #include <sys/systm.h>
1.206     jruoho    118: #include <sys/timetc.h>
1.1       thorpej   119:
                    120: #include <dev/acpi/acpireg.h>
                    121: #include <dev/acpi/acpivar.h>
1.261     msaitoh   122: #include <dev/acpi/acpi_mcfg.h>
1.1       thorpej   123: #include <dev/acpi/acpi_osd.h>
1.155     jruoho    124: #include <dev/acpi/acpi_pci.h>
1.181     jruoho    125: #include <dev/acpi/acpi_power.h>
1.90      drochner  126: #include <dev/acpi/acpi_timer.h>
1.127     jmcneill  127: #include <dev/acpi/acpi_wakedev.h>
1.155     jruoho    128:
1.239     jruoho    129: #include <machine/acpi_machdep.h>
                    130:
1.264     riastrad  131: #include "ioconf.h"
                    132:
1.169     jruoho    133: #define _COMPONENT     ACPI_BUS_COMPONENT
                    134: ACPI_MODULE_NAME       ("acpi")
1.132     mlelstv   135:
1.1       thorpej   136: /*
1.231     jruoho    137:  * The acpi_active variable is set when the ACPI subsystem is active.
                    138:  * Machine-dependent code may wish to skip other steps (such as attaching
1.1       thorpej   139:  * subsystems that ACPI supercedes) when ACPI is active.
                    140:  */
1.231     jruoho    141: int            acpi_active = 0;
                    142: int            acpi_suspended = 0;
                    143: int            acpi_force_load = 0;
                    144: int            acpi_verbose_loaded = 0;
1.1       thorpej   145:
1.238     jruoho    146: struct acpi_softc      *acpi_softc = NULL;
1.211     jruoho    147: static uint64_t                 acpi_root_pointer;
                    148: extern kmutex_t                 acpi_interrupt_list_mtx;
                    149: static ACPI_HANDLE      acpi_scopes[4];
1.213     jruoho    150: ACPI_TABLE_HEADER      *madt_header;
1.271.2.1  christos  151: ACPI_TABLE_HEADER      *gtdt_header;
1.32      tshiozak  152:
1.79      cube      153: /*
1.176     jruoho    154:  * This structure provides a context for the ACPI
                    155:  * namespace walk performed in acpi_build_tree().
                    156:  */
                    157: struct acpi_walkcontext {
                    158:        struct acpi_softc       *aw_sc;
                    159:        struct acpi_devnode     *aw_parent;
                    160: };
                    161:
                    162: /*
1.147     jruoho    163:  * Ignored HIDs.
1.116     jmcneill  164:  */
                    165: static const char * const acpi_ignored_ids[] = {
                    166: #if defined(i386) || defined(x86_64)
1.240     jruoho    167:        "ACPI0007",     /* ACPI CPUs do not attach to acpi(4) */
1.116     jmcneill  168:        "PNP0000",      /* AT interrupt controller is handled internally */
                    169:        "PNP0200",      /* AT DMA controller is handled internally */
1.137     cegger    170:        "PNP0A??",      /* PCI Busses are handled internally */
1.116     jmcneill  171:        "PNP0B00",      /* AT RTC is handled internally */
                    172:        "PNP0C0F",      /* ACPI PCI link devices are handled internally */
                    173: #endif
                    174: #if defined(x86_64)
                    175:        "PNP0C04",      /* FPU is handled internally */
                    176: #endif
1.271.2.1  christos  177: #if defined(__aarch64__)
1.271.2.2! martin    178:        "ACPI0004",     /* ACPI module devices are handled internally */
1.271.2.1  christos  179:        "ACPI0007",     /* ACPI CPUs are attached via MADT GICC subtables */
                    180:        "PNP0C0F",      /* ACPI PCI link devices are handled internally */
                    181: #endif
1.116     jmcneill  182:        NULL
                    183: };
                    184:
1.226     jruoho    185: /*
                    186:  * Devices that should be attached early.
                    187:  */
                    188: static const char * const acpi_early_ids[] = {
                    189:        "PNP0C09",      /* acpiec(4) */
                    190:        NULL
                    191: };
                    192:
1.169     jruoho    193: static int             acpi_match(device_t, cfdata_t, void *);
                    194: static int             acpi_submatch(device_t, cfdata_t, const int *, void *);
                    195: static void            acpi_attach(device_t, device_t, void *);
                    196: static int             acpi_detach(device_t, int);
                    197: static void            acpi_childdet(device_t, device_t);
                    198: static bool            acpi_suspend(device_t, const pmf_qual_t *);
                    199: static bool            acpi_resume(device_t, const pmf_qual_t *);
                    200:
1.64      kochi     201: static void            acpi_build_tree(struct acpi_softc *);
1.255     chs       202: static void            acpi_config_tree(struct acpi_softc *);
1.271.2.2! martin    203: static void            acpi_config_dma(struct acpi_softc *);
1.151     jruoho    204: static ACPI_STATUS     acpi_make_devnode(ACPI_HANDLE, uint32_t,
                    205:                                          void *, void **);
1.176     jruoho    206: static ACPI_STATUS     acpi_make_devnode_post(ACPI_HANDLE, uint32_t,
                    207:                                               void *, void **);
1.229     jruoho    208: static void            acpi_make_name(struct acpi_devnode *, uint32_t);
1.1       thorpej   209:
1.169     jruoho    210: static int             acpi_rescan(device_t, const char *, const int *);
1.226     jruoho    211: static void            acpi_rescan_early(struct acpi_softc *);
1.169     jruoho    212: static void            acpi_rescan_nodes(struct acpi_softc *);
1.224     jruoho    213: static void            acpi_rescan_capabilities(device_t);
1.169     jruoho    214: static int             acpi_print(void *aux, const char *);
                    215:
1.175     jruoho    216: static void            acpi_notify_handler(ACPI_HANDLE, uint32_t, void *);
                    217:
1.168     jruoho    218: static void            acpi_register_fixed_button(struct acpi_softc *, int);
                    219: static void            acpi_deregister_fixed_button(struct acpi_softc *, int);
                    220: static uint32_t                acpi_fixed_button_handler(void *);
                    221: static void            acpi_fixed_button_pressed(void *);
                    222:
1.166     jruoho    223: static void            acpi_sleep_init(struct acpi_softc *);
1.1       thorpej   224:
1.209     jruoho    225: static int             sysctl_hw_acpi_fixedstats(SYSCTLFN_PROTO);
                    226: static int             sysctl_hw_acpi_sleepstate(SYSCTLFN_PROTO);
                    227: static int             sysctl_hw_acpi_sleepstates(SYSCTLFN_PROTO);
1.169     jruoho    228:
1.185     jruoho    229: static bool              acpi_is_scope(struct acpi_devnode *);
1.108     jmcneill  230: static ACPI_TABLE_HEADER *acpi_map_rsdt(void);
1.185     jruoho    231: static void              acpi_unmap_rsdt(ACPI_TABLE_HEADER *);
1.108     jmcneill  232:
1.211     jruoho    233: void                   acpi_print_verbose_stub(struct acpi_softc *);
                    234: void                   acpi_print_dev_stub(const char *);
1.123     jmcneill  235:
1.228     jruoho    236: static void            acpi_activate_device(ACPI_HANDLE, ACPI_DEVICE_INFO **);
                    237: ACPI_STATUS            acpi_allocate_resources(ACPI_HANDLE);
                    238:
1.211     jruoho    239: void (*acpi_print_verbose)(struct acpi_softc *) = acpi_print_verbose_stub;
1.200     pgoyette  240: void (*acpi_print_dev)(const char *) = acpi_print_dev_stub;
1.197     pgoyette  241:
1.271.2.2! martin    242: bus_dma_tag_t          acpi_default_dma_tag(struct acpi_softc *, struct acpi_devnode *);
        !           243: bus_dma_tag_t          acpi_default_dma64_tag(struct acpi_softc *, struct acpi_devnode *);
        !           244: pci_chipset_tag_t      acpi_default_pci_chipset_tag(struct acpi_softc *, int, int);
        !           245:
1.169     jruoho    246: CFATTACH_DECL2_NEW(acpi, sizeof(struct acpi_softc),
                    247:     acpi_match, acpi_attach, acpi_detach, NULL, acpi_rescan, acpi_childdet);
1.159     jruoho    248:
1.1       thorpej   249: /*
1.169     jruoho    250:  * Probe for ACPI support.
1.1       thorpej   251:  *
1.169     jruoho    252:  * This is called by the machine-dependent ACPI front-end.
                    253:  * Note: this is not an autoconfiguration interface function.
1.1       thorpej   254:  */
                    255: int
                    256: acpi_probe(void)
                    257: {
1.108     jmcneill  258:        ACPI_TABLE_HEADER *rsdt;
1.1       thorpej   259:        ACPI_STATUS rv;
1.238     jruoho    260:        int quirks;
1.169     jruoho    261:
1.238     jruoho    262:        if (acpi_softc != NULL)
1.169     jruoho    263:                panic("%s: already probed", __func__);
1.1       thorpej   264:
1.103     ad        265:        mutex_init(&acpi_interrupt_list_mtx, MUTEX_DEFAULT, IPL_NONE);
1.32      tshiozak  266:
1.1       thorpej   267:        /*
                    268:         * Start up ACPICA.
                    269:         */
1.172     jruoho    270:        AcpiGbl_EnableInterpreterSlack = true;
1.104     jmcneill  271:
1.1       thorpej   272:        rv = AcpiInitializeSubsystem();
1.172     jruoho    273:
1.238     jruoho    274:        if (ACPI_FAILURE(rv)) {
                    275:                aprint_error("%s: failed to initialize subsystem\n", __func__);
                    276:                return 0;
1.1       thorpej   277:        }
                    278:
1.178     jruoho    279:        /*
                    280:         * Allocate space for RSDT/XSDT and DSDT,
                    281:         * but allow resizing if more tables exist.
                    282:         */
                    283:        rv = AcpiInitializeTables(NULL, 2, true);
1.172     jruoho    284:
1.104     jmcneill  285:        if (ACPI_FAILURE(rv)) {
1.238     jruoho    286:                aprint_error("%s: failed to initialize tables\n", __func__);
1.172     jruoho    287:                goto fail;
1.104     jmcneill  288:        }
                    289:
1.1       thorpej   290:        rv = AcpiLoadTables();
1.172     jruoho    291:
1.56      mycroft   292:        if (ACPI_FAILURE(rv)) {
1.238     jruoho    293:                aprint_error("%s: failed to load tables\n", __func__);
1.172     jruoho    294:                goto fail;
1.1       thorpej   295:        }
                    296:
1.108     jmcneill  297:        rsdt = acpi_map_rsdt();
1.172     jruoho    298:
1.108     jmcneill  299:        if (rsdt == NULL) {
1.238     jruoho    300:                aprint_error("%s: failed to map RSDT\n", __func__);
1.172     jruoho    301:                goto fail;
1.108     jmcneill  302:        }
1.107     jmcneill  303:
1.238     jruoho    304:        quirks = acpi_find_quirks();
                    305:
                    306:        if (acpi_force_load == 0 && (quirks & ACPI_QUIRK_BROKEN) != 0) {
                    307:
1.172     jruoho    308:                aprint_normal("ACPI: BIOS is listed as broken:\n");
                    309:                aprint_normal("ACPI: X/RSDT: OemId <%6.6s,%8.8s,%08x>, "
1.238     jruoho    310:                       "AslId <%4.4s,%08x>\n", rsdt->OemId, rsdt->OemTableId,
                    311:                        rsdt->OemRevision, rsdt->AslCompilerId,
1.108     jmcneill  312:                        rsdt->AslCompilerRevision);
1.172     jruoho    313:                aprint_normal("ACPI: Not used. Set acpi_force_load to use.\n");
1.238     jruoho    314:
1.108     jmcneill  315:                acpi_unmap_rsdt(rsdt);
1.238     jruoho    316:                goto fail;
1.93      christos  317:        }
1.238     jruoho    318:
                    319:        if (acpi_force_load == 0 && (quirks & ACPI_QUIRK_OLDBIOS) != 0) {
                    320:
                    321:                aprint_normal("ACPI: BIOS is too old (%s). "
                    322:                    "Set acpi_force_load to use.\n",
1.252     jmcneill  323:                    pmf_get_platform("bios-date"));
1.238     jruoho    324:
1.219     jmcneill  325:                acpi_unmap_rsdt(rsdt);
1.238     jruoho    326:                goto fail;
1.219     jmcneill  327:        }
1.93      christos  328:
1.108     jmcneill  329:        acpi_unmap_rsdt(rsdt);
                    330:
1.104     jmcneill  331:        rv = AcpiEnableSubsystem(~(ACPI_NO_HARDWARE_INIT|ACPI_NO_ACPI_ENABLE));
1.172     jruoho    332:
1.104     jmcneill  333:        if (ACPI_FAILURE(rv)) {
1.238     jruoho    334:                aprint_error("%s: failed to enable subsystem\n", __func__);
1.172     jruoho    335:                goto fail;
1.104     jmcneill  336:        }
                    337:
1.63      kochi     338:        return 1;
1.172     jruoho    339:
                    340: fail:
1.238     jruoho    341:        (void)AcpiTerminate();
1.172     jruoho    342:
                    343:        return 0;
1.1       thorpej   344: }
                    345:
1.214     jruoho    346: void
                    347: acpi_disable(void)
                    348: {
                    349:
1.222     jruoho    350:        if (acpi_softc == NULL)
                    351:                return;
                    352:
                    353:        KASSERT(acpi_active != 0);
                    354:
1.214     jruoho    355:        if (AcpiGbl_FADT.SmiCommand != 0)
                    356:                AcpiDisable();
                    357: }
                    358:
1.98      cube      359: int
                    360: acpi_check(device_t parent, const char *ifattr)
                    361: {
                    362:        return (config_search_ia(acpi_submatch, parent, ifattr, NULL) != NULL);
                    363: }
                    364:
1.248     jmcneill  365: int
                    366: acpi_reset(void)
                    367: {
                    368:        struct acpi_softc *sc = acpi_softc;
                    369:        ACPI_GENERIC_ADDRESS *ResetReg;
                    370:        ACPI_PCI_ID PciId;
                    371:        ACPI_STATUS status;
                    372:
                    373:        if (sc == NULL)
                    374:                return ENXIO;
                    375:
                    376:        ResetReg = &AcpiGbl_FADT.ResetRegister;
                    377:
                    378:        /* Check if the reset register is supported */
                    379:        if (!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER) ||
                    380:            !ResetReg->Address) {
                    381:                return ENOENT;
                    382:        }
                    383:
                    384:        switch (ResetReg->SpaceId) {
                    385:        case ACPI_ADR_SPACE_PCI_CONFIG:
                    386:                PciId.Segment = PciId.Bus = 0;
                    387:                PciId.Device = ACPI_GAS_PCI_DEV(ResetReg->Address);
                    388:                PciId.Function = ACPI_GAS_PCI_FUNC(ResetReg->Address);
                    389:                status = AcpiOsWritePciConfiguration(&PciId,
                    390:                    ACPI_GAS_PCI_REGOFF(ResetReg->Address),
                    391:                    AcpiGbl_FADT.ResetValue, ResetReg->BitWidth);
                    392:                break;
                    393:        case ACPI_ADR_SPACE_SYSTEM_IO:
                    394:        case ACPI_ADR_SPACE_SYSTEM_MEMORY:
                    395:                status = AcpiReset();
                    396:                break;
                    397:        default:
                    398:                status = AE_TYPE;
                    399:                break;
                    400:        }
                    401:
                    402:        return ACPI_FAILURE(status) ? EIO : 0;
                    403: }
                    404:
1.174     jruoho    405: /*
                    406:  * Autoconfiguration.
                    407:  */
1.64      kochi     408: static int
1.126     cegger    409: acpi_match(device_t parent, cfdata_t match, void *aux)
1.1       thorpej   410: {
                    411:        /*
1.169     jruoho    412:         * XXX: Nada; MD code has called acpi_probe().
1.1       thorpej   413:         */
1.63      kochi     414:        return 1;
1.1       thorpej   415: }
                    416:
1.169     jruoho    417: static int
                    418: acpi_submatch(device_t parent, cfdata_t cf, const int *locs, void *aux)
1.111     dyoung    419: {
1.169     jruoho    420:        struct cfattach *ca;
1.111     dyoung    421:
1.169     jruoho    422:        ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname);
1.124     dyoung    423:
1.169     jruoho    424:        return (ca == &acpi_ca);
1.111     dyoung    425: }
                    426:
1.64      kochi     427: static void
1.111     dyoung    428: acpi_attach(device_t parent, device_t self, void *aux)
1.1       thorpej   429: {
1.111     dyoung    430:        struct acpi_softc *sc = device_private(self);
1.1       thorpej   431:        struct acpibus_attach_args *aa = aux;
1.166     jruoho    432:        ACPI_TABLE_HEADER *rsdt;
1.1       thorpej   433:        ACPI_STATUS rv;
                    434:
1.116     jmcneill  435:        aprint_naive("\n");
                    436:        aprint_normal(": Intel ACPICA %08x\n", ACPI_CA_VERSION);
1.1       thorpej   437:
                    438:        if (acpi_softc != NULL)
1.172     jruoho    439:                panic("%s: already attached", __func__);
1.29      fvdl      440:
1.172     jruoho    441:        rsdt = acpi_map_rsdt();
1.37      kochi     442:
1.172     jruoho    443:        if (rsdt == NULL)
                    444:                aprint_error_dev(self, "X/RSDT: Not found\n");
                    445:        else {
                    446:                aprint_verbose_dev(self,
1.111     dyoung    447:                    "X/RSDT: OemId <%6.6s,%8.8s,%08x>, AslId <%4.4s,%08x>\n",
1.108     jmcneill  448:                    rsdt->OemId, rsdt->OemTableId,
                    449:                    rsdt->OemRevision,
                    450:                    rsdt->AslCompilerId, rsdt->AslCompilerRevision);
1.172     jruoho    451:        }
1.157     jruoho    452:
1.108     jmcneill  453:        acpi_unmap_rsdt(rsdt);
1.1       thorpej   454:
1.113     jmcneill  455:        sc->sc_dev = self;
1.176     jruoho    456:        sc->sc_root = NULL;
                    457:
                    458:        sc->sc_sleepstate = ACPI_STATE_S0;
1.36      fvdl      459:        sc->sc_quirks = acpi_find_quirks();
                    460:
1.172     jruoho    461:        sysmon_power_settype("acpi");
                    462:
1.1       thorpej   463:        sc->sc_iot = aa->aa_iot;
                    464:        sc->sc_memt = aa->aa_memt;
                    465:        sc->sc_pciflags = aa->aa_pciflags;
1.19      jmcneill  466:        sc->sc_ic = aa->aa_ic;
1.262     nonaka    467:        sc->sc_dmat = aa->aa_dmat;
                    468:        sc->sc_dmat64 = aa->aa_dmat64;
1.1       thorpej   469:
1.176     jruoho    470:        SIMPLEQ_INIT(&sc->ad_head);
1.157     jruoho    471:
1.1       thorpej   472:        acpi_softc = sc;
                    473:
1.172     jruoho    474:        if (pmf_device_register(self, acpi_suspend, acpi_resume) != true)
1.104     jmcneill  475:                aprint_error_dev(self, "couldn't establish power handler\n");
                    476:
                    477:        /*
1.238     jruoho    478:         * Bring ACPICA on-line.
1.1       thorpej   479:         */
1.104     jmcneill  480:
1.255     chs       481:        rv = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION);
1.172     jruoho    482:
                    483:        if (ACPI_FAILURE(rv))
                    484:                goto fail;
1.60      kochi     485:
1.174     jruoho    486:        /*
1.243     jruoho    487:         * Early initialization of acpiec(4) via ECDT.
                    488:         */
                    489:        (void)config_found_ia(self, "acpiecdtbus", aa, NULL);
1.60      kochi     490:
1.104     jmcneill  491:        rv = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION);
1.172     jruoho    492:
                    493:        if (ACPI_FAILURE(rv))
                    494:                goto fail;
                    495:
1.175     jruoho    496:        /*
1.255     chs       497:         * Scan the namespace and build our device tree.
                    498:         */
                    499:        acpi_build_tree(sc);
                    500:
1.268     scole     501: #if NPCI > 0
1.261     msaitoh   502:        /*
                    503:         * Probe MCFG table
                    504:         */
                    505:        acpimcfg_probe(sc);
1.266     maya      506: #endif
1.261     msaitoh   507:
1.255     chs       508:        acpi_md_callback(sc);
                    509:
                    510:        /*
1.244     jruoho    511:         * Early initialization of the _PDC control method
                    512:         * that may load additional SSDT tables dynamically.
                    513:         */
                    514:        (void)acpi_md_pdc();
                    515:
                    516:        /*
1.175     jruoho    517:         * Install global notify handlers.
                    518:         */
                    519:        rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT,
                    520:            ACPI_SYSTEM_NOTIFY, acpi_notify_handler, NULL);
                    521:
                    522:        if (ACPI_FAILURE(rv))
                    523:                goto fail;
                    524:
                    525:        rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT,
                    526:            ACPI_DEVICE_NOTIFY, acpi_notify_handler, NULL);
                    527:
                    528:        if (ACPI_FAILURE(rv))
                    529:                goto fail;
                    530:
1.1       thorpej   531:        acpi_active = 1;
                    532:
1.271.2.1  christos  533:        if (!AcpiGbl_ReducedHardware) {
                    534:                /* Show SCI interrupt. */
                    535:                aprint_verbose_dev(self, "SCI interrupting at int %u\n",
                    536:                    AcpiGbl_FADT.SciInterrupt);
1.104     jmcneill  537:
1.271.2.1  christos  538:                /*
                    539:                 * Install fixed-event handlers.
                    540:                 */
                    541:                acpi_register_fixed_button(sc, ACPI_EVENT_POWER_BUTTON);
                    542:                acpi_register_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON);
                    543:        }
1.168     jruoho    544:
1.206     jruoho    545:        acpitimer_init(sc);
1.255     chs       546:        acpi_config_tree(sc);
1.166     jruoho    547:        acpi_sleep_init(sc);
1.78      cube      548:
1.148     jruoho    549: #ifdef ACPI_DEBUG
                    550:        acpi_debug_init();
                    551: #endif
1.172     jruoho    552:
1.211     jruoho    553:        /*
                    554:         * Print debug information.
                    555:         */
                    556:        acpi_print_verbose(sc);
                    557:
1.172     jruoho    558:        return;
                    559:
                    560: fail:
                    561:        aprint_error("%s: failed to initialize ACPI: %s\n",
                    562:            __func__, AcpiFormatException(rv));
1.1       thorpej   563: }
                    564:
1.171     jruoho    565: /*
                    566:  * XXX: This is incomplete.
                    567:  */
1.124     dyoung    568: static int
                    569: acpi_detach(device_t self, int flags)
                    570: {
1.168     jruoho    571:        struct acpi_softc *sc = device_private(self);
1.175     jruoho    572:        ACPI_STATUS rv;
1.124     dyoung    573:        int rc;
                    574:
1.175     jruoho    575:        rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT,
                    576:            ACPI_SYSTEM_NOTIFY, acpi_notify_handler);
                    577:
                    578:        if (ACPI_FAILURE(rv))
                    579:                return EBUSY;
                    580:
                    581:        rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT,
                    582:            ACPI_DEVICE_NOTIFY, acpi_notify_handler);
                    583:
                    584:        if (ACPI_FAILURE(rv))
                    585:                return EBUSY;
                    586:
1.124     dyoung    587:        if ((rc = config_detach_children(self, flags)) != 0)
                    588:                return rc;
                    589:
                    590:        if ((rc = acpitimer_detach()) != 0)
                    591:                return rc;
                    592:
1.271.2.1  christos  593:        if (!AcpiGbl_ReducedHardware) {
                    594:                acpi_deregister_fixed_button(sc, ACPI_EVENT_POWER_BUTTON);
                    595:                acpi_deregister_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON);
                    596:        }
1.124     dyoung    597:
                    598:        pmf_device_deregister(self);
                    599:
                    600:        acpi_softc = NULL;
                    601:
                    602:        return 0;
                    603: }
                    604:
1.169     jruoho    605: static void
                    606: acpi_childdet(device_t self, device_t child)
                    607: {
                    608:        struct acpi_softc *sc = device_private(self);
                    609:        struct acpi_devnode *ad;
                    610:
                    611:        if (sc->sc_apmbus == child)
                    612:                sc->sc_apmbus = NULL;
1.239     jruoho    613:
1.245     jruoho    614:        if (sc->sc_hpet == child)
                    615:                sc->sc_hpet = NULL;
                    616:
1.239     jruoho    617:        if (sc->sc_wdrt == child)
1.234     jmcneill  618:                sc->sc_wdrt = NULL;
1.169     jruoho    619:
1.176     jruoho    620:        SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
1.169     jruoho    621:
                    622:                if (ad->ad_device == child)
                    623:                        ad->ad_device = NULL;
                    624:        }
                    625: }
                    626:
1.123     jmcneill  627: static bool
1.149     dyoung    628: acpi_suspend(device_t dv, const pmf_qual_t *qual)
1.123     jmcneill  629: {
1.169     jruoho    630:
1.123     jmcneill  631:        acpi_suspended = 1;
1.169     jruoho    632:
1.123     jmcneill  633:        return true;
                    634: }
                    635:
                    636: static bool
1.149     dyoung    637: acpi_resume(device_t dv, const pmf_qual_t *qual)
1.123     jmcneill  638: {
1.169     jruoho    639:
1.123     jmcneill  640:        acpi_suspended = 0;
1.169     jruoho    641:
1.123     jmcneill  642:        return true;
                    643: }
                    644:
1.1       thorpej   645: /*
1.169     jruoho    646:  * Namespace scan.
1.1       thorpej   647:  */
1.64      kochi     648: static void
1.1       thorpej   649: acpi_build_tree(struct acpi_softc *sc)
                    650: {
1.176     jruoho    651:        struct acpi_walkcontext awc;
1.157     jruoho    652:
1.185     jruoho    653:        /*
                    654:         * Get the root scope handles.
                    655:         */
                    656:        KASSERT(__arraycount(acpi_scopes) == 4);
                    657:
                    658:        (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_PR_", &acpi_scopes[0]);
1.187     jruoho    659:        (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &acpi_scopes[1]);
                    660:        (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SI_", &acpi_scopes[2]);
1.185     jruoho    661:        (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_TZ_", &acpi_scopes[3]);
                    662:
                    663:        /*
                    664:         * Make the root node.
                    665:         */
1.176     jruoho    666:        awc.aw_sc = sc;
                    667:        awc.aw_parent = NULL;
                    668:
                    669:        (void)acpi_make_devnode(ACPI_ROOT_OBJECT, 0, &awc, NULL);
                    670:
                    671:        KASSERT(sc->sc_root == NULL);
                    672:        KASSERT(awc.aw_parent != NULL);
                    673:
                    674:        sc->sc_root = awc.aw_parent;
                    675:
1.185     jruoho    676:        /*
                    677:         * Build the internal namespace.
                    678:         */
1.176     jruoho    679:        (void)AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, UINT32_MAX,
                    680:            acpi_make_devnode, acpi_make_devnode_post, &awc, NULL);
                    681:
1.185     jruoho    682:        /*
                    683:         * Scan the internal namespace.
                    684:         */
1.221     gsutre    685:        (void)acpi_pcidev_scan(sc->sc_root);
1.255     chs       686: }
                    687:
                    688: static void
                    689: acpi_config_tree(struct acpi_softc *sc)
                    690: {
1.271.2.2! martin    691:        /*
        !           692:         * Assign bus_dma resources
        !           693:         */
        !           694:        acpi_config_dma(sc);
1.255     chs       695:
                    696:        /*
                    697:         * Configure all everything found "at acpi?".
                    698:         */
1.204     jruoho    699:        (void)acpi_rescan(sc->sc_dev, NULL, NULL);
                    700:
1.224     jruoho    701:        /*
1.236     jruoho    702:         * Update GPE information.
                    703:         *
                    704:         * Note that this must be called after
                    705:         * all GPE handlers have been installed.
                    706:         */
                    707:        (void)AcpiUpdateAllGpes();
                    708:
                    709:        /*
1.224     jruoho    710:         * Defer rest of the configuration.
                    711:         */
                    712:        (void)config_defer(sc->sc_dev, acpi_rescan_capabilities);
1.124     dyoung    713: }
1.1       thorpej   714:
1.271.2.2! martin    715: static void
        !           716: acpi_config_dma(struct acpi_softc *sc)
        !           717: {
        !           718:        struct acpi_devnode *ad;
        !           719:
        !           720:        SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
        !           721:
        !           722:                if (ad->ad_device != NULL)
        !           723:                        continue;
        !           724:
        !           725:                if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE)
        !           726:                        continue;
        !           727:
        !           728:                ad->ad_dmat = acpi_get_dma_tag(sc, ad);
        !           729:                ad->ad_dmat64 = acpi_get_dma64_tag(sc, ad);
        !           730:        }
        !           731: }
        !           732:
1.169     jruoho    733: static ACPI_STATUS
                    734: acpi_make_devnode(ACPI_HANDLE handle, uint32_t level,
                    735:     void *context, void **status)
1.124     dyoung    736: {
1.176     jruoho    737:        struct acpi_walkcontext *awc = context;
                    738:        struct acpi_softc *sc = awc->aw_sc;
1.169     jruoho    739:        struct acpi_devnode *ad;
                    740:        ACPI_DEVICE_INFO *devinfo;
                    741:        ACPI_OBJECT_TYPE type;
                    742:        ACPI_STATUS rv;
                    743:
                    744:        rv = AcpiGetObjectInfo(handle, &devinfo);
1.124     dyoung    745:
1.169     jruoho    746:        if (ACPI_FAILURE(rv))
                    747:                return AE_OK;   /* Do not terminate the walk. */
1.124     dyoung    748:
1.169     jruoho    749:        type = devinfo->Type;
1.124     dyoung    750:
1.169     jruoho    751:        switch (type) {
1.124     dyoung    752:
1.169     jruoho    753:        case ACPI_TYPE_DEVICE:
                    754:                acpi_activate_device(handle, &devinfo);
1.265     jmcneill  755:                /* FALLTHROUGH */
                    756:
1.169     jruoho    757:        case ACPI_TYPE_PROCESSOR:
                    758:        case ACPI_TYPE_THERMAL:
                    759:        case ACPI_TYPE_POWER:
1.124     dyoung    760:
1.254     jruoho    761:                ad = kmem_zalloc(sizeof(*ad), KM_SLEEP);
1.25      jmcneill  762:
1.175     jruoho    763:                ad->ad_device = NULL;
1.176     jruoho    764:                ad->ad_notify = NULL;
1.180     jruoho    765:                ad->ad_pciinfo = NULL;
1.236     jruoho    766:                ad->ad_wakedev = NULL;
1.175     jruoho    767:
                    768:                ad->ad_type = type;
                    769:                ad->ad_handle = handle;
1.169     jruoho    770:                ad->ad_devinfo = devinfo;
1.157     jruoho    771:
1.176     jruoho    772:                ad->ad_root = sc->sc_dev;
                    773:                ad->ad_parent = awc->aw_parent;
                    774:
1.246     jruoho    775:                acpi_match_node_init(ad);
1.229     jruoho    776:                acpi_make_name(ad, devinfo->Name);
1.160     jruoho    777:
1.236     jruoho    778:                /*
                    779:                 * Identify wake GPEs from the _PRW. Note that
                    780:                 * AcpiUpdateAllGpes() must be called afterwards.
                    781:                 */
                    782:                if (ad->ad_devinfo->Type == ACPI_TYPE_DEVICE)
                    783:                        acpi_wakedev_init(ad);
                    784:
1.176     jruoho    785:                SIMPLEQ_INIT(&ad->ad_child_head);
                    786:                SIMPLEQ_INSERT_TAIL(&sc->ad_head, ad, ad_list);
                    787:
                    788:                if (ad->ad_parent != NULL) {
                    789:
                    790:                        SIMPLEQ_INSERT_TAIL(&ad->ad_parent->ad_child_head,
                    791:                            ad, ad_child_list);
                    792:                }
                    793:
                    794:                awc->aw_parent = ad;
1.169     jruoho    795:        }
                    796:
                    797:        return AE_OK;
                    798: }
                    799:
1.176     jruoho    800: static ACPI_STATUS
                    801: acpi_make_devnode_post(ACPI_HANDLE handle, uint32_t level,
                    802:     void *context, void **status)
                    803: {
                    804:        struct acpi_walkcontext *awc = context;
                    805:
                    806:        KASSERT(awc != NULL);
                    807:        KASSERT(awc->aw_parent != NULL);
                    808:
                    809:        if (handle == awc->aw_parent->ad_handle)
                    810:                awc->aw_parent = awc->aw_parent->ad_parent;
                    811:
                    812:        return AE_OK;
                    813: }
                    814:
1.229     jruoho    815: static void
                    816: acpi_make_name(struct acpi_devnode *ad, uint32_t name)
                    817: {
                    818:        ACPI_NAME_UNION *anu;
                    819:        int clear, i;
                    820:
                    821:        anu = (ACPI_NAME_UNION *)&name;
                    822:        ad->ad_name[4] = '\0';
                    823:
                    824:        for (i = 3, clear = 0; i >= 0; i--) {
                    825:
                    826:                if (clear == 0 && anu->Ascii[i] == '_')
                    827:                        ad->ad_name[i] = '\0';
                    828:                else {
                    829:                        ad->ad_name[i] = anu->Ascii[i];
                    830:                        clear = 1;
                    831:                }
                    832:        }
                    833:
                    834:        if (ad->ad_name[0] == '\0')
                    835:                ad->ad_name[0] = '_';
                    836: }
                    837:
1.271.2.2! martin    838: bus_dma_tag_t
        !           839: acpi_default_dma_tag(struct acpi_softc *sc, struct acpi_devnode *ad)
        !           840: {
        !           841:        return sc->sc_dmat;
        !           842: }
        !           843: __weak_alias(acpi_get_dma_tag,acpi_default_dma_tag);
        !           844:
        !           845: bus_dma_tag_t
        !           846: acpi_default_dma64_tag(struct acpi_softc *sc, struct acpi_devnode *ad)
        !           847: {
        !           848:        return sc->sc_dmat64;
        !           849: }
        !           850: __weak_alias(acpi_get_dma64_tag,acpi_default_dma64_tag);
        !           851:
        !           852: pci_chipset_tag_t
        !           853: acpi_default_pci_chipset_tag(struct acpi_softc *sc, int seg, int bbn)
        !           854: {
        !           855:        return NULL;
        !           856: }
        !           857: __weak_alias(acpi_get_pci_chipset_tag,acpi_default_pci_chipset_tag);
        !           858:
1.1       thorpej   859: /*
1.169     jruoho    860:  * Device attachment.
1.1       thorpej   861:  */
1.169     jruoho    862: static int
                    863: acpi_rescan(device_t self, const char *ifattr, const int *locators)
                    864: {
                    865:        struct acpi_softc *sc = device_private(self);
1.245     jruoho    866:        struct acpi_attach_args aa;
                    867:
                    868:        /*
                    869:         * Try to attach hpet(4) first via a specific table.
                    870:         */
                    871:        aa.aa_memt = sc->sc_memt;
                    872:
                    873:        if (ifattr_match(ifattr, "acpihpetbus") && sc->sc_hpet == NULL)
                    874:                sc->sc_hpet = config_found_ia(sc->sc_dev,
                    875:                    "acpihpetbus", &aa, NULL);
1.169     jruoho    876:
1.226     jruoho    877:        /*
                    878:         * A two-pass scan for acpinodebus.
                    879:         */
                    880:        if (ifattr_match(ifattr, "acpinodebus")) {
                    881:                acpi_rescan_early(sc);
1.169     jruoho    882:                acpi_rescan_nodes(sc);
1.226     jruoho    883:        }
1.169     jruoho    884:
1.245     jruoho    885:        /*
                    886:         * Attach APM emulation and acpiwdrt(4).
                    887:         */
1.169     jruoho    888:        if (ifattr_match(ifattr, "acpiapmbus") && sc->sc_apmbus == NULL)
                    889:                sc->sc_apmbus = config_found_ia(sc->sc_dev,
                    890:                    "acpiapmbus", NULL, NULL);
1.204     jruoho    891:
1.234     jmcneill  892:        if (ifattr_match(ifattr, "acpiwdrtbus") && sc->sc_wdrt == NULL)
                    893:                sc->sc_wdrt = config_found_ia(sc->sc_dev,
                    894:                    "acpiwdrtbus", NULL, NULL);
                    895:
1.204     jruoho    896:        return 0;
1.169     jruoho    897: }
                    898:
                    899: static void
1.226     jruoho    900: acpi_rescan_early(struct acpi_softc *sc)
                    901: {
                    902:        struct acpi_attach_args aa;
                    903:        struct acpi_devnode *ad;
                    904:
                    905:        /*
                    906:         * First scan for devices such as acpiec(4) that
                    907:         * should be always attached before anything else.
                    908:         * We want these devices to attach regardless of
                    909:         * the device status and other restrictions.
                    910:         */
                    911:        SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
                    912:
                    913:                if (ad->ad_device != NULL)
                    914:                        continue;
                    915:
                    916:                if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE)
                    917:                        continue;
                    918:
                    919:                if (acpi_match_hid(ad->ad_devinfo, acpi_early_ids) == 0)
                    920:                        continue;
                    921:
                    922:                aa.aa_node = ad;
                    923:                aa.aa_iot = sc->sc_iot;
                    924:                aa.aa_memt = sc->sc_memt;
1.271.2.2! martin    925:                if (ad->ad_pciinfo != NULL) {
        !           926:                        aa.aa_pc = ad->ad_pciinfo->ap_pc;
        !           927:                        aa.aa_pciflags = sc->sc_pciflags;
        !           928:                }
1.226     jruoho    929:                aa.aa_ic = sc->sc_ic;
1.271.2.2! martin    930:                aa.aa_dmat = ad->ad_dmat;
        !           931:                aa.aa_dmat64 = ad->ad_dmat64;
1.226     jruoho    932:
                    933:                ad->ad_device = config_found_ia(sc->sc_dev,
                    934:                    "acpinodebus", &aa, acpi_print);
                    935:        }
                    936: }
                    937:
                    938: static void
1.169     jruoho    939: acpi_rescan_nodes(struct acpi_softc *sc)
1.1       thorpej   940: {
1.245     jruoho    941:        const char * const hpet_ids[] = { "PNP0103", NULL };
1.169     jruoho    942:        struct acpi_attach_args aa;
1.1       thorpej   943:        struct acpi_devnode *ad;
1.193     jruoho    944:        ACPI_DEVICE_INFO *di;
1.1       thorpej   945:
1.176     jruoho    946:        SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
1.15      augustss  947:
1.169     jruoho    948:                if (ad->ad_device != NULL)
                    949:                        continue;
1.151     jruoho    950:
1.185     jruoho    951:                /*
                    952:                 * There is a bug in ACPICA: it defines the type
                    953:                 * of the scopes incorrectly for its own reasons.
                    954:                 */
                    955:                if (acpi_is_scope(ad) != false)
                    956:                        continue;
1.151     jruoho    957:
1.193     jruoho    958:                di = ad->ad_devinfo;
                    959:
1.270     christos  960:                /*
                    961:                 * We only attach devices which are present, enabled, and
                    962:                 * functioning properly. However, if a device is enabled,
                    963:                 * it is decoding resources and we should claim these,
                    964:                 * if possible. This requires changes to bus_space(9).
                    965:                 */
                    966:                if (di->Type == ACPI_TYPE_DEVICE &&
                    967:                    !acpi_device_present(ad->ad_handle)) {
                    968:                        continue;
                    969:                }
                    970:
1.207     jruoho    971:                if (di->Type == ACPI_TYPE_POWER)
1.169     jruoho    972:                        continue;
1.15      augustss  973:
1.240     jruoho    974:                if (di->Type == ACPI_TYPE_PROCESSOR)
1.231     jruoho    975:                        continue;
                    976:
1.227     jruoho    977:                if (acpi_match_hid(di, acpi_early_ids) != 0)
                    978:                        continue;
                    979:
                    980:                if (acpi_match_hid(di, acpi_ignored_ids) != 0)
1.169     jruoho    981:                        continue;
1.151     jruoho    982:
1.245     jruoho    983:                if (acpi_match_hid(di, hpet_ids) != 0 && sc->sc_hpet != NULL)
                    984:                        continue;
                    985:
1.185     jruoho    986:                aa.aa_node = ad;
                    987:                aa.aa_iot = sc->sc_iot;
                    988:                aa.aa_memt = sc->sc_memt;
1.271.2.2! martin    989:                if (ad->ad_pciinfo != NULL) {
        !           990:                        aa.aa_pc = ad->ad_pciinfo->ap_pc;
        !           991:                        aa.aa_pciflags = sc->sc_pciflags;
        !           992:                }
1.185     jruoho    993:                aa.aa_ic = sc->sc_ic;
1.271.2.2! martin    994:                aa.aa_dmat = ad->ad_dmat;
        !           995:                aa.aa_dmat64 = ad->ad_dmat64;
1.185     jruoho    996:
1.169     jruoho    997:                ad->ad_device = config_found_ia(sc->sc_dev,
                    998:                    "acpinodebus", &aa, acpi_print);
                    999:        }
                   1000: }
1.151     jruoho   1001:
1.169     jruoho   1002: static void
1.224     jruoho   1003: acpi_rescan_capabilities(device_t self)
1.169     jruoho   1004: {
1.224     jruoho   1005:        struct acpi_softc *sc = device_private(self);
1.169     jruoho   1006:        struct acpi_devnode *ad;
                   1007:        ACPI_HANDLE tmp;
                   1008:        ACPI_STATUS rv;
1.151     jruoho   1009:
1.176     jruoho   1010:        SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
1.151     jruoho   1011:
1.195     jruoho   1012:                if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE)
1.169     jruoho   1013:                        continue;
1.151     jruoho   1014:
1.169     jruoho   1015:                /*
                   1016:                 * Scan power resource capabilities.
1.181     jruoho   1017:                 *
                   1018:                 * If any power states are supported,
                   1019:                 * at least _PR0 and _PR3 must be present.
1.169     jruoho   1020:                 */
                   1021:                rv = AcpiGetHandle(ad->ad_handle, "_PR0", &tmp);
1.102     cube     1022:
1.181     jruoho   1023:                if (ACPI_SUCCESS(rv)) {
1.169     jruoho   1024:                        ad->ad_flags |= ACPI_DEVICE_POWER;
1.184     jruoho   1025:                        acpi_power_add(ad);
1.181     jruoho   1026:                }
1.1       thorpej  1027:
1.169     jruoho   1028:                /*
                   1029:                 * Scan wake-up capabilities.
                   1030:                 */
1.236     jruoho   1031:                if (ad->ad_wakedev != NULL) {
1.169     jruoho   1032:                        ad->ad_flags |= ACPI_DEVICE_WAKEUP;
                   1033:                        acpi_wakedev_add(ad);
                   1034:                }
1.225     jruoho   1035:
                   1036:                /*
1.232     jruoho   1037:                 * Scan docking stations.
                   1038:                 */
                   1039:                rv = AcpiGetHandle(ad->ad_handle, "_DCK", &tmp);
                   1040:
                   1041:                if (ACPI_SUCCESS(rv))
                   1042:                        ad->ad_flags |= ACPI_DEVICE_DOCK;
                   1043:
                   1044:                /*
1.225     jruoho   1045:                 * Scan devices that are ejectable.
                   1046:                 */
                   1047:                rv = AcpiGetHandle(ad->ad_handle, "_EJ0", &tmp);
                   1048:
                   1049:                if (ACPI_SUCCESS(rv))
                   1050:                        ad->ad_flags |= ACPI_DEVICE_EJECT;
1.1       thorpej  1051:        }
1.169     jruoho   1052: }
1.151     jruoho   1053:
1.64      kochi    1054: static int
1.1       thorpej  1055: acpi_print(void *aux, const char *pnp)
                   1056: {
                   1057:        struct acpi_attach_args *aa = aux;
1.233     jruoho   1058:        struct acpi_devnode *ad;
                   1059:        const char *hid, *uid;
                   1060:        ACPI_DEVICE_INFO *di;
                   1061:
                   1062:        ad = aa->aa_node;
                   1063:        di = ad->ad_devinfo;
                   1064:
                   1065:        hid = di->HardwareId.String;
                   1066:        uid = di->UniqueId.String;
                   1067:
                   1068:        if (pnp != NULL) {
                   1069:
                   1070:                if (di->Type != ACPI_TYPE_DEVICE) {
                   1071:
                   1072:                        aprint_normal("%s (ACPI Object Type '%s') at %s",
                   1073:                            ad->ad_name, AcpiUtGetTypeName(ad->ad_type), pnp);
                   1074:
                   1075:                        return UNCONF;
                   1076:                }
1.1       thorpej  1077:
1.233     jruoho   1078:                if ((di->Valid & ACPI_VALID_HID) == 0 || hid == NULL)
1.104     jmcneill 1079:                        return 0;
1.233     jruoho   1080:
                   1081:                aprint_normal("%s (%s) ", ad->ad_name, hid);
                   1082:                acpi_print_dev(hid);
                   1083:                aprint_normal("at %s", pnp);
                   1084:
                   1085:                return UNCONF;
                   1086:        }
                   1087:
                   1088:        aprint_normal(" (%s", ad->ad_name);
                   1089:
                   1090:        if ((di->Valid & ACPI_VALID_HID) != 0 && hid != NULL) {
                   1091:
                   1092:                aprint_normal(", %s", hid);
                   1093:
                   1094:                if ((di->Valid & ACPI_VALID_UID) != 0 && uid != NULL) {
                   1095:
                   1096:                        if (uid[0] == '\0')
                   1097:                                uid = "<null>";
                   1098:
                   1099:                        aprint_normal("-%s", uid);
1.22      jmcneill 1100:                }
1.4       thorpej  1101:        }
1.1       thorpej  1102:
1.233     jruoho   1103:        aprint_normal(")");
                   1104:
1.63      kochi    1105:        return UNCONF;
1.1       thorpej  1106: }
                   1107:
1.168     jruoho   1108: /*
1.175     jruoho   1109:  * Notify.
                   1110:  */
                   1111: static void
                   1112: acpi_notify_handler(ACPI_HANDLE handle, uint32_t event, void *aux)
                   1113: {
                   1114:        struct acpi_softc *sc = acpi_softc;
                   1115:        struct acpi_devnode *ad;
                   1116:
                   1117:        KASSERT(sc != NULL);
                   1118:        KASSERT(aux == NULL);
                   1119:        KASSERT(acpi_active != 0);
                   1120:
                   1121:        if (acpi_suspended != 0)
                   1122:                return;
                   1123:
                   1124:        /*
                   1125:         *  System: 0x00 - 0x7F.
                   1126:         *  Device: 0x80 - 0xFF.
                   1127:         */
                   1128:        switch (event) {
                   1129:
                   1130:        case ACPI_NOTIFY_BUS_CHECK:
                   1131:        case ACPI_NOTIFY_DEVICE_CHECK:
                   1132:        case ACPI_NOTIFY_DEVICE_WAKE:
                   1133:        case ACPI_NOTIFY_EJECT_REQUEST:
                   1134:        case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
                   1135:        case ACPI_NOTIFY_FREQUENCY_MISMATCH:
                   1136:        case ACPI_NOTIFY_BUS_MODE_MISMATCH:
                   1137:        case ACPI_NOTIFY_POWER_FAULT:
                   1138:        case ACPI_NOTIFY_CAPABILITIES_CHECK:
                   1139:        case ACPI_NOTIFY_DEVICE_PLD_CHECK:
                   1140:        case ACPI_NOTIFY_RESERVED:
                   1141:        case ACPI_NOTIFY_LOCALITY_UPDATE:
                   1142:                break;
                   1143:        }
                   1144:
                   1145:        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "notification 0x%02X for "
                   1146:                "%s (%p)\n", event, acpi_name(handle), handle));
                   1147:
                   1148:        /*
                   1149:         * We deliver notifications only to drivers
1.247     jakllsch 1150:         * that have been successfully attached and
1.175     jruoho   1151:         * that have registered a handler with us.
                   1152:         * The opaque pointer is always the device_t.
                   1153:         */
1.176     jruoho   1154:        SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
1.175     jruoho   1155:
                   1156:                if (ad->ad_device == NULL)
                   1157:                        continue;
                   1158:
                   1159:                if (ad->ad_notify == NULL)
                   1160:                        continue;
                   1161:
                   1162:                if (ad->ad_handle != handle)
                   1163:                        continue;
                   1164:
                   1165:                (*ad->ad_notify)(ad->ad_handle, event, ad->ad_device);
                   1166:
                   1167:                return;
                   1168:        }
                   1169:
                   1170:        aprint_debug_dev(sc->sc_dev, "unhandled notify 0x%02X "
                   1171:            "for %s (%p)\n", event, acpi_name(handle), handle);
                   1172: }
                   1173:
                   1174: bool
                   1175: acpi_register_notify(struct acpi_devnode *ad, ACPI_NOTIFY_HANDLER notify)
                   1176: {
                   1177:        struct acpi_softc *sc = acpi_softc;
                   1178:
                   1179:        KASSERT(sc != NULL);
                   1180:        KASSERT(acpi_active != 0);
                   1181:
                   1182:        if (acpi_suspended != 0)
                   1183:                goto fail;
                   1184:
                   1185:        if (ad == NULL || notify == NULL)
                   1186:                goto fail;
                   1187:
                   1188:        ad->ad_notify = notify;
                   1189:
                   1190:        return true;
                   1191:
                   1192: fail:
                   1193:        aprint_error_dev(sc->sc_dev, "failed to register notify "
                   1194:            "handler for %s (%p)\n", ad->ad_name, ad->ad_handle);
                   1195:
                   1196:        return false;
                   1197: }
                   1198:
                   1199: void
                   1200: acpi_deregister_notify(struct acpi_devnode *ad)
                   1201: {
                   1202:
                   1203:        ad->ad_notify = NULL;
                   1204: }
                   1205:
                   1206: /*
1.168     jruoho   1207:  * Fixed buttons.
                   1208:  */
                   1209: static void
                   1210: acpi_register_fixed_button(struct acpi_softc *sc, int event)
                   1211: {
                   1212:        struct sysmon_pswitch *smpsw;
                   1213:        ACPI_STATUS rv;
                   1214:        int type;
                   1215:
                   1216:        switch (event) {
                   1217:
                   1218:        case ACPI_EVENT_POWER_BUTTON:
                   1219:
                   1220:                if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) != 0)
                   1221:                        return;
                   1222:
                   1223:                type = PSWITCH_TYPE_POWER;
                   1224:                smpsw = &sc->sc_smpsw_power;
                   1225:                break;
                   1226:
                   1227:        case ACPI_EVENT_SLEEP_BUTTON:
                   1228:
                   1229:                if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) != 0)
                   1230:                        return;
                   1231:
                   1232:                type = PSWITCH_TYPE_SLEEP;
                   1233:                smpsw = &sc->sc_smpsw_sleep;
                   1234:                break;
                   1235:
                   1236:        default:
                   1237:                rv = AE_TYPE;
                   1238:                goto fail;
                   1239:        }
                   1240:
                   1241:        smpsw->smpsw_type = type;
                   1242:        smpsw->smpsw_name = device_xname(sc->sc_dev);
                   1243:
                   1244:        if (sysmon_pswitch_register(smpsw) != 0) {
                   1245:                rv = AE_ERROR;
                   1246:                goto fail;
                   1247:        }
                   1248:
1.250     jakllsch 1249:        AcpiClearEvent(event);
                   1250:
1.168     jruoho   1251:        rv = AcpiInstallFixedEventHandler(event,
                   1252:            acpi_fixed_button_handler, smpsw);
                   1253:
1.199     jruoho   1254:        if (ACPI_FAILURE(rv)) {
                   1255:                sysmon_pswitch_unregister(smpsw);
1.168     jruoho   1256:                goto fail;
1.199     jruoho   1257:        }
1.168     jruoho   1258:
1.271     ryoon    1259:        aprint_normal_dev(sc->sc_dev, "fixed %s button present\n",
1.271.2.1  christos 1260:            (type != PSWITCH_TYPE_SLEEP) ? "power" : "sleep");
1.168     jruoho   1261:
                   1262:        return;
1.1       thorpej  1263:
1.168     jruoho   1264: fail:
                   1265:        aprint_error_dev(sc->sc_dev, "failed to register "
1.249     jakllsch 1266:            "fixed event %d: %s\n", event, AcpiFormatException(rv));
1.168     jruoho   1267: }
1.1       thorpej  1268:
1.64      kochi    1269: static void
1.169     jruoho   1270: acpi_deregister_fixed_button(struct acpi_softc *sc, int event)
1.69      kochi    1271: {
1.169     jruoho   1272:        struct sysmon_pswitch *smpsw;
1.69      kochi    1273:        ACPI_STATUS rv;
                   1274:
1.169     jruoho   1275:        switch (event) {
1.144     jruoho   1276:
1.169     jruoho   1277:        case ACPI_EVENT_POWER_BUTTON:
                   1278:                smpsw = &sc->sc_smpsw_power;
1.144     jruoho   1279:
1.169     jruoho   1280:                if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) != 0) {
                   1281:                        KASSERT(smpsw->smpsw_type != PSWITCH_TYPE_POWER);
                   1282:                        return;
                   1283:                }
1.144     jruoho   1284:
                   1285:                break;
                   1286:
1.169     jruoho   1287:        case ACPI_EVENT_SLEEP_BUTTON:
                   1288:                smpsw = &sc->sc_smpsw_sleep;
1.144     jruoho   1289:
1.169     jruoho   1290:                if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) != 0) {
                   1291:                        KASSERT(smpsw->smpsw_type != PSWITCH_TYPE_SLEEP);
                   1292:                        return;
                   1293:                }
1.144     jruoho   1294:
                   1295:                break;
1.69      kochi    1296:
1.144     jruoho   1297:        default:
1.169     jruoho   1298:                rv = AE_TYPE;
                   1299:                goto fail;
1.144     jruoho   1300:        }
1.69      kochi    1301:
1.169     jruoho   1302:        rv = AcpiRemoveFixedEventHandler(event, acpi_fixed_button_handler);
                   1303:
                   1304:        if (ACPI_SUCCESS(rv)) {
                   1305:                sysmon_pswitch_unregister(smpsw);
                   1306:                return;
                   1307:        }
1.69      kochi    1308:
1.169     jruoho   1309: fail:
                   1310:        aprint_error_dev(sc->sc_dev, "failed to deregister "
                   1311:            "fixed event: %s\n", AcpiFormatException(rv));
1.69      kochi    1312: }
                   1313:
1.169     jruoho   1314: static uint32_t
                   1315: acpi_fixed_button_handler(void *context)
1.118     dyoung   1316: {
1.169     jruoho   1317:        static const int handler = OSL_NOTIFY_HANDLER;
                   1318:        struct sysmon_pswitch *smpsw = context;
                   1319:
                   1320:        (void)AcpiOsExecute(handler, acpi_fixed_button_pressed, smpsw);
                   1321:
                   1322:        return ACPI_INTERRUPT_HANDLED;
1.118     dyoung   1323: }
                   1324:
1.169     jruoho   1325: static void
                   1326: acpi_fixed_button_pressed(void *context)
1.118     dyoung   1327: {
1.169     jruoho   1328:        struct sysmon_pswitch *smpsw = context;
1.118     dyoung   1329:
1.199     jruoho   1330:        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s fixed button pressed\n",
                   1331:                (smpsw->smpsw_type != ACPI_EVENT_SLEEP_BUTTON) ?
                   1332:                "power" : "sleep"));
1.10      tshiozak 1333:
1.169     jruoho   1334:        sysmon_pswitch_event(smpsw, PSWITCH_EVENT_PRESSED);
                   1335: }
1.10      tshiozak 1336:
1.166     jruoho   1337: /*
1.169     jruoho   1338:  * Sleep.
1.166     jruoho   1339:  */
                   1340: static void
                   1341: acpi_sleep_init(struct acpi_softc *sc)
1.10      tshiozak 1342: {
1.166     jruoho   1343:        uint8_t a, b, i;
                   1344:        ACPI_STATUS rv;
1.10      tshiozak 1345:
1.166     jruoho   1346:        CTASSERT(ACPI_STATE_S0 == 0 && ACPI_STATE_S1 == 1);
                   1347:        CTASSERT(ACPI_STATE_S2 == 2 && ACPI_STATE_S3 == 3);
                   1348:        CTASSERT(ACPI_STATE_S4 == 4 && ACPI_STATE_S5 == 5);
                   1349:
1.169     jruoho   1350:        /*
                   1351:         * Evaluate supported sleep states.
                   1352:         */
1.166     jruoho   1353:        for (i = ACPI_STATE_S0; i <= ACPI_STATE_S5; i++) {
                   1354:
                   1355:                rv = AcpiGetSleepTypeData(i, &a, &b);
                   1356:
                   1357:                if (ACPI_SUCCESS(rv))
                   1358:                        sc->sc_sleepstates |= __BIT(i);
                   1359:        }
1.10      tshiozak 1360: }
                   1361:
1.230     jruoho   1362: /*
                   1363:  * Must be called with interrupts enabled.
                   1364:  */
1.194     jruoho   1365: void
1.222     jruoho   1366: acpi_enter_sleep_state(int state)
1.10      tshiozak 1367: {
1.222     jruoho   1368:        struct acpi_softc *sc = acpi_softc;
1.194     jruoho   1369:        ACPI_STATUS rv;
1.10      tshiozak 1370:
1.222     jruoho   1371:        if (acpi_softc == NULL)
                   1372:                return;
                   1373:
1.166     jruoho   1374:        if (state == sc->sc_sleepstate)
1.194     jruoho   1375:                return;
1.92      christos 1376:
1.222     jruoho   1377:        if (state < ACPI_STATE_S0 || state > ACPI_STATE_S5)
                   1378:                return;
                   1379:
1.166     jruoho   1380:        aprint_normal_dev(sc->sc_dev, "entering state S%d\n", state);
1.92      christos 1381:
1.10      tshiozak 1382:        switch (state) {
1.166     jruoho   1383:
1.10      tshiozak 1384:        case ACPI_STATE_S0:
1.194     jruoho   1385:                sc->sc_sleepstate = ACPI_STATE_S0;
                   1386:                return;
1.166     jruoho   1387:
1.10      tshiozak 1388:        case ACPI_STATE_S1:
                   1389:        case ACPI_STATE_S2:
                   1390:        case ACPI_STATE_S3:
                   1391:        case ACPI_STATE_S4:
1.166     jruoho   1392:
                   1393:                if ((sc->sc_sleepstates & __BIT(state)) == 0) {
                   1394:                        aprint_error_dev(sc->sc_dev, "sleep state "
                   1395:                            "S%d is not available\n", state);
1.194     jruoho   1396:                        return;
1.10      tshiozak 1397:                }
1.104     jmcneill 1398:
1.188     jruoho   1399:                /*
1.190     jruoho   1400:                 * Evaluate the _TTS method. This should be done before
                   1401:                 * pmf_system_suspend(9) and the evaluation of _PTS.
                   1402:                 * We should also re-evaluate this once we return to
                   1403:                 * S0 or if we abort the sleep state transition in the
                   1404:                 * middle (see ACPI 3.0, section 7.3.6). In reality,
                   1405:                 * however, the _TTS method is seldom seen in the field.
1.189     jruoho   1406:                 */
                   1407:                rv = acpi_eval_set_integer(NULL, "\\_TTS", state);
                   1408:
                   1409:                if (ACPI_SUCCESS(rv))
                   1410:                        aprint_debug_dev(sc->sc_dev, "evaluated _TTS\n");
                   1411:
1.190     jruoho   1412:                if (state != ACPI_STATE_S1 &&
                   1413:                    pmf_system_suspend(PMF_Q_NONE) != true) {
                   1414:                        aprint_error_dev(sc->sc_dev, "aborting suspend\n");
                   1415:                        break;
                   1416:                }
                   1417:
1.189     jruoho   1418:                /*
1.188     jruoho   1419:                 * This will evaluate the  _PTS and _SST methods,
                   1420:                 * but unlike the documentation claims, not _GTS,
                   1421:                 * which is evaluated in AcpiEnterSleepState().
                   1422:                 * This must be called with interrupts enabled.
                   1423:                 */
1.166     jruoho   1424:                rv = AcpiEnterSleepStatePrep(state);
                   1425:
                   1426:                if (ACPI_FAILURE(rv)) {
                   1427:                        aprint_error_dev(sc->sc_dev, "failed to prepare "
                   1428:                            "S%d: %s\n", state, AcpiFormatException(rv));
1.10      tshiozak 1429:                        break;
                   1430:                }
1.104     jmcneill 1431:
1.203     jruoho   1432:                /*
                   1433:                 * After the _PTS method has been evaluated, we can
                   1434:                 * enable wake and evaluate _PSW (ACPI 4.0, p. 284).
                   1435:                 */
                   1436:                acpi_wakedev_commit(sc, state);
                   1437:
1.166     jruoho   1438:                sc->sc_sleepstate = state;
                   1439:
1.92      christos 1440:                if (state == ACPI_STATE_S1) {
1.166     jruoho   1441:
1.241     jruoho   1442:                        /*
1.242     jruoho   1443:                         * Before the transition to S1, CPU caches
                   1444:                         * must be flushed (see ACPI 4.0, 7.3.4.2).
                   1445:                         *
                   1446:                         * Note that interrupts must be off before
                   1447:                         * calling AcpiEnterSleepState(). Conversely,
                   1448:                         * AcpiLeaveSleepState() should always be
                   1449:                         * called with interrupts enabled.
1.241     jruoho   1450:                         */
1.12      kanaoka  1451:                        acpi_md_OsDisableInterrupt();
1.242     jruoho   1452:
                   1453:                        ACPI_FLUSH_CPU_CACHE();
1.166     jruoho   1454:                        rv = AcpiEnterSleepState(state);
                   1455:
                   1456:                        if (ACPI_FAILURE(rv))
                   1457:                                aprint_error_dev(sc->sc_dev, "failed to "
                   1458:                                    "enter S1: %s\n", AcpiFormatException(rv));
                   1459:
1.251     jmcneill 1460:                        /*
                   1461:                         * Clear fixed events and disable all GPEs before
                   1462:                         * interrupts are enabled.
                   1463:                         */
                   1464:                        AcpiClearEvent(ACPI_EVENT_PMTIMER);
                   1465:                        AcpiClearEvent(ACPI_EVENT_GLOBAL);
                   1466:                        AcpiClearEvent(ACPI_EVENT_POWER_BUTTON);
                   1467:                        AcpiClearEvent(ACPI_EVENT_SLEEP_BUTTON);
                   1468:                        AcpiClearEvent(ACPI_EVENT_RTC);
1.271.2.1  christos 1469: #if (!ACPI_REDUCED_HARDWARE)
1.251     jmcneill 1470:                        AcpiHwDisableAllGpes();
1.271.2.1  christos 1471: #endif
1.251     jmcneill 1472:
1.241     jruoho   1473:                        acpi_md_OsEnableInterrupt();
                   1474:                        rv = AcpiLeaveSleepState(state);
1.166     jruoho   1475:
1.10      tshiozak 1476:                } else {
1.166     jruoho   1477:
1.256     christos 1478:                        (void)acpi_md_sleep(state);
1.166     jruoho   1479:
1.104     jmcneill 1480:                        if (state == ACPI_STATE_S4)
1.10      tshiozak 1481:                                AcpiEnable();
1.166     jruoho   1482:
1.235     jruoho   1483:                        (void)pmf_system_bus_resume(PMF_Q_NONE);
1.166     jruoho   1484:                        (void)AcpiLeaveSleepState(state);
1.260     christos 1485:                        (void)AcpiSetFirmwareWakingVector(0, 0);
1.235     jruoho   1486:                        (void)pmf_system_resume(PMF_Q_NONE);
1.10      tshiozak 1487:                }
1.104     jmcneill 1488:
1.241     jruoho   1489:                /*
                   1490:                 * No wake GPEs should be enabled at runtime.
                   1491:                 */
1.237     jruoho   1492:                acpi_wakedev_commit(sc, ACPI_STATE_S0);
1.10      tshiozak 1493:                break;
1.189     jruoho   1494:
1.10      tshiozak 1495:        case ACPI_STATE_S5:
1.166     jruoho   1496:
1.190     jruoho   1497:                (void)acpi_eval_set_integer(NULL, "\\_TTS", ACPI_STATE_S5);
1.189     jruoho   1498:
1.166     jruoho   1499:                rv = AcpiEnterSleepStatePrep(ACPI_STATE_S5);
                   1500:
                   1501:                if (ACPI_FAILURE(rv)) {
                   1502:                        aprint_error_dev(sc->sc_dev, "failed to prepare "
                   1503:                            "S%d: %s\n", state, AcpiFormatException(rv));
1.42      kochi    1504:                        break;
                   1505:                }
1.166     jruoho   1506:
1.230     jruoho   1507:                (void)AcpiDisableAllGpes();
                   1508:
1.104     jmcneill 1509:                DELAY(1000000);
1.166     jruoho   1510:
                   1511:                sc->sc_sleepstate = state;
1.12      kanaoka  1512:                acpi_md_OsDisableInterrupt();
1.166     jruoho   1513:
                   1514:                (void)AcpiEnterSleepState(ACPI_STATE_S5);
                   1515:
                   1516:                aprint_error_dev(sc->sc_dev, "WARNING: powerdown failed!\n");
1.189     jruoho   1517:
1.10      tshiozak 1518:                break;
                   1519:        }
                   1520:
1.166     jruoho   1521:        sc->sc_sleepstate = ACPI_STATE_S0;
                   1522:
1.189     jruoho   1523:        (void)acpi_eval_set_integer(NULL, "\\_TTS", ACPI_STATE_S0);
1.1       thorpej  1524: }
1.13      augustss 1525:
1.159     jruoho   1526: /*
1.169     jruoho   1527:  * Sysctl.
1.159     jruoho   1528:  */
1.79      cube     1529: SYSCTL_SETUP(sysctl_acpi_setup, "sysctl hw.acpi subtree setup")
                   1530: {
1.253     jruoho   1531:        const struct sysctlnode *rnode, *snode;
1.165     jruoho   1532:        int err;
                   1533:
                   1534:        err = sysctl_createv(clog, 0, NULL, &rnode,
                   1535:            CTLFLAG_PERMANENT, CTLTYPE_NODE,
                   1536:            "acpi", SYSCTL_DESCR("ACPI subsystem parameters"),
1.79      cube     1537:            NULL, 0, NULL, 0,
1.258     pooka    1538:            CTL_HW, CTL_CREATE, CTL_EOL);
1.165     jruoho   1539:
                   1540:        if (err != 0)
1.79      cube     1541:                return;
                   1542:
1.165     jruoho   1543:        (void)sysctl_createv(NULL, 0, &rnode, NULL,
                   1544:            CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
                   1545:            "root", SYSCTL_DESCR("ACPI root pointer"),
1.109     jmcneill 1546:            NULL, 0, &acpi_root_pointer, sizeof(acpi_root_pointer),
1.165     jruoho   1547:            CTL_CREATE, CTL_EOL);
                   1548:
1.223     jruoho   1549:        err = sysctl_createv(clog, 0, &rnode, &snode,
                   1550:            CTLFLAG_PERMANENT, CTLTYPE_NODE,
                   1551:            "sleep", SYSCTL_DESCR("ACPI sleep"),
                   1552:            NULL, 0, NULL, 0,
                   1553:            CTL_CREATE, CTL_EOL);
                   1554:
                   1555:        if (err != 0)
                   1556:                return;
                   1557:
                   1558:        (void)sysctl_createv(NULL, 0, &snode, NULL,
                   1559:            CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
                   1560:            "state", SYSCTL_DESCR("System sleep state"),
                   1561:            sysctl_hw_acpi_sleepstate, 0, NULL, 0,
                   1562:            CTL_CREATE, CTL_EOL);
                   1563:
                   1564:        (void)sysctl_createv(NULL, 0, &snode, NULL,
1.165     jruoho   1565:            CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_STRING,
1.223     jruoho   1566:            "states", SYSCTL_DESCR("Supported sleep states"),
1.166     jruoho   1567:            sysctl_hw_acpi_sleepstates, 0, NULL, 0,
1.165     jruoho   1568:            CTL_CREATE, CTL_EOL);
                   1569:
                   1570:        err = sysctl_createv(clog, 0, &rnode, &rnode,
                   1571:            CTLFLAG_PERMANENT, CTLTYPE_NODE,
                   1572:            "stat", SYSCTL_DESCR("ACPI statistics"),
                   1573:            NULL, 0, NULL, 0,
                   1574:            CTL_CREATE, CTL_EOL);
                   1575:
                   1576:        if (err != 0)
1.86      jmcneill 1577:                return;
1.165     jruoho   1578:
                   1579:        (void)sysctl_createv(clog, 0, &rnode, NULL,
                   1580:            CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
                   1581:            "gpe", SYSCTL_DESCR("Number of dispatched GPEs"),
                   1582:            NULL, 0, &AcpiGpeCount, sizeof(AcpiGpeCount),
                   1583:            CTL_CREATE, CTL_EOL);
                   1584:
                   1585:        (void)sysctl_createv(clog, 0, &rnode, NULL,
                   1586:            CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
                   1587:            "sci", SYSCTL_DESCR("Number of SCI interrupts"),
                   1588:            NULL, 0, &AcpiSciCount, sizeof(AcpiSciCount),
                   1589:            CTL_CREATE, CTL_EOL);
                   1590:
                   1591:        (void)sysctl_createv(clog, 0, &rnode, NULL,
                   1592:            CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
                   1593:            "fixed", SYSCTL_DESCR("Number of fixed events"),
                   1594:            sysctl_hw_acpi_fixedstats, 0, NULL, 0,
                   1595:            CTL_CREATE, CTL_EOL);
                   1596:
                   1597:        (void)sysctl_createv(clog, 0, &rnode, NULL,
                   1598:            CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
                   1599:            "method", SYSCTL_DESCR("Number of methods executed"),
                   1600:            NULL, 0, &AcpiMethodCount, sizeof(AcpiMethodCount),
                   1601:            CTL_CREATE, CTL_EOL);
                   1602:
                   1603:        CTASSERT(sizeof(AcpiGpeCount) == sizeof(uint64_t));
                   1604:        CTASSERT(sizeof(AcpiSciCount) == sizeof(uint64_t));
                   1605: }
                   1606:
                   1607: static int
                   1608: sysctl_hw_acpi_fixedstats(SYSCTLFN_ARGS)
                   1609: {
                   1610:        struct sysctlnode node;
                   1611:        uint64_t t;
                   1612:        int err, i;
                   1613:
                   1614:        for (i = t = 0; i < __arraycount(AcpiFixedEventCount); i++)
                   1615:                t += AcpiFixedEventCount[i];
                   1616:
                   1617:        node = *rnode;
                   1618:        node.sysctl_data = &t;
                   1619:
                   1620:        err = sysctl_lookup(SYSCTLFN_CALL(&node));
                   1621:
                   1622:        if (err || newp == NULL)
                   1623:                return err;
                   1624:
                   1625:        return 0;
1.86      jmcneill 1626: }
                   1627:
                   1628: static int
                   1629: sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS)
                   1630: {
1.166     jruoho   1631:        struct acpi_softc *sc = acpi_softc;
1.86      jmcneill 1632:        struct sysctlnode node;
1.165     jruoho   1633:        int err, t;
1.86      jmcneill 1634:
1.166     jruoho   1635:        if (acpi_softc == NULL)
                   1636:                return ENOSYS;
                   1637:
1.86      jmcneill 1638:        node = *rnode;
1.166     jruoho   1639:        t = sc->sc_sleepstate;
1.86      jmcneill 1640:        node.sysctl_data = &t;
1.165     jruoho   1641:
                   1642:        err = sysctl_lookup(SYSCTLFN_CALL(&node));
                   1643:
                   1644:        if (err || newp == NULL)
                   1645:                return err;
1.86      jmcneill 1646:
1.166     jruoho   1647:        if (t < ACPI_STATE_S0 || t > ACPI_STATE_S5)
                   1648:                return EINVAL;
                   1649:
1.222     jruoho   1650:        acpi_enter_sleep_state(t);
1.166     jruoho   1651:
                   1652:        return 0;
                   1653: }
                   1654:
                   1655: static int
                   1656: sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS)
                   1657: {
                   1658:        struct acpi_softc *sc = acpi_softc;
                   1659:        struct sysctlnode node;
                   1660:        char t[3 * 6 + 1];
                   1661:        int err;
                   1662:
1.92      christos 1663:        if (acpi_softc == NULL)
                   1664:                return ENOSYS;
1.86      jmcneill 1665:
1.166     jruoho   1666:        (void)memset(t, '\0', sizeof(t));
                   1667:
                   1668:        (void)snprintf(t, sizeof(t), "%s%s%s%s%s%s",
                   1669:            ((sc->sc_sleepstates & __BIT(0)) != 0) ? "S0 " : "",
                   1670:            ((sc->sc_sleepstates & __BIT(1)) != 0) ? "S1 " : "",
                   1671:            ((sc->sc_sleepstates & __BIT(2)) != 0) ? "S2 " : "",
                   1672:            ((sc->sc_sleepstates & __BIT(3)) != 0) ? "S3 " : "",
                   1673:            ((sc->sc_sleepstates & __BIT(4)) != 0) ? "S4 " : "",
                   1674:            ((sc->sc_sleepstates & __BIT(5)) != 0) ? "S5 " : "");
                   1675:
                   1676:        node = *rnode;
                   1677:        node.sysctl_data = &t;
                   1678:
                   1679:        err = sysctl_lookup(SYSCTLFN_CALL(&node));
1.165     jruoho   1680:
1.166     jruoho   1681:        if (err || newp == NULL)
                   1682:                return err;
1.86      jmcneill 1683:
                   1684:        return 0;
1.79      cube     1685: }
1.108     jmcneill 1686:
1.169     jruoho   1687: /*
1.212     jruoho   1688:  * Tables.
1.169     jruoho   1689:  */
                   1690: ACPI_PHYSICAL_ADDRESS
                   1691: acpi_OsGetRootPointer(void)
                   1692: {
                   1693:        ACPI_PHYSICAL_ADDRESS PhysicalAddress;
                   1694:
                   1695:        /*
1.172     jruoho   1696:         * We let MD code handle this since there are multiple ways to do it:
1.169     jruoho   1697:         *
1.172     jruoho   1698:         *      IA-32: Use AcpiFindRootPointer() to locate the RSDP.
1.169     jruoho   1699:         *
1.172     jruoho   1700:         *      IA-64: Use the EFI.
1.169     jruoho   1701:         */
                   1702:        PhysicalAddress = acpi_md_OsGetRootPointer();
                   1703:
                   1704:        if (acpi_root_pointer == 0)
                   1705:                acpi_root_pointer = PhysicalAddress;
                   1706:
                   1707:        return PhysicalAddress;
                   1708: }
                   1709:
1.108     jmcneill 1710: static ACPI_TABLE_HEADER *
                   1711: acpi_map_rsdt(void)
                   1712: {
                   1713:        ACPI_PHYSICAL_ADDRESS paddr;
                   1714:        ACPI_TABLE_RSDP *rsdp;
                   1715:
                   1716:        paddr = AcpiOsGetRootPointer();
1.172     jruoho   1717:
                   1718:        if (paddr == 0)
1.108     jmcneill 1719:                return NULL;
1.172     jruoho   1720:
1.108     jmcneill 1721:        rsdp = AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_RSDP));
1.172     jruoho   1722:
                   1723:        if (rsdp == NULL)
1.108     jmcneill 1724:                return NULL;
1.172     jruoho   1725:
1.108     jmcneill 1726:        if (rsdp->Revision > 1 && rsdp->XsdtPhysicalAddress)
1.172     jruoho   1727:                paddr = rsdp->XsdtPhysicalAddress;
1.108     jmcneill 1728:        else
1.172     jruoho   1729:                paddr = rsdp->RsdtPhysicalAddress;
                   1730:
1.108     jmcneill 1731:        AcpiOsUnmapMemory(rsdp, sizeof(ACPI_TABLE_RSDP));
                   1732:
                   1733:        return AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_HEADER));
                   1734: }
                   1735:
1.238     jruoho   1736: /*
                   1737:  * XXX: Refactor to be a generic function that unmaps tables.
                   1738:  */
1.108     jmcneill 1739: static void
                   1740: acpi_unmap_rsdt(ACPI_TABLE_HEADER *rsdt)
                   1741: {
1.172     jruoho   1742:
1.108     jmcneill 1743:        if (rsdt == NULL)
                   1744:                return;
                   1745:
                   1746:        AcpiOsUnmapMemory(rsdt, sizeof(ACPI_TABLE_HEADER));
                   1747: }
1.211     jruoho   1748:
                   1749: /*
1.212     jruoho   1750:  * XXX: Refactor to be a generic function that maps tables.
                   1751:  */
                   1752: ACPI_STATUS
                   1753: acpi_madt_map(void)
                   1754: {
                   1755:        ACPI_STATUS  rv;
                   1756:
                   1757:        if (madt_header != NULL)
                   1758:                return AE_ALREADY_EXISTS;
                   1759:
                   1760:        rv = AcpiGetTable(ACPI_SIG_MADT, 1, &madt_header);
                   1761:
                   1762:        if (ACPI_FAILURE(rv))
                   1763:                return rv;
                   1764:
                   1765:        return AE_OK;
                   1766: }
                   1767:
                   1768: void
                   1769: acpi_madt_unmap(void)
                   1770: {
                   1771:        madt_header = NULL;
                   1772: }
                   1773:
1.271.2.1  christos 1774: ACPI_STATUS
                   1775: acpi_gtdt_map(void)
                   1776: {
                   1777:        ACPI_STATUS  rv;
                   1778:
                   1779:        if (gtdt_header != NULL)
                   1780:                return AE_ALREADY_EXISTS;
                   1781:
                   1782:        rv = AcpiGetTable(ACPI_SIG_GTDT, 1, &gtdt_header);
                   1783:
                   1784:        if (ACPI_FAILURE(rv))
                   1785:                return rv;
                   1786:
                   1787:        return AE_OK;
                   1788: }
                   1789:
                   1790: void
                   1791: acpi_gtdt_unmap(void)
                   1792: {
                   1793:        gtdt_header = NULL;
                   1794: }
                   1795:
1.212     jruoho   1796: /*
                   1797:  * XXX: Refactor to be a generic function that walks tables.
                   1798:  */
                   1799: void
                   1800: acpi_madt_walk(ACPI_STATUS (*func)(ACPI_SUBTABLE_HEADER *, void *), void *aux)
                   1801: {
                   1802:        ACPI_SUBTABLE_HEADER *hdrp;
                   1803:        char *madtend, *where;
                   1804:
                   1805:        madtend = (char *)madt_header + madt_header->Length;
                   1806:        where = (char *)madt_header + sizeof (ACPI_TABLE_MADT);
                   1807:
                   1808:        while (where < madtend) {
                   1809:
                   1810:                hdrp = (ACPI_SUBTABLE_HEADER *)where;
                   1811:
                   1812:                if (ACPI_FAILURE(func(hdrp, aux)))
                   1813:                        break;
                   1814:
                   1815:                where += hdrp->Length;
                   1816:        }
                   1817: }
                   1818:
1.271.2.1  christos 1819: void
                   1820: acpi_gtdt_walk(ACPI_STATUS (*func)(ACPI_GTDT_HEADER *, void *), void *aux)
                   1821: {
                   1822:        ACPI_GTDT_HEADER *hdrp;
                   1823:        char *gtdtend, *where;
                   1824:
                   1825:        gtdtend = (char *)gtdt_header + gtdt_header->Length;
                   1826:        where = (char *)gtdt_header + sizeof (ACPI_TABLE_GTDT);
                   1827:
                   1828:        while (where < gtdtend) {
                   1829:
                   1830:                hdrp = (ACPI_GTDT_HEADER *)where;
                   1831:
                   1832:                if (ACPI_FAILURE(func(hdrp, aux)))
                   1833:                        break;
                   1834:
                   1835:                where += hdrp->Length;
                   1836:        }
                   1837: }
                   1838:
1.212     jruoho   1839: /*
                   1840:  * Miscellaneous.
                   1841:  */
                   1842: static bool
                   1843: acpi_is_scope(struct acpi_devnode *ad)
                   1844: {
                   1845:        int i;
                   1846:
                   1847:        /*
                   1848:         * Return true if the node is a root scope.
                   1849:         */
                   1850:        if (ad->ad_parent == NULL)
                   1851:                return false;
                   1852:
                   1853:        if (ad->ad_parent->ad_handle != ACPI_ROOT_OBJECT)
                   1854:                return false;
                   1855:
                   1856:        for (i = 0; i < __arraycount(acpi_scopes); i++) {
                   1857:
                   1858:                if (acpi_scopes[i] == NULL)
                   1859:                        continue;
                   1860:
                   1861:                if (ad->ad_handle == acpi_scopes[i])
                   1862:                        return true;
                   1863:        }
                   1864:
                   1865:        return false;
                   1866: }
                   1867:
1.270     christos 1868: bool
                   1869: acpi_device_present(ACPI_HANDLE handle)
                   1870: {
                   1871:        ACPI_STATUS rv;
                   1872:        ACPI_INTEGER sta;
                   1873:
                   1874:        rv = acpi_eval_integer(handle, "_STA", &sta);
                   1875:
                   1876:        if (ACPI_FAILURE(rv)) {
                   1877:                /* No _STA method -> must be there */
                   1878:                return rv == AE_NOT_FOUND;
                   1879:        }
                   1880:
                   1881:        return (sta & ACPI_STA_OK) == ACPI_STA_OK;
                   1882: }
                   1883:
1.212     jruoho   1884: /*
1.211     jruoho   1885:  * ACPIVERBOSE.
                   1886:  */
                   1887: void
                   1888: acpi_load_verbose(void)
                   1889: {
                   1890:
1.216     pgoyette 1891:        if (acpi_verbose_loaded == 0)
1.211     jruoho   1892:                module_autoload("acpiverbose", MODULE_CLASS_MISC);
                   1893: }
                   1894:
                   1895: void
                   1896: acpi_print_verbose_stub(struct acpi_softc *sc)
                   1897: {
                   1898:
                   1899:        acpi_load_verbose();
                   1900:
                   1901:        if (acpi_verbose_loaded != 0)
                   1902:                acpi_print_verbose(sc);
                   1903: }
                   1904:
                   1905: void
                   1906: acpi_print_dev_stub(const char *pnpstr)
                   1907: {
                   1908:
                   1909:        acpi_load_verbose();
                   1910:
                   1911:        if (acpi_verbose_loaded != 0)
                   1912:                acpi_print_dev(pnpstr);
                   1913: }
1.228     jruoho   1914:
1.239     jruoho   1915: MALLOC_DECLARE(M_ACPI); /* XXX: ACPI_ACTIVATE_DEV should use kmem(9). */
                   1916:
1.228     jruoho   1917: /*
                   1918:  * ACPI_ACTIVATE_DEV.
                   1919:  */
                   1920: static void
                   1921: acpi_activate_device(ACPI_HANDLE handle, ACPI_DEVICE_INFO **di)
                   1922: {
                   1923:
                   1924: #ifndef ACPI_ACTIVATE_DEV
                   1925:        return;
                   1926: }
                   1927: #else
1.269     christos 1928:        static const int valid = ACPI_VALID_HID;
1.228     jruoho   1929:        ACPI_DEVICE_INFO *newdi;
                   1930:        ACPI_STATUS rv;
                   1931:
1.270     christos 1932:
1.228     jruoho   1933:        /*
                   1934:         * If the device is valid and present,
                   1935:         * but not enabled, try to activate it.
                   1936:         */
                   1937:        if (((*di)->Valid & valid) != valid)
                   1938:                return;
                   1939:
1.270     christos 1940:        if (!acpi_device_present(handle))
                   1941:                return;
                   1942:
1.228     jruoho   1943:        rv = acpi_allocate_resources(handle);
                   1944:
                   1945:        if (ACPI_FAILURE(rv))
                   1946:                goto fail;
                   1947:
                   1948:        rv = AcpiGetObjectInfo(handle, &newdi);
                   1949:
                   1950:        if (ACPI_FAILURE(rv))
                   1951:                goto fail;
                   1952:
                   1953:        ACPI_FREE(*di);
                   1954:        *di = newdi;
                   1955:
                   1956:        aprint_verbose_dev(acpi_softc->sc_dev,
1.269     christos 1957:            "%s activated\n", (*di)->HardwareId.String);
1.228     jruoho   1958:
                   1959:        return;
                   1960:
                   1961: fail:
                   1962:        aprint_error_dev(acpi_softc->sc_dev, "failed to "
                   1963:            "activate %s\n", (*di)->HardwareId.String);
                   1964: }
                   1965:
                   1966: /*
                   1967:  * XXX: This very incomplete.
                   1968:  */
                   1969: ACPI_STATUS
                   1970: acpi_allocate_resources(ACPI_HANDLE handle)
                   1971: {
                   1972:        ACPI_BUFFER bufp, bufc, bufn;
                   1973:        ACPI_RESOURCE *resp, *resc, *resn;
                   1974:        ACPI_RESOURCE_IRQ *irq;
1.257     christos 1975: #if 0
1.228     jruoho   1976:        ACPI_RESOURCE_EXTENDED_IRQ *xirq;
1.257     christos 1977: #endif
1.228     jruoho   1978:        ACPI_STATUS rv;
                   1979:        uint delta;
                   1980:
                   1981:        rv = acpi_get(handle, &bufp, AcpiGetPossibleResources);
                   1982:        if (ACPI_FAILURE(rv))
                   1983:                goto out;
                   1984:        rv = acpi_get(handle, &bufc, AcpiGetCurrentResources);
                   1985:        if (ACPI_FAILURE(rv)) {
                   1986:                goto out1;
                   1987:        }
                   1988:
                   1989:        bufn.Length = 1000;
                   1990:        bufn.Pointer = resn = malloc(bufn.Length, M_ACPI, M_WAITOK);
                   1991:        resp = bufp.Pointer;
                   1992:        resc = bufc.Pointer;
                   1993:        while (resc->Type != ACPI_RESOURCE_TYPE_END_TAG &&
                   1994:               resp->Type != ACPI_RESOURCE_TYPE_END_TAG) {
                   1995:                while (resc->Type != resp->Type && resp->Type != ACPI_RESOURCE_TYPE_END_TAG)
                   1996:                        resp = ACPI_NEXT_RESOURCE(resp);
                   1997:                if (resp->Type == ACPI_RESOURCE_TYPE_END_TAG)
                   1998:                        break;
                   1999:                /* Found identical Id */
                   2000:                resn->Type = resc->Type;
                   2001:                switch (resc->Type) {
                   2002:                case ACPI_RESOURCE_TYPE_IRQ:
                   2003:                        memcpy(&resn->Data, &resp->Data,
                   2004:                               sizeof(ACPI_RESOURCE_IRQ));
                   2005:                        irq = (ACPI_RESOURCE_IRQ *)&resn->Data;
                   2006:                        irq->Interrupts[0] =
                   2007:                            ((ACPI_RESOURCE_IRQ *)&resp->Data)->
                   2008:                                Interrupts[irq->InterruptCount-1];
                   2009:                        irq->InterruptCount = 1;
                   2010:                        resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_IRQ);
                   2011:                        break;
                   2012:                case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
                   2013:                        memcpy(&resn->Data, &resp->Data,
                   2014:                               sizeof(ACPI_RESOURCE_EXTENDED_IRQ));
1.257     christos 2015: #if 0
1.228     jruoho   2016:                        xirq = (ACPI_RESOURCE_EXTENDED_IRQ *)&resn->Data;
                   2017:                        /*
                   2018:                         * XXX: Not duplicating the interrupt logic above
                   2019:                         *      because its not clear what it accomplishes.
                   2020:                         */
                   2021:                        xirq->Interrupts[0] =
                   2022:                            ((ACPI_RESOURCE_EXT_IRQ *)&resp->Data)->
                   2023:                            Interrupts[irq->NumberOfInterrupts-1];
                   2024:                        xirq->NumberOfInterrupts = 1;
                   2025: #endif
                   2026:                        resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_EXTENDED_IRQ);
                   2027:                        break;
                   2028:                case ACPI_RESOURCE_TYPE_IO:
                   2029:                        memcpy(&resn->Data, &resp->Data,
                   2030:                               sizeof(ACPI_RESOURCE_IO));
                   2031:                        resn->Length = resp->Length;
                   2032:                        break;
                   2033:                default:
                   2034:                        aprint_error_dev(acpi_softc->sc_dev,
                   2035:                            "%s: invalid type %u\n", __func__, resc->Type);
                   2036:                        rv = AE_BAD_DATA;
                   2037:                        goto out2;
                   2038:                }
                   2039:                resc = ACPI_NEXT_RESOURCE(resc);
                   2040:                resn = ACPI_NEXT_RESOURCE(resn);
                   2041:                resp = ACPI_NEXT_RESOURCE(resp);
                   2042:                delta = (uint8_t *)resn - (uint8_t *)bufn.Pointer;
                   2043:                if (delta >=
                   2044:                    bufn.Length-ACPI_RS_SIZE(ACPI_RESOURCE_DATA)) {
                   2045:                        bufn.Length *= 2;
                   2046:                        bufn.Pointer = realloc(bufn.Pointer, bufn.Length,
                   2047:                                               M_ACPI, M_WAITOK);
                   2048:                        resn = (ACPI_RESOURCE *)((uint8_t *)bufn.Pointer +
                   2049:                            delta);
                   2050:                }
                   2051:        }
                   2052:
                   2053:        if (resc->Type != ACPI_RESOURCE_TYPE_END_TAG) {
                   2054:                aprint_error_dev(acpi_softc->sc_dev,
                   2055:                    "%s: resc not exhausted\n", __func__);
                   2056:                rv = AE_BAD_DATA;
                   2057:                goto out3;
                   2058:        }
                   2059:
                   2060:        resn->Type = ACPI_RESOURCE_TYPE_END_TAG;
                   2061:        rv = AcpiSetCurrentResources(handle, &bufn);
                   2062:
                   2063:        if (ACPI_FAILURE(rv))
                   2064:                aprint_error_dev(acpi_softc->sc_dev, "%s: failed to set "
                   2065:                    "resources: %s\n", __func__, AcpiFormatException(rv));
                   2066:
                   2067: out3:
                   2068:        free(bufn.Pointer, M_ACPI);
                   2069: out2:
                   2070:        ACPI_FREE(bufc.Pointer);
                   2071: out1:
                   2072:        ACPI_FREE(bufp.Pointer);
                   2073: out:
                   2074:        return rv;
                   2075: }
                   2076:
                   2077: #endif /* ACPI_ACTIVATE_DEV */

CVSweb <webmaster@jp.NetBSD.org>