[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.178

1.178   ! jruoho      1: /*     $NetBSD: acpi.c,v 1.177 2010/04/18 14:07:16 jruoho Exp $        */
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.34      thorpej    33:  * Copyright 2001, 2003 Wasabi Systems, Inc.
1.1       thorpej    34:  * All rights reserved.
                     35:  *
                     36:  * Written by Jason R. Thorpe 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:
1.5       lukem      67: #include <sys/cdefs.h>
1.178   ! jruoho     68: __KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.177 2010/04/18 14:07:16 jruoho Exp $");
1.27      christos   69:
                     70: #include "opt_acpi.h"
1.73      sekiya     71: #include "opt_pcifixup.h"
1.1       thorpej    72:
                     73: #include <sys/param.h>
                     74: #include <sys/device.h>
1.155     jruoho     75: #include <sys/kernel.h>
1.1       thorpej    76: #include <sys/malloc.h>
1.100     xtraeme    77: #include <sys/mutex.h>
1.78      cube       78: #include <sys/sysctl.h>
1.155     jruoho     79: #include <sys/systm.h>
1.1       thorpej    80:
                     81: #include <dev/acpi/acpireg.h>
                     82: #include <dev/acpi/acpivar.h>
                     83: #include <dev/acpi/acpi_osd.h>
1.155     jruoho     84: #include <dev/acpi/acpi_pci.h>
1.90      drochner   85: #include <dev/acpi/acpi_timer.h>
1.127     jmcneill   86: #include <dev/acpi/acpi_wakedev.h>
1.155     jruoho     87:
1.27      christos   88: #ifdef ACPIVERBOSE
                     89: #include <dev/acpi/acpidevs_data.h>
                     90: #endif
1.1       thorpej    91:
1.169     jruoho     92: #define _COMPONENT     ACPI_BUS_COMPONENT
                     93: ACPI_MODULE_NAME       ("acpi")
1.132     mlelstv    94:
1.74      sekiya     95: #if defined(ACPI_PCI_FIXUP)
1.93      christos   96: #error The option ACPI_PCI_FIXUP has been obsoleted by PCI_INTR_FIXUP_DISABLED.  Please adjust your kernel configuration file.
1.74      sekiya     97: #endif
                     98:
1.93      christos   99: #ifdef PCI_INTR_FIXUP_DISABLED
1.13      augustss  100: #include <dev/pci/pcidevs.h>
                    101: #endif
                    102:
1.33      christos  103: MALLOC_DECLARE(M_ACPI);
                    104:
1.10      tshiozak  105: #include <machine/acpi_machdep.h>
1.39      kochi     106:
1.40      kochi     107: #ifdef ACPI_DEBUGGER
1.1       thorpej   108: #define        ACPI_DBGR_INIT          0x01
                    109: #define        ACPI_DBGR_TABLES        0x02
                    110: #define        ACPI_DBGR_ENABLE        0x04
                    111: #define        ACPI_DBGR_PROBE         0x08
                    112: #define        ACPI_DBGR_RUNNING       0x10
                    113:
1.82      kochi     114: static int acpi_dbgr = 0x00;
1.1       thorpej   115: #endif
                    116:
                    117: /*
                    118:  * This is a flag we set when the ACPI subsystem is active.  Machine
                    119:  * dependent code may wish to skip other steps (such as attaching
                    120:  * subsystems that ACPI supercedes) when ACPI is active.
                    121:  */
                    122: int    acpi_active;
1.93      christos  123: int    acpi_force_load;
1.123     jmcneill  124: int    acpi_suspended = 0;
1.1       thorpej   125:
                    126: struct acpi_softc *acpi_softc;
1.166     jruoho    127: static uint64_t acpi_root_pointer;
1.101     ad        128: extern kmutex_t acpi_interrupt_list_mtx;
1.32      tshiozak  129:
1.79      cube      130: /*
1.176     jruoho    131:  * This structure provides a context for the ACPI
                    132:  * namespace walk performed in acpi_build_tree().
                    133:  */
                    134: struct acpi_walkcontext {
                    135:        struct acpi_softc       *aw_sc;
                    136:        struct acpi_devnode     *aw_parent;
                    137: };
                    138:
                    139: /*
1.147     jruoho    140:  * Ignored HIDs.
1.116     jmcneill  141:  */
                    142: static const char * const acpi_ignored_ids[] = {
                    143: #if defined(i386) || defined(x86_64)
                    144:        "PNP0000",      /* AT interrupt controller is handled internally */
                    145:        "PNP0200",      /* AT DMA controller is handled internally */
1.137     cegger    146:        "PNP0A??",      /* PCI Busses are handled internally */
1.116     jmcneill  147:        "PNP0B00",      /* AT RTC is handled internally */
                    148:        "PNP0C01",      /* No "System Board" driver */
                    149:        "PNP0C02",      /* No "PnP motherboard register resources" driver */
1.143     jruoho    150:        "PNP0C0B",      /* No need for "ACPI fan" driver */
1.116     jmcneill  151:        "PNP0C0F",      /* ACPI PCI link devices are handled internally */
1.162     jruoho    152:        "IFX0102",      /* No driver for Infineon TPM */
                    153:        "INT0800",      /* No driver for Intel Firmware Hub device */
1.116     jmcneill  154: #endif
                    155: #if defined(x86_64)
                    156:        "PNP0C04",      /* FPU is handled internally */
                    157: #endif
                    158:        NULL
                    159: };
                    160:
1.169     jruoho    161: static int             acpi_match(device_t, cfdata_t, void *);
                    162: static int             acpi_submatch(device_t, cfdata_t, const int *, void *);
                    163: static void            acpi_attach(device_t, device_t, void *);
                    164: static int             acpi_detach(device_t, int);
                    165: static void            acpi_childdet(device_t, device_t);
                    166: static bool            acpi_suspend(device_t, const pmf_qual_t *);
                    167: static bool            acpi_resume(device_t, const pmf_qual_t *);
                    168:
1.64      kochi     169: static void            acpi_build_tree(struct acpi_softc *);
1.176     jruoho    170:
                    171: #ifdef ACPI_DEBUG
                    172: static void            acpi_print_tree(struct acpi_devnode *, uint32_t);
                    173: #endif
                    174:
1.151     jruoho    175: static ACPI_STATUS     acpi_make_devnode(ACPI_HANDLE, uint32_t,
                    176:                                          void *, void **);
1.176     jruoho    177: static ACPI_STATUS     acpi_make_devnode_post(ACPI_HANDLE, uint32_t,
                    178:                                               void *, void **);
1.1       thorpej   179:
1.169     jruoho    180: #ifdef ACPI_ACTIVATE_DEV
                    181: static void            acpi_activate_device(ACPI_HANDLE, ACPI_DEVICE_INFO **);
                    182: static ACPI_STATUS     acpi_allocate_resources(ACPI_HANDLE);
                    183: #endif
                    184:
                    185: static int             acpi_rescan(device_t, const char *, const int *);
                    186: static void            acpi_rescan1(struct acpi_softc *,
                    187:                                     const char *, const int *);
                    188: static void            acpi_rescan_nodes(struct acpi_softc *);
                    189: static void            acpi_rescan_capabilities(struct acpi_softc *);
                    190: static int             acpi_print(void *aux, const char *);
                    191:
1.175     jruoho    192: static void            acpi_notify_handler(ACPI_HANDLE, uint32_t, void *);
                    193:
1.168     jruoho    194: static void            acpi_register_fixed_button(struct acpi_softc *, int);
                    195: static void            acpi_deregister_fixed_button(struct acpi_softc *, int);
                    196: static uint32_t                acpi_fixed_button_handler(void *);
                    197: static void            acpi_fixed_button_pressed(void *);
                    198:
1.166     jruoho    199: static void            acpi_sleep_init(struct acpi_softc *);
1.1       thorpej   200:
1.169     jruoho    201: static int             sysctl_hw_acpi_fixedstats(SYSCTLFN_ARGS);
                    202: static int             sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS);
                    203: static int             sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS);
                    204:
1.108     jmcneill  205: static ACPI_TABLE_HEADER *acpi_map_rsdt(void);
                    206: static void            acpi_unmap_rsdt(ACPI_TABLE_HEADER *);
                    207:
1.169     jruoho    208: extern struct cfdriver acpi_cd;
1.123     jmcneill  209:
1.169     jruoho    210: CFATTACH_DECL2_NEW(acpi, sizeof(struct acpi_softc),
                    211:     acpi_match, acpi_attach, acpi_detach, NULL, acpi_rescan, acpi_childdet);
1.159     jruoho    212:
1.1       thorpej   213: /*
1.169     jruoho    214:  * Probe for ACPI support.
1.1       thorpej   215:  *
1.169     jruoho    216:  * This is called by the machine-dependent ACPI front-end.
                    217:  * Note: this is not an autoconfiguration interface function.
1.1       thorpej   218:  */
                    219: int
                    220: acpi_probe(void)
                    221: {
1.108     jmcneill  222:        ACPI_TABLE_HEADER *rsdt;
1.172     jruoho    223:        const char *func;
                    224:        static int once;
                    225:        bool initialized;
1.1       thorpej   226:        ACPI_STATUS rv;
1.169     jruoho    227:
                    228:        if (once != 0)
                    229:                panic("%s: already probed", __func__);
1.1       thorpej   230:
1.169     jruoho    231:        once = 1;
1.172     jruoho    232:        func = NULL;
                    233:        initialized = false;
1.1       thorpej   234:
1.103     ad        235:        mutex_init(&acpi_interrupt_list_mtx, MUTEX_DEFAULT, IPL_NONE);
1.32      tshiozak  236:
1.1       thorpej   237:        /*
                    238:         * Start up ACPICA.
                    239:         */
1.40      kochi     240: #ifdef ACPI_DEBUGGER
1.1       thorpej   241:        if (acpi_dbgr & ACPI_DBGR_INIT)
                    242:                acpi_osd_debugger();
                    243: #endif
                    244:
1.178   ! jruoho    245:        CTASSERT(TRUE == true);
        !           246:        CTASSERT(FALSE == false);
        !           247:
1.172     jruoho    248:        AcpiGbl_AllMethodsSerialized = false;
                    249:        AcpiGbl_EnableInterpreterSlack = true;
1.104     jmcneill  250:
1.1       thorpej   251:        rv = AcpiInitializeSubsystem();
1.172     jruoho    252:
                    253:        if (ACPI_SUCCESS(rv))
                    254:                initialized = true;
                    255:        else {
                    256:                func = "AcpiInitializeSubsystem()";
                    257:                goto fail;
1.1       thorpej   258:        }
                    259:
1.178   ! jruoho    260:        /*
        !           261:         * Allocate space for RSDT/XSDT and DSDT,
        !           262:         * but allow resizing if more tables exist.
        !           263:         */
        !           264:        rv = AcpiInitializeTables(NULL, 2, true);
1.172     jruoho    265:
1.104     jmcneill  266:        if (ACPI_FAILURE(rv)) {
1.172     jruoho    267:                func = "AcpiInitializeTables()";
                    268:                goto fail;
1.104     jmcneill  269:        }
                    270:
1.40      kochi     271: #ifdef ACPI_DEBUGGER
1.1       thorpej   272:        if (acpi_dbgr & ACPI_DBGR_TABLES)
                    273:                acpi_osd_debugger();
                    274: #endif
                    275:
                    276:        rv = AcpiLoadTables();
1.172     jruoho    277:
1.56      mycroft   278:        if (ACPI_FAILURE(rv)) {
1.172     jruoho    279:                func = "AcpiLoadTables()";
                    280:                goto fail;
1.1       thorpej   281:        }
                    282:
1.108     jmcneill  283:        rsdt = acpi_map_rsdt();
1.172     jruoho    284:
1.108     jmcneill  285:        if (rsdt == NULL) {
1.172     jruoho    286:                func = "acpi_map_rsdt()";
                    287:                rv = AE_ERROR;
                    288:                goto fail;
1.108     jmcneill  289:        }
1.107     jmcneill  290:
1.172     jruoho    291:        if (acpi_force_load == 0 && (acpi_find_quirks() & ACPI_QUIRK_BROKEN)) {
                    292:                aprint_normal("ACPI: BIOS is listed as broken:\n");
                    293:                aprint_normal("ACPI: X/RSDT: OemId <%6.6s,%8.8s,%08x>, "
1.93      christos  294:                       "AslId <%4.4s,%08x>\n",
1.108     jmcneill  295:                        rsdt->OemId, rsdt->OemTableId,
                    296:                        rsdt->OemRevision,
                    297:                        rsdt->AslCompilerId,
                    298:                        rsdt->AslCompilerRevision);
1.172     jruoho    299:                aprint_normal("ACPI: Not used. Set acpi_force_load to use.\n");
1.108     jmcneill  300:                acpi_unmap_rsdt(rsdt);
1.130     jmcneill  301:                AcpiTerminate();
1.93      christos  302:                return 0;
                    303:        }
                    304:
1.108     jmcneill  305:        acpi_unmap_rsdt(rsdt);
                    306:
1.107     jmcneill  307: #if notyet
1.169     jruoho    308:        /*
                    309:         * Install the default address space handlers.
                    310:         */
1.172     jruoho    311:        func = "AcpiInstallAddressSpaceHandler()";
                    312:
1.104     jmcneill  313:        rv = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
                    314:            ACPI_ADR_SPACE_SYSTEM_MEMORY, ACPI_DEFAULT_HANDLER, NULL, NULL);
1.172     jruoho    315:
                    316:        if (ACPI_FAILURE(rv))
                    317:                goto fail;
                    318:
1.104     jmcneill  319:        rv = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
                    320:            ACPI_ADR_SPACE_SYSTEM_IO, ACPI_DEFAULT_HANDLER, NULL, NULL);
1.172     jruoho    321:
                    322:        if (ACPI_FAILURE(rv))
                    323:                goto fail;
                    324:
1.104     jmcneill  325:        rv = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
                    326:            ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
1.172     jruoho    327:
                    328:        if (ACPI_FAILURE(rv))
                    329:                goto fail;
1.104     jmcneill  330: #endif
                    331:
                    332:        rv = AcpiEnableSubsystem(~(ACPI_NO_HARDWARE_INIT|ACPI_NO_ACPI_ENABLE));
1.172     jruoho    333:
1.104     jmcneill  334:        if (ACPI_FAILURE(rv)) {
1.172     jruoho    335:                func = "AcpiEnableSubsystem()";
                    336:                goto fail;
1.104     jmcneill  337:        }
                    338:
1.1       thorpej   339:        /*
                    340:         * Looks like we have ACPI!
                    341:         */
1.63      kochi     342:        return 1;
1.172     jruoho    343:
                    344: fail:
                    345:        KASSERT(rv != AE_OK);
                    346:        KASSERT(func != NULL);
                    347:
                    348:        aprint_error("%s: failed to probe ACPI: %s\n",
                    349:            func, AcpiFormatException(rv));
                    350:
                    351:        if (initialized != false)
                    352:                (void)AcpiTerminate();
                    353:
                    354:        return 0;
1.1       thorpej   355: }
                    356:
1.98      cube      357: int
                    358: acpi_check(device_t parent, const char *ifattr)
                    359: {
                    360:        return (config_search_ia(acpi_submatch, parent, ifattr, NULL) != NULL);
                    361: }
                    362:
1.174     jruoho    363: /*
                    364:  * Autoconfiguration.
                    365:  */
1.64      kochi     366: static int
1.126     cegger    367: acpi_match(device_t parent, cfdata_t match, void *aux)
1.1       thorpej   368: {
                    369:        /*
1.169     jruoho    370:         * XXX: Nada; MD code has called acpi_probe().
1.1       thorpej   371:         */
1.63      kochi     372:        return 1;
1.1       thorpej   373: }
                    374:
1.169     jruoho    375: static int
                    376: acpi_submatch(device_t parent, cfdata_t cf, const int *locs, void *aux)
1.111     dyoung    377: {
1.169     jruoho    378:        struct cfattach *ca;
1.111     dyoung    379:
1.169     jruoho    380:        ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname);
1.124     dyoung    381:
1.169     jruoho    382:        return (ca == &acpi_ca);
1.111     dyoung    383: }
                    384:
1.64      kochi     385: static void
1.111     dyoung    386: acpi_attach(device_t parent, device_t self, void *aux)
1.1       thorpej   387: {
1.111     dyoung    388:        struct acpi_softc *sc = device_private(self);
1.1       thorpej   389:        struct acpibus_attach_args *aa = aux;
1.166     jruoho    390:        ACPI_TABLE_HEADER *rsdt;
1.1       thorpej   391:        ACPI_STATUS rv;
                    392:
1.116     jmcneill  393:        aprint_naive("\n");
                    394:        aprint_normal(": Intel ACPICA %08x\n", ACPI_CA_VERSION);
1.1       thorpej   395:
                    396:        if (acpi_softc != NULL)
1.172     jruoho    397:                panic("%s: already attached", __func__);
1.29      fvdl      398:
1.172     jruoho    399:        rsdt = acpi_map_rsdt();
1.37      kochi     400:
1.172     jruoho    401:        if (rsdt == NULL)
                    402:                aprint_error_dev(self, "X/RSDT: Not found\n");
                    403:        else {
                    404:                aprint_verbose_dev(self,
1.111     dyoung    405:                    "X/RSDT: OemId <%6.6s,%8.8s,%08x>, AslId <%4.4s,%08x>\n",
1.108     jmcneill  406:                    rsdt->OemId, rsdt->OemTableId,
                    407:                    rsdt->OemRevision,
                    408:                    rsdt->AslCompilerId, rsdt->AslCompilerRevision);
1.172     jruoho    409:        }
1.157     jruoho    410:
1.108     jmcneill  411:        acpi_unmap_rsdt(rsdt);
1.1       thorpej   412:
1.113     jmcneill  413:        sc->sc_dev = self;
1.176     jruoho    414:        sc->sc_root = NULL;
                    415:
                    416:        sc->sc_sleepstate = ACPI_STATE_S0;
1.36      fvdl      417:        sc->sc_quirks = acpi_find_quirks();
                    418:
1.172     jruoho    419:        sysmon_power_settype("acpi");
                    420:
1.1       thorpej   421:        sc->sc_iot = aa->aa_iot;
                    422:        sc->sc_memt = aa->aa_memt;
                    423:        sc->sc_pc = aa->aa_pc;
                    424:        sc->sc_pciflags = aa->aa_pciflags;
1.19      jmcneill  425:        sc->sc_ic = aa->aa_ic;
1.1       thorpej   426:
1.176     jruoho    427:        SIMPLEQ_INIT(&sc->ad_head);
1.157     jruoho    428:
1.1       thorpej   429:        acpi_softc = sc;
                    430:
1.172     jruoho    431:        if (pmf_device_register(self, acpi_suspend, acpi_resume) != true)
1.104     jmcneill  432:                aprint_error_dev(self, "couldn't establish power handler\n");
                    433:
                    434:        /*
1.1       thorpej   435:         * Bring ACPI on-line.
                    436:         */
1.40      kochi     437: #ifdef ACPI_DEBUGGER
1.1       thorpej   438:        if (acpi_dbgr & ACPI_DBGR_ENABLE)
                    439:                acpi_osd_debugger();
                    440: #endif
1.47      mycroft   441:
1.104     jmcneill  442: #define ACPI_ENABLE_PHASE1 \
                    443:     (ACPI_NO_HANDLER_INIT | ACPI_NO_EVENT_INIT)
                    444: #define ACPI_ENABLE_PHASE2 \
                    445:     (ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE | \
                    446:      ACPI_NO_ADDRESS_SPACE_INIT)
                    447:
                    448:        rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE1);
1.172     jruoho    449:
                    450:        if (ACPI_FAILURE(rv))
                    451:                goto fail;
1.104     jmcneill  452:
                    453:        acpi_md_callback();
                    454:
                    455:        rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE2);
1.172     jruoho    456:
                    457:        if (ACPI_FAILURE(rv))
                    458:                goto fail;
1.60      kochi     459:
1.174     jruoho    460:        /*
                    461:         * Early EC handler initialization if ECDT table is available.
                    462:         */
1.163     dyoung    463:        config_found_ia(self, "acpiecdtbus", aa, NULL);
1.60      kochi     464:
1.104     jmcneill  465:        rv = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION);
1.172     jruoho    466:
                    467:        if (ACPI_FAILURE(rv))
                    468:                goto fail;
                    469:
1.175     jruoho    470:        /*
                    471:         * Install global notify handlers.
                    472:         */
                    473:        rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT,
                    474:            ACPI_SYSTEM_NOTIFY, acpi_notify_handler, NULL);
                    475:
                    476:        if (ACPI_FAILURE(rv))
                    477:                goto fail;
                    478:
                    479:        rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT,
                    480:            ACPI_DEVICE_NOTIFY, acpi_notify_handler, NULL);
                    481:
                    482:        if (ACPI_FAILURE(rv))
                    483:                goto fail;
                    484:
1.1       thorpej   485:        acpi_active = 1;
                    486:
1.9       kanaoka   487:        /* Show SCI interrupt. */
1.150     jruoho    488:        aprint_verbose_dev(self, "SCI interrupting at int %u\n",
1.111     dyoung    489:            AcpiGbl_FADT.SciInterrupt);
1.104     jmcneill  490:
1.1       thorpej   491:        /*
1.168     jruoho    492:         * Install fixed-event handlers.
1.1       thorpej   493:         */
1.168     jruoho    494:        acpi_register_fixed_button(sc, ACPI_EVENT_POWER_BUTTON);
                    495:        acpi_register_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON);
                    496:
1.90      drochner  497:        acpitimer_init();
1.1       thorpej   498:
1.40      kochi     499: #ifdef ACPI_DEBUGGER
1.1       thorpej   500:        if (acpi_dbgr & ACPI_DBGR_PROBE)
                    501:                acpi_osd_debugger();
                    502: #endif
1.166     jruoho    503:
1.168     jruoho    504:        /*
                    505:         * Scan the namespace and build our device tree.
                    506:         */
1.1       thorpej   507:        acpi_build_tree(sc);
1.166     jruoho    508:        acpi_sleep_init(sc);
1.78      cube      509:
1.40      kochi     510: #ifdef ACPI_DEBUGGER
1.1       thorpej   511:        if (acpi_dbgr & ACPI_DBGR_RUNNING)
                    512:                acpi_osd_debugger();
                    513: #endif
1.148     jruoho    514:
                    515: #ifdef ACPI_DEBUG
                    516:        acpi_debug_init();
                    517: #endif
1.172     jruoho    518:
                    519:        return;
                    520:
                    521: fail:
                    522:        KASSERT(rv != AE_OK);
                    523:
                    524:        aprint_error("%s: failed to initialize ACPI: %s\n",
                    525:            __func__, AcpiFormatException(rv));
1.1       thorpej   526: }
                    527:
1.171     jruoho    528: /*
                    529:  * XXX: This is incomplete.
                    530:  */
1.124     dyoung    531: static int
                    532: acpi_detach(device_t self, int flags)
                    533: {
1.168     jruoho    534:        struct acpi_softc *sc = device_private(self);
1.175     jruoho    535:        ACPI_STATUS rv;
1.124     dyoung    536:        int rc;
                    537:
1.175     jruoho    538:        rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT,
                    539:            ACPI_SYSTEM_NOTIFY, acpi_notify_handler);
                    540:
                    541:        if (ACPI_FAILURE(rv))
                    542:                return EBUSY;
                    543:
                    544:        rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT,
                    545:            ACPI_DEVICE_NOTIFY, acpi_notify_handler);
                    546:
                    547:        if (ACPI_FAILURE(rv))
                    548:                return EBUSY;
                    549:
1.124     dyoung    550:        if ((rc = config_detach_children(self, flags)) != 0)
                    551:                return rc;
                    552:
                    553:        if ((rc = acpitimer_detach()) != 0)
                    554:                return rc;
                    555:
1.168     jruoho    556:        acpi_deregister_fixed_button(sc, ACPI_EVENT_POWER_BUTTON);
                    557:        acpi_deregister_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON);
1.124     dyoung    558:
                    559:        pmf_device_deregister(self);
                    560:
                    561:        acpi_softc = NULL;
                    562:
                    563:        return 0;
                    564: }
                    565:
1.169     jruoho    566: /*
                    567:  * XXX: Need to reclaim any resources? Yes.
                    568:  */
                    569: static void
                    570: acpi_childdet(device_t self, device_t child)
                    571: {
                    572:        struct acpi_softc *sc = device_private(self);
                    573:        struct acpi_devnode *ad;
                    574:
                    575:        if (sc->sc_apmbus == child)
                    576:                sc->sc_apmbus = NULL;
                    577:
1.176     jruoho    578:        SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
1.169     jruoho    579:
                    580:                if (ad->ad_device == child)
                    581:                        ad->ad_device = NULL;
                    582:        }
                    583: }
                    584:
1.123     jmcneill  585: static bool
1.149     dyoung    586: acpi_suspend(device_t dv, const pmf_qual_t *qual)
1.123     jmcneill  587: {
1.169     jruoho    588:
1.123     jmcneill  589:        acpi_suspended = 1;
1.169     jruoho    590:
1.123     jmcneill  591:        return true;
                    592: }
                    593:
                    594: static bool
1.149     dyoung    595: acpi_resume(device_t dv, const pmf_qual_t *qual)
1.123     jmcneill  596: {
1.169     jruoho    597:
1.123     jmcneill  598:        acpi_suspended = 0;
1.169     jruoho    599:
1.123     jmcneill  600:        return true;
                    601: }
                    602:
1.1       thorpej   603: /*
1.169     jruoho    604:  * Namespace scan.
1.1       thorpej   605:  */
1.64      kochi     606: static void
1.1       thorpej   607: acpi_build_tree(struct acpi_softc *sc)
                    608: {
1.176     jruoho    609:        struct acpi_walkcontext awc;
1.157     jruoho    610:
1.176     jruoho    611:        awc.aw_sc = sc;
                    612:        awc.aw_parent = NULL;
                    613:
                    614:        (void)acpi_make_devnode(ACPI_ROOT_OBJECT, 0, &awc, NULL);
                    615:
                    616:        KASSERT(sc->sc_root == NULL);
                    617:        KASSERT(awc.aw_parent != NULL);
                    618:
                    619:        sc->sc_root = awc.aw_parent;
                    620:
                    621:        (void)AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, UINT32_MAX,
                    622:            acpi_make_devnode, acpi_make_devnode_post, &awc, NULL);
                    623:
                    624: #ifdef ACPI_DEBUG
                    625:        acpi_print_tree(sc->sc_root, 0);
                    626: #endif
1.124     dyoung    627:
                    628:        acpi_rescan1(sc, NULL, NULL);
1.160     jruoho    629:        acpi_rescan_capabilities(sc);
                    630:
1.137     cegger    631:        acpi_pcidev_scan(sc);
1.124     dyoung    632: }
1.1       thorpej   633:
1.176     jruoho    634: #ifdef ACPI_DEBUG
                    635: static void
                    636: acpi_print_tree(struct acpi_devnode *ad, uint32_t level)
                    637: {
                    638:        struct acpi_devnode *child;
                    639:        uint32_t i;
                    640:
                    641:        for (i = 0; i < level; i++)
                    642:                aprint_normal("           ");
                    643:
                    644:        aprint_normal("[%02u] %-5s\n", ad->ad_type, ad->ad_name);
                    645:
                    646:        SIMPLEQ_FOREACH(child, &ad->ad_child_head, ad_child_list)
                    647:            acpi_print_tree(child, level + 1);
                    648: }
                    649: #endif
                    650:
1.169     jruoho    651: static ACPI_STATUS
                    652: acpi_make_devnode(ACPI_HANDLE handle, uint32_t level,
                    653:     void *context, void **status)
1.124     dyoung    654: {
1.176     jruoho    655:        struct acpi_walkcontext *awc = context;
                    656:        struct acpi_softc *sc = awc->aw_sc;
1.169     jruoho    657:        struct acpi_devnode *ad;
                    658:        ACPI_DEVICE_INFO *devinfo;
                    659:        ACPI_OBJECT_TYPE type;
                    660:        ACPI_NAME_UNION *anu;
                    661:        ACPI_STATUS rv;
                    662:        int clear, i;
                    663:
                    664:        rv = AcpiGetObjectInfo(handle, &devinfo);
1.124     dyoung    665:
1.169     jruoho    666:        if (ACPI_FAILURE(rv))
                    667:                return AE_OK;   /* Do not terminate the walk. */
1.124     dyoung    668:
1.169     jruoho    669:        type = devinfo->Type;
1.124     dyoung    670:
1.169     jruoho    671:        switch (type) {
1.124     dyoung    672:
1.169     jruoho    673:        case ACPI_TYPE_DEVICE:
1.124     dyoung    674:
1.169     jruoho    675: #ifdef ACPI_ACTIVATE_DEV
                    676:                acpi_activate_device(handle, &devinfo);
                    677: #endif
1.124     dyoung    678:
1.169     jruoho    679:        case ACPI_TYPE_PROCESSOR:
                    680:        case ACPI_TYPE_THERMAL:
                    681:        case ACPI_TYPE_POWER:
1.124     dyoung    682:
1.169     jruoho    683:                ad = malloc(sizeof(*ad), M_ACPI, M_NOWAIT | M_ZERO);
1.25      jmcneill  684:
1.169     jruoho    685:                if (ad == NULL)
                    686:                        return AE_NO_MEMORY;
1.1       thorpej   687:
1.175     jruoho    688:                ad->ad_device = NULL;
1.176     jruoho    689:                ad->ad_notify = NULL;
1.175     jruoho    690:
                    691:                ad->ad_type = type;
                    692:                ad->ad_handle = handle;
1.169     jruoho    693:                ad->ad_devinfo = devinfo;
1.157     jruoho    694:
1.176     jruoho    695:                ad->ad_root = sc->sc_dev;
                    696:                ad->ad_parent = awc->aw_parent;
                    697:
1.169     jruoho    698:                anu = (ACPI_NAME_UNION *)&devinfo->Name;
                    699:                ad->ad_name[4] = '\0';
1.157     jruoho    700:
1.169     jruoho    701:                for (i = 3, clear = 0; i >= 0; i--) {
1.116     jmcneill  702:
1.169     jruoho    703:                        if (clear == 0 && anu->Ascii[i] == '_')
                    704:                                ad->ad_name[i] = '\0';
                    705:                        else {
                    706:                                ad->ad_name[i] = anu->Ascii[i];
                    707:                                clear = 1;
                    708:                        }
                    709:                }
1.1       thorpej   710:
1.169     jruoho    711:                if (ad->ad_name[0] == '\0')
                    712:                        ad->ad_name[0] = '_';
1.160     jruoho    713:
1.176     jruoho    714:                SIMPLEQ_INIT(&ad->ad_child_head);
                    715:                SIMPLEQ_INSERT_TAIL(&sc->ad_head, ad, ad_list);
                    716:
                    717:                if (ad->ad_parent != NULL) {
                    718:
                    719:                        SIMPLEQ_INSERT_TAIL(&ad->ad_parent->ad_child_head,
                    720:                            ad, ad_child_list);
                    721:                }
                    722:
                    723:                awc->aw_parent = ad;
1.160     jruoho    724:
1.169     jruoho    725: #ifdef ACPIVERBOSE
1.160     jruoho    726:
1.169     jruoho    727:                if (type != ACPI_TYPE_DEVICE)
                    728:                        return AE_OK;
1.160     jruoho    729:
1.169     jruoho    730:                aprint_normal_dev(sc->sc_dev, "%-5s ", ad->ad_name);
1.160     jruoho    731:
1.169     jruoho    732:                aprint_normal("HID %-10s ",
                    733:                    ((devinfo->Valid & ACPI_VALID_HID) != 0) ?
                    734:                    devinfo->HardwareId.String: "-");
1.160     jruoho    735:
1.169     jruoho    736:                aprint_normal("UID %-4s ",
                    737:                    ((devinfo->Valid & ACPI_VALID_UID) != 0) ?
                    738:                    devinfo->UniqueId.String : "-");
                    739:
                    740:                if ((devinfo->Valid & ACPI_VALID_STA) != 0)
                    741:                        aprint_normal("STA 0x%08X ", devinfo->CurrentStatus);
                    742:                else
                    743:                        aprint_normal("STA %10s ", "-");
                    744:
                    745:                if ((devinfo->Valid & ACPI_VALID_ADR) != 0)
                    746:                        aprint_normal("ADR 0x%016" PRIX64"",
                    747:                            devinfo->Address);
                    748:
                    749:                aprint_normal("\n");
                    750: #endif
                    751:        }
                    752:
                    753:        return AE_OK;
                    754: }
                    755:
1.176     jruoho    756: static ACPI_STATUS
                    757: acpi_make_devnode_post(ACPI_HANDLE handle, uint32_t level,
                    758:     void *context, void **status)
                    759: {
                    760:        struct acpi_walkcontext *awc = context;
                    761:
                    762:        KASSERT(awc != NULL);
                    763:        KASSERT(awc->aw_parent != NULL);
                    764:
                    765:        if (handle == awc->aw_parent->ad_handle)
                    766:                awc->aw_parent = awc->aw_parent->ad_parent;
                    767:
                    768:        return AE_OK;
                    769: }
                    770:
1.169     jruoho    771: #ifdef ACPI_ACTIVATE_DEV
                    772:
                    773: #define ACPI_DEV_VALID (ACPI_VALID_STA | ACPI_VALID_HID)
                    774: #define ACPI_DEV_STATUS        (ACPI_STA_DEV_PRESENT | ACPI_STA_DEV_ENABLED)
                    775:
                    776: static void
                    777: acpi_activate_device(ACPI_HANDLE handle, ACPI_DEVICE_INFO **di)
                    778: {
                    779:        ACPI_DEVICE_INFO *newdi;
                    780:        ACPI_STATUS rv;
                    781:        uint32_t old;
                    782:
                    783:        /*
                    784:         * If the device is valid and present,
                    785:         * but not enabled, try to activate it.
                    786:         */
                    787:        if (((*di)->Valid & ACPI_DEV_VALID) != ACPI_DEV_VALID)
                    788:                return;
                    789:
                    790:        old = (*di)->CurrentStatus;
                    791:
                    792:        if ((old & ACPI_DEV_STATUS) != ACPI_STA_DEV_PRESENT)
                    793:                return;
                    794:
                    795:        rv = acpi_allocate_resources(handle);
                    796:
                    797:        if (ACPI_FAILURE(rv))
                    798:                goto fail;
                    799:
                    800:        rv = AcpiGetObjectInfo(handle, &newdi);
1.160     jruoho    801:
1.169     jruoho    802:        if (ACPI_FAILURE(rv))
                    803:                goto fail;
1.160     jruoho    804:
1.169     jruoho    805:        ACPI_FREE(*di);
                    806:        *di = newdi;
1.160     jruoho    807:
1.169     jruoho    808:        aprint_verbose_dev(acpi_softc->sc_dev,
                    809:            "%s activated, STA 0x%08X -> STA 0x%08X\n",
                    810:            (*di)->HardwareId.String, old, (*di)->CurrentStatus);
1.160     jruoho    811:
1.169     jruoho    812:        return;
1.160     jruoho    813:
1.169     jruoho    814: fail:
                    815:        aprint_error_dev(acpi_softc->sc_dev, "failed to "
                    816:            "activate %s\n", (*di)->HardwareId.String);
                    817: }
1.160     jruoho    818:
1.169     jruoho    819: /*
                    820:  * XXX: This very incomplete.
                    821:  */
                    822: ACPI_STATUS
                    823: acpi_allocate_resources(ACPI_HANDLE handle)
                    824: {
                    825:        ACPI_BUFFER bufp, bufc, bufn;
                    826:        ACPI_RESOURCE *resp, *resc, *resn;
                    827:        ACPI_RESOURCE_IRQ *irq;
                    828:        ACPI_RESOURCE_EXTENDED_IRQ *xirq;
                    829:        ACPI_STATUS rv;
                    830:        uint delta;
1.160     jruoho    831:
1.169     jruoho    832:        rv = acpi_get(handle, &bufp, AcpiGetPossibleResources);
                    833:        if (ACPI_FAILURE(rv))
                    834:                goto out;
                    835:        rv = acpi_get(handle, &bufc, AcpiGetCurrentResources);
                    836:        if (ACPI_FAILURE(rv)) {
                    837:                goto out1;
                    838:        }
1.160     jruoho    839:
1.169     jruoho    840:        bufn.Length = 1000;
                    841:        bufn.Pointer = resn = malloc(bufn.Length, M_ACPI, M_WAITOK);
                    842:        resp = bufp.Pointer;
                    843:        resc = bufc.Pointer;
                    844:        while (resc->Type != ACPI_RESOURCE_TYPE_END_TAG &&
                    845:               resp->Type != ACPI_RESOURCE_TYPE_END_TAG) {
                    846:                while (resc->Type != resp->Type && resp->Type != ACPI_RESOURCE_TYPE_END_TAG)
                    847:                        resp = ACPI_NEXT_RESOURCE(resp);
                    848:                if (resp->Type == ACPI_RESOURCE_TYPE_END_TAG)
                    849:                        break;
                    850:                /* Found identical Id */
                    851:                resn->Type = resc->Type;
                    852:                switch (resc->Type) {
                    853:                case ACPI_RESOURCE_TYPE_IRQ:
                    854:                        memcpy(&resn->Data, &resp->Data,
                    855:                               sizeof(ACPI_RESOURCE_IRQ));
                    856:                        irq = (ACPI_RESOURCE_IRQ *)&resn->Data;
                    857:                        irq->Interrupts[0] =
                    858:                            ((ACPI_RESOURCE_IRQ *)&resp->Data)->
                    859:                                Interrupts[irq->InterruptCount-1];
                    860:                        irq->InterruptCount = 1;
                    861:                        resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_IRQ);
                    862:                        break;
                    863:                case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
                    864:                        memcpy(&resn->Data, &resp->Data,
                    865:                               sizeof(ACPI_RESOURCE_EXTENDED_IRQ));
                    866:                        xirq = (ACPI_RESOURCE_EXTENDED_IRQ *)&resn->Data;
                    867: #if 0
                    868:                        /*
1.174     jruoho    869:                         * XXX: Not duplicating the interrupt logic above
                    870:                         *      because its not clear what it accomplishes.
1.169     jruoho    871:                         */
                    872:                        xirq->Interrupts[0] =
                    873:                            ((ACPI_RESOURCE_EXT_IRQ *)&resp->Data)->
                    874:                            Interrupts[irq->NumberOfInterrupts-1];
                    875:                        xirq->NumberOfInterrupts = 1;
                    876: #endif
                    877:                        resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_EXTENDED_IRQ);
                    878:                        break;
                    879:                case ACPI_RESOURCE_TYPE_IO:
                    880:                        memcpy(&resn->Data, &resp->Data,
                    881:                               sizeof(ACPI_RESOURCE_IO));
                    882:                        resn->Length = resp->Length;
                    883:                        break;
                    884:                default:
                    885:                        aprint_error_dev(acpi_softc->sc_dev,
                    886:                            "%s: invalid type %u\n", __func__, resc->Type);
                    887:                        rv = AE_BAD_DATA;
                    888:                        goto out2;
                    889:                }
                    890:                resc = ACPI_NEXT_RESOURCE(resc);
                    891:                resn = ACPI_NEXT_RESOURCE(resn);
                    892:                resp = ACPI_NEXT_RESOURCE(resp);
1.173     jruoho    893:                delta = (uint8_t *)resn - (uint8_t *)bufn.Pointer;
1.169     jruoho    894:                if (delta >=
                    895:                    bufn.Length-ACPI_RS_SIZE(ACPI_RESOURCE_DATA)) {
                    896:                        bufn.Length *= 2;
                    897:                        bufn.Pointer = realloc(bufn.Pointer, bufn.Length,
                    898:                                               M_ACPI, M_WAITOK);
1.173     jruoho    899:                        resn = (ACPI_RESOURCE *)((uint8_t *)bufn.Pointer +
                    900:                            delta);
1.160     jruoho    901:                }
                    902:        }
1.169     jruoho    903:
                    904:        if (resc->Type != ACPI_RESOURCE_TYPE_END_TAG) {
                    905:                aprint_error_dev(acpi_softc->sc_dev,
                    906:                    "%s: resc not exhausted\n", __func__);
                    907:                rv = AE_BAD_DATA;
                    908:                goto out3;
                    909:        }
                    910:
                    911:        resn->Type = ACPI_RESOURCE_TYPE_END_TAG;
                    912:        rv = AcpiSetCurrentResources(handle, &bufn);
                    913:
                    914:        if (ACPI_FAILURE(rv))
                    915:                aprint_error_dev(acpi_softc->sc_dev, "%s: failed to set "
                    916:                    "resources: %s\n", __func__, AcpiFormatException(rv));
                    917:
                    918: out3:
                    919:        free(bufn.Pointer, M_ACPI);
                    920: out2:
                    921:        ACPI_FREE(bufc.Pointer);
                    922: out1:
                    923:        ACPI_FREE(bufp.Pointer);
                    924: out:
                    925:        return rv;
1.160     jruoho    926: }
                    927:
1.169     jruoho    928: #undef ACPI_DEV_VALID
                    929: #undef ACPI_DEV_STATUS
                    930:
                    931: #endif /* ACPI_ACTIVATE_DEV */
1.160     jruoho    932:
1.1       thorpej   933: /*
1.169     jruoho    934:  * Device attachment.
1.1       thorpej   935:  */
1.169     jruoho    936: static int
                    937: acpi_rescan(device_t self, const char *ifattr, const int *locators)
                    938: {
                    939:        struct acpi_softc *sc = device_private(self);
                    940:
                    941:        acpi_rescan1(sc, ifattr, locators);
                    942:
                    943:        return 0;
                    944: }
                    945:
                    946: static void
                    947: acpi_rescan1(struct acpi_softc *sc, const char *ifattr, const int *locators)
                    948: {
                    949:
                    950:        if (ifattr_match(ifattr, "acpinodebus"))
                    951:                acpi_rescan_nodes(sc);
                    952:
                    953:        if (ifattr_match(ifattr, "acpiapmbus") && sc->sc_apmbus == NULL)
                    954:                sc->sc_apmbus = config_found_ia(sc->sc_dev,
                    955:                    "acpiapmbus", NULL, NULL);
                    956: }
                    957:
                    958: static void
                    959: acpi_rescan_nodes(struct acpi_softc *sc)
1.1       thorpej   960: {
1.169     jruoho    961:        struct acpi_attach_args aa;
1.1       thorpej   962:        struct acpi_devnode *ad;
                    963:
1.176     jruoho    964:        SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
1.15      augustss  965:
1.169     jruoho    966:                if (ad->ad_device != NULL)
                    967:                        continue;
1.151     jruoho    968:
1.169     jruoho    969:                aa.aa_node = ad;
                    970:                aa.aa_iot = sc->sc_iot;
                    971:                aa.aa_memt = sc->sc_memt;
                    972:                aa.aa_pc = sc->sc_pc;
                    973:                aa.aa_pciflags = sc->sc_pciflags;
                    974:                aa.aa_ic = sc->sc_ic;
1.151     jruoho    975:
1.174     jruoho    976:                /*
                    977:                 * XXX: We only attach devices which are present, enabled, and
                    978:                 *      functioning properly. However, if a device is enabled,
                    979:                 *      it is decoding resources and we should claim these,
                    980:                 *      if possible. This requires changes to bus_space(9).
                    981:                 */
1.169     jruoho    982:                if (ad->ad_devinfo->Type == ACPI_TYPE_DEVICE) {
1.174     jruoho    983:
1.169     jruoho    984:                        if ((ad->ad_devinfo->Valid & ACPI_VALID_STA) ==
                    985:                            ACPI_VALID_STA &&
                    986:                            (ad->ad_devinfo->CurrentStatus &
                    987:                             (ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED|
                    988:                              ACPI_STA_DEV_OK)) !=
                    989:                            (ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED|
                    990:                             ACPI_STA_DEV_OK))
                    991:                                continue;
                    992:                }
1.151     jruoho    993:
1.169     jruoho    994:                /*
1.174     jruoho    995:                 * XXX: The same problem as above. As for example
                    996:                 *      thermal zones and power resources do not
                    997:                 *      have a valid HID, only evaluate devices.
1.169     jruoho    998:                 */
                    999:                if (ad->ad_devinfo->Type == ACPI_TYPE_DEVICE &&
                   1000:                    (ad->ad_devinfo->Valid & ACPI_VALID_HID) == 0)
                   1001:                        continue;
1.151     jruoho   1002:
1.169     jruoho   1003:                /*
                   1004:                 * Handled internally.
                   1005:                 */
                   1006:                if (ad->ad_devinfo->Type == ACPI_TYPE_PROCESSOR ||
                   1007:                    ad->ad_devinfo->Type == ACPI_TYPE_POWER)
                   1008:                        continue;
1.15      augustss 1009:
1.169     jruoho   1010:                /*
                   1011:                 * Skip ignored HIDs.
                   1012:                 */
                   1013:                if (acpi_match_hid(ad->ad_devinfo, acpi_ignored_ids))
                   1014:                        continue;
1.151     jruoho   1015:
1.169     jruoho   1016:                ad->ad_device = config_found_ia(sc->sc_dev,
                   1017:                    "acpinodebus", &aa, acpi_print);
                   1018:        }
                   1019: }
1.151     jruoho   1020:
1.169     jruoho   1021: #define ACPI_STA_DEV_VALID      \
                   1022:        (ACPI_STA_DEV_PRESENT | ACPI_STA_DEV_ENABLED | ACPI_STA_DEV_OK)
1.151     jruoho   1023:
1.169     jruoho   1024: static void
                   1025: acpi_rescan_capabilities(struct acpi_softc *sc)
                   1026: {
                   1027:        struct acpi_devnode *ad;
                   1028:        ACPI_DEVICE_INFO *di;
                   1029:        ACPI_HANDLE tmp;
                   1030:        ACPI_STATUS rv;
1.151     jruoho   1031:
1.176     jruoho   1032:        SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
1.151     jruoho   1033:
1.169     jruoho   1034:                di = ad->ad_devinfo;
1.151     jruoho   1035:
1.169     jruoho   1036:                if (di->Type != ACPI_TYPE_DEVICE)
                   1037:                        continue;
1.151     jruoho   1038:
1.169     jruoho   1039:                if ((di->Valid & ACPI_VALID_STA) != 0 &&
                   1040:                    (di->CurrentStatus & ACPI_STA_DEV_VALID) !=
                   1041:                     ACPI_STA_DEV_VALID)
                   1042:                        continue;
1.151     jruoho   1043:
1.169     jruoho   1044:                /*
                   1045:                 * Scan power resource capabilities.
                   1046:                 */
                   1047:                rv = AcpiGetHandle(ad->ad_handle, "_PR0", &tmp);
1.102     cube     1048:
1.169     jruoho   1049:                if (ACPI_FAILURE(rv))
                   1050:                        rv = AcpiGetHandle(ad->ad_handle, "_PSC", &tmp);
1.158     jruoho   1051:
1.169     jruoho   1052:                if (ACPI_SUCCESS(rv))
                   1053:                        ad->ad_flags |= ACPI_DEVICE_POWER;
1.1       thorpej  1054:
1.169     jruoho   1055:                /*
                   1056:                 * Scan wake-up capabilities.
                   1057:                 */
                   1058:                rv = AcpiGetHandle(ad->ad_handle, "_PRW", &tmp);
1.1       thorpej  1059:
1.169     jruoho   1060:                if (ACPI_SUCCESS(rv)) {
                   1061:                        ad->ad_flags |= ACPI_DEVICE_WAKEUP;
                   1062:                        acpi_wakedev_add(ad);
                   1063:                }
1.158     jruoho   1064:
1.169     jruoho   1065:                if (ad->ad_flags != 0) {
                   1066:                        aprint_debug_dev(sc->sc_dev, "%-5s ", ad->ad_name);
1.158     jruoho   1067:
1.169     jruoho   1068:                        if ((ad->ad_flags & ACPI_DEVICE_POWER) != 0)
                   1069:                                aprint_debug("power ");
1.158     jruoho   1070:
1.169     jruoho   1071:                        if ((ad->ad_flags & ACPI_DEVICE_WAKEUP) != 0)
                   1072:                                aprint_debug("wake-up ");
1.151     jruoho   1073:
1.169     jruoho   1074:                        aprint_debug("\n");
                   1075:                }
1.1       thorpej  1076:        }
1.169     jruoho   1077: }
1.151     jruoho   1078:
1.169     jruoho   1079: #undef ACPI_STA_DEV_VALID
1.1       thorpej  1080:
1.64      kochi    1081: static int
1.1       thorpej  1082: acpi_print(void *aux, const char *pnp)
                   1083: {
                   1084:        struct acpi_attach_args *aa = aux;
1.56      mycroft  1085:        ACPI_STATUS rv;
1.1       thorpej  1086:
1.4       thorpej  1087:        if (pnp) {
1.54      kochi    1088:                if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_HID) {
                   1089:                        char *pnpstr =
1.128     jmcneill 1090:                            aa->aa_node->ad_devinfo->HardwareId.String;
1.121     mlelstv  1091:                        ACPI_BUFFER buf;
1.27      christos 1092:
1.102     cube     1093:                        aprint_normal("%s (%s) ", aa->aa_node->ad_name,
                   1094:                            pnpstr);
1.121     mlelstv  1095:
1.140     jruoho   1096:                        rv = acpi_eval_struct(aa->aa_node->ad_handle,
                   1097:                            "_STR", &buf);
1.56      mycroft  1098:                        if (ACPI_SUCCESS(rv)) {
1.121     mlelstv  1099:                                ACPI_OBJECT *obj = buf.Pointer;
                   1100:                                switch (obj->Type) {
                   1101:                                case ACPI_TYPE_STRING:
                   1102:                                        aprint_normal("[%s] ", obj->String.Pointer);
                   1103:                                        break;
                   1104:                                case ACPI_TYPE_BUFFER:
                   1105:                                        aprint_normal("buffer %p ", obj->Buffer.Pointer);
                   1106:                                        break;
                   1107:                                default:
1.150     jruoho   1108:                                        aprint_normal("type %u ",obj->Type);
1.121     mlelstv  1109:                                        break;
                   1110:                                }
1.132     mlelstv  1111:                                ACPI_FREE(buf.Pointer);
1.27      christos 1112:                        }
                   1113: #ifdef ACPIVERBOSE
                   1114:                        else {
                   1115:                                int i;
                   1116:
1.134     cegger   1117:                                for (i = 0; i < __arraycount(acpi_knowndevs);
                   1118:                                    i++) {
1.27      christos 1119:                                        if (strcmp(acpi_knowndevs[i].pnp,
                   1120:                                            pnpstr) == 0) {
1.83      kochi    1121:                                                aprint_normal("[%s] ",
1.27      christos 1122:                                                    acpi_knowndevs[i].str);
                   1123:                                        }
                   1124:                                }
                   1125:                        }
1.62      kochi    1126:
1.27      christos 1127: #endif
1.104     jmcneill 1128:                        aprint_normal("at %s", pnp);
                   1129:                } else if (aa->aa_node->ad_devinfo->Type != ACPI_TYPE_DEVICE) {
1.102     cube     1130:                        aprint_normal("%s (ACPI Object Type '%s' "
                   1131:                            "[0x%02x]) ", aa->aa_node->ad_name,
                   1132:                             AcpiUtGetTypeName(aa->aa_node->ad_devinfo->Type),
                   1133:                             aa->aa_node->ad_devinfo->Type);
1.104     jmcneill 1134:                        aprint_normal("at %s", pnp);
                   1135:                } else
                   1136:                        return 0;
1.21      matt     1137:        } else {
1.102     cube     1138:                aprint_normal(" (%s", aa->aa_node->ad_name);
1.54      kochi    1139:                if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_HID) {
1.128     jmcneill 1140:                        aprint_normal(", %s", aa->aa_node->ad_devinfo->HardwareId.String);
1.54      kochi    1141:                        if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_UID) {
1.70      christos 1142:                                const char *uid;
1.41      kochi    1143:
1.128     jmcneill 1144:                                uid = aa->aa_node->ad_devinfo->UniqueId.String;
1.48      mycroft  1145:                                if (uid[0] == '\0')
1.41      kochi    1146:                                        uid = "<null>";
                   1147:                                aprint_normal("-%s", uid);
                   1148:                        }
1.22      jmcneill 1149:                }
1.102     cube     1150:                aprint_normal(")");
1.4       thorpej  1151:        }
1.1       thorpej  1152:
1.63      kochi    1153:        return UNCONF;
1.1       thorpej  1154: }
                   1155:
1.168     jruoho   1156: /*
1.175     jruoho   1157:  * Notify.
                   1158:  */
                   1159: static void
                   1160: acpi_notify_handler(ACPI_HANDLE handle, uint32_t event, void *aux)
                   1161: {
                   1162:        struct acpi_softc *sc = acpi_softc;
                   1163:        struct acpi_devnode *ad;
                   1164:
                   1165:        KASSERT(sc != NULL);
                   1166:        KASSERT(aux == NULL);
                   1167:        KASSERT(acpi_active != 0);
                   1168:
                   1169:        if (acpi_suspended != 0)
                   1170:                return;
                   1171:
                   1172:        /*
                   1173:         *  System: 0x00 - 0x7F.
                   1174:         *  Device: 0x80 - 0xFF.
                   1175:         */
                   1176:        switch (event) {
                   1177:
                   1178:        case ACPI_NOTIFY_BUS_CHECK:
                   1179:        case ACPI_NOTIFY_DEVICE_CHECK:
                   1180:        case ACPI_NOTIFY_DEVICE_WAKE:
                   1181:        case ACPI_NOTIFY_EJECT_REQUEST:
                   1182:        case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
                   1183:        case ACPI_NOTIFY_FREQUENCY_MISMATCH:
                   1184:        case ACPI_NOTIFY_BUS_MODE_MISMATCH:
                   1185:        case ACPI_NOTIFY_POWER_FAULT:
                   1186:        case ACPI_NOTIFY_CAPABILITIES_CHECK:
                   1187:        case ACPI_NOTIFY_DEVICE_PLD_CHECK:
                   1188:        case ACPI_NOTIFY_RESERVED:
                   1189:        case ACPI_NOTIFY_LOCALITY_UPDATE:
                   1190:                break;
                   1191:        }
                   1192:
                   1193:        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "notification 0x%02X for "
                   1194:                "%s (%p)\n", event, acpi_name(handle), handle));
                   1195:
                   1196:        /*
                   1197:         * We deliver notifications only to drivers
                   1198:         * that have been succesfully attached and
                   1199:         * that have registered a handler with us.
                   1200:         * The opaque pointer is always the device_t.
                   1201:         */
1.176     jruoho   1202:        SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
1.175     jruoho   1203:
                   1204:                if (ad->ad_device == NULL)
                   1205:                        continue;
                   1206:
                   1207:                if (ad->ad_notify == NULL)
                   1208:                        continue;
                   1209:
                   1210:                if (ad->ad_handle != handle)
                   1211:                        continue;
                   1212:
                   1213:                (*ad->ad_notify)(ad->ad_handle, event, ad->ad_device);
                   1214:
                   1215:                return;
                   1216:        }
                   1217:
                   1218:        aprint_debug_dev(sc->sc_dev, "unhandled notify 0x%02X "
                   1219:            "for %s (%p)\n", event, acpi_name(handle), handle);
                   1220: }
                   1221:
                   1222: bool
                   1223: acpi_register_notify(struct acpi_devnode *ad, ACPI_NOTIFY_HANDLER notify)
                   1224: {
                   1225:        struct acpi_softc *sc = acpi_softc;
                   1226:
                   1227:        KASSERT(sc != NULL);
                   1228:        KASSERT(acpi_active != 0);
                   1229:
                   1230:        if (acpi_suspended != 0)
                   1231:                goto fail;
                   1232:
                   1233:        if (ad == NULL || notify == NULL)
                   1234:                goto fail;
                   1235:
                   1236:        ad->ad_notify = notify;
                   1237:
                   1238:        return true;
                   1239:
                   1240: fail:
                   1241:        aprint_error_dev(sc->sc_dev, "failed to register notify "
                   1242:            "handler for %s (%p)\n", ad->ad_name, ad->ad_handle);
                   1243:
                   1244:        return false;
                   1245: }
                   1246:
                   1247: void
                   1248: acpi_deregister_notify(struct acpi_devnode *ad)
                   1249: {
                   1250:
                   1251:        ad->ad_notify = NULL;
                   1252: }
                   1253:
                   1254: /*
1.168     jruoho   1255:  * Fixed buttons.
                   1256:  */
                   1257: static void
                   1258: acpi_register_fixed_button(struct acpi_softc *sc, int event)
                   1259: {
                   1260:        struct sysmon_pswitch *smpsw;
                   1261:        ACPI_STATUS rv;
                   1262:        int type;
                   1263:
                   1264:        switch (event) {
                   1265:
                   1266:        case ACPI_EVENT_POWER_BUTTON:
                   1267:
                   1268:                if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) != 0)
                   1269:                        return;
                   1270:
                   1271:                type = PSWITCH_TYPE_POWER;
                   1272:                smpsw = &sc->sc_smpsw_power;
                   1273:                break;
                   1274:
                   1275:        case ACPI_EVENT_SLEEP_BUTTON:
                   1276:
                   1277:                if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) != 0)
                   1278:                        return;
                   1279:
                   1280:                type = PSWITCH_TYPE_SLEEP;
                   1281:                smpsw = &sc->sc_smpsw_sleep;
                   1282:                break;
                   1283:
                   1284:        default:
                   1285:                rv = AE_TYPE;
                   1286:                goto fail;
                   1287:        }
                   1288:
                   1289:        smpsw->smpsw_type = type;
                   1290:        smpsw->smpsw_name = device_xname(sc->sc_dev);
                   1291:
                   1292:        if (sysmon_pswitch_register(smpsw) != 0) {
                   1293:                rv = AE_ERROR;
                   1294:                goto fail;
                   1295:        }
                   1296:
                   1297:        rv = AcpiInstallFixedEventHandler(event,
                   1298:            acpi_fixed_button_handler, smpsw);
                   1299:
                   1300:        if (ACPI_FAILURE(rv))
                   1301:                goto fail;
                   1302:
                   1303:        aprint_debug_dev(sc->sc_dev, "fixed %s button present\n",
                   1304:            (type != ACPI_EVENT_SLEEP_BUTTON) ? "power" : "sleep");
                   1305:
                   1306:        return;
1.1       thorpej  1307:
1.168     jruoho   1308: fail:
                   1309:        aprint_error_dev(sc->sc_dev, "failed to register "
                   1310:            "fixed event: %s\n", AcpiFormatException(rv));
                   1311: }
1.1       thorpej  1312:
1.64      kochi    1313: static void
1.169     jruoho   1314: acpi_deregister_fixed_button(struct acpi_softc *sc, int event)
1.69      kochi    1315: {
1.169     jruoho   1316:        struct sysmon_pswitch *smpsw;
1.69      kochi    1317:        ACPI_STATUS rv;
                   1318:
1.169     jruoho   1319:        switch (event) {
1.144     jruoho   1320:
1.169     jruoho   1321:        case ACPI_EVENT_POWER_BUTTON:
                   1322:                smpsw = &sc->sc_smpsw_power;
1.144     jruoho   1323:
1.169     jruoho   1324:                if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) != 0) {
                   1325:                        KASSERT(smpsw->smpsw_type != PSWITCH_TYPE_POWER);
                   1326:                        return;
                   1327:                }
1.144     jruoho   1328:
                   1329:                break;
                   1330:
1.169     jruoho   1331:        case ACPI_EVENT_SLEEP_BUTTON:
                   1332:                smpsw = &sc->sc_smpsw_sleep;
1.144     jruoho   1333:
1.169     jruoho   1334:                if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) != 0) {
                   1335:                        KASSERT(smpsw->smpsw_type != PSWITCH_TYPE_SLEEP);
                   1336:                        return;
                   1337:                }
1.144     jruoho   1338:
                   1339:                break;
1.69      kochi    1340:
1.144     jruoho   1341:        default:
1.169     jruoho   1342:                rv = AE_TYPE;
                   1343:                goto fail;
1.144     jruoho   1344:        }
1.69      kochi    1345:
1.169     jruoho   1346:        rv = AcpiRemoveFixedEventHandler(event, acpi_fixed_button_handler);
                   1347:
                   1348:        if (ACPI_SUCCESS(rv)) {
                   1349:                sysmon_pswitch_unregister(smpsw);
                   1350:                return;
                   1351:        }
1.69      kochi    1352:
1.169     jruoho   1353: fail:
                   1354:        aprint_error_dev(sc->sc_dev, "failed to deregister "
                   1355:            "fixed event: %s\n", AcpiFormatException(rv));
1.69      kochi    1356: }
                   1357:
1.169     jruoho   1358: static uint32_t
                   1359: acpi_fixed_button_handler(void *context)
1.118     dyoung   1360: {
1.169     jruoho   1361:        static const int handler = OSL_NOTIFY_HANDLER;
                   1362:        struct sysmon_pswitch *smpsw = context;
                   1363:
                   1364:        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: fixed event\n", __func__));
                   1365:
                   1366:        (void)AcpiOsExecute(handler, acpi_fixed_button_pressed, smpsw);
                   1367:
                   1368:        return ACPI_INTERRUPT_HANDLED;
1.118     dyoung   1369: }
                   1370:
1.169     jruoho   1371: static void
                   1372: acpi_fixed_button_pressed(void *context)
1.118     dyoung   1373: {
1.169     jruoho   1374:        struct sysmon_pswitch *smpsw = context;
1.118     dyoung   1375:
1.169     jruoho   1376:        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: %s fixed button pressed\n",
                   1377:                __func__, smpsw->smpsw_name));
1.10      tshiozak 1378:
1.169     jruoho   1379:        sysmon_pswitch_event(smpsw, PSWITCH_EVENT_PRESSED);
                   1380: }
1.10      tshiozak 1381:
1.166     jruoho   1382: /*
1.169     jruoho   1383:  * Sleep.
1.166     jruoho   1384:  */
                   1385: static void
                   1386: acpi_sleep_init(struct acpi_softc *sc)
1.10      tshiozak 1387: {
1.166     jruoho   1388:        uint8_t a, b, i;
                   1389:        ACPI_STATUS rv;
1.10      tshiozak 1390:
1.166     jruoho   1391:        CTASSERT(ACPI_STATE_S0 == 0 && ACPI_STATE_S1 == 1);
                   1392:        CTASSERT(ACPI_STATE_S2 == 2 && ACPI_STATE_S3 == 3);
                   1393:        CTASSERT(ACPI_STATE_S4 == 4 && ACPI_STATE_S5 == 5);
                   1394:
1.169     jruoho   1395:        /*
                   1396:         * Evaluate supported sleep states.
                   1397:         */
1.166     jruoho   1398:        for (i = ACPI_STATE_S0; i <= ACPI_STATE_S5; i++) {
                   1399:
                   1400:                rv = AcpiGetSleepTypeData(i, &a, &b);
                   1401:
                   1402:                if (ACPI_SUCCESS(rv))
                   1403:                        sc->sc_sleepstates |= __BIT(i);
                   1404:        }
1.10      tshiozak 1405: }
                   1406:
                   1407: ACPI_STATUS
                   1408: acpi_enter_sleep_state(struct acpi_softc *sc, int state)
                   1409: {
1.166     jruoho   1410:        ACPI_STATUS rv = AE_OK;
1.104     jmcneill 1411:        int err;
1.10      tshiozak 1412:
1.166     jruoho   1413:        if (state == sc->sc_sleepstate)
1.92      christos 1414:                return AE_OK;
                   1415:
1.166     jruoho   1416:        aprint_normal_dev(sc->sc_dev, "entering state S%d\n", state);
1.92      christos 1417:
1.10      tshiozak 1418:        switch (state) {
1.166     jruoho   1419:
1.10      tshiozak 1420:        case ACPI_STATE_S0:
                   1421:                break;
1.166     jruoho   1422:
1.10      tshiozak 1423:        case ACPI_STATE_S1:
                   1424:        case ACPI_STATE_S2:
                   1425:        case ACPI_STATE_S3:
                   1426:        case ACPI_STATE_S4:
1.166     jruoho   1427:
                   1428:                if ((sc->sc_sleepstates & __BIT(state)) == 0) {
                   1429:                        aprint_error_dev(sc->sc_dev, "sleep state "
                   1430:                            "S%d is not available\n", state);
1.10      tshiozak 1431:                        break;
                   1432:                }
1.104     jmcneill 1433:
1.156     jruoho   1434:                acpi_wakedev_commit(sc, state);
1.127     jmcneill 1435:
1.166     jruoho   1436:                if (state != ACPI_STATE_S1 &&
                   1437:                    pmf_system_suspend(PMF_Q_NONE) != true) {
1.113     jmcneill 1438:                        aprint_error_dev(sc->sc_dev, "aborting suspend\n");
1.104     jmcneill 1439:                        break;
                   1440:                }
                   1441:
1.166     jruoho   1442:                rv = AcpiEnterSleepStatePrep(state);
                   1443:
                   1444:                if (ACPI_FAILURE(rv)) {
                   1445:                        aprint_error_dev(sc->sc_dev, "failed to prepare "
                   1446:                            "S%d: %s\n", state, AcpiFormatException(rv));
1.10      tshiozak 1447:                        break;
                   1448:                }
1.104     jmcneill 1449:
1.166     jruoho   1450:                sc->sc_sleepstate = state;
                   1451:
1.92      christos 1452:                if (state == ACPI_STATE_S1) {
1.166     jruoho   1453:
                   1454:                        /* Just enter the state. */
1.12      kanaoka  1455:                        acpi_md_OsDisableInterrupt();
1.166     jruoho   1456:                        rv = AcpiEnterSleepState(state);
                   1457:
                   1458:                        if (ACPI_FAILURE(rv))
                   1459:                                aprint_error_dev(sc->sc_dev, "failed to "
                   1460:                                    "enter S1: %s\n", AcpiFormatException(rv));
                   1461:
                   1462:                        (void)AcpiLeaveSleepState(state);
                   1463:
1.10      tshiozak 1464:                } else {
1.166     jruoho   1465:
1.104     jmcneill 1466:                        err = acpi_md_sleep(state);
1.166     jruoho   1467:
1.104     jmcneill 1468:                        if (state == ACPI_STATE_S4)
1.10      tshiozak 1469:                                AcpiEnable();
1.166     jruoho   1470:
1.133     dyoung   1471:                        pmf_system_bus_resume(PMF_Q_NONE);
1.166     jruoho   1472:                        (void)AcpiLeaveSleepState(state);
1.133     dyoung   1473:                        pmf_system_resume(PMF_Q_NONE);
1.10      tshiozak 1474:                }
1.104     jmcneill 1475:
1.10      tshiozak 1476:                break;
                   1477:        case ACPI_STATE_S5:
1.166     jruoho   1478:
                   1479:                rv = AcpiEnterSleepStatePrep(ACPI_STATE_S5);
                   1480:
                   1481:                if (ACPI_FAILURE(rv)) {
                   1482:                        aprint_error_dev(sc->sc_dev, "failed to prepare "
                   1483:                            "S%d: %s\n", state, AcpiFormatException(rv));
1.42      kochi    1484:                        break;
                   1485:                }
1.166     jruoho   1486:
1.104     jmcneill 1487:                DELAY(1000000);
1.166     jruoho   1488:
                   1489:                sc->sc_sleepstate = state;
1.12      kanaoka  1490:                acpi_md_OsDisableInterrupt();
1.166     jruoho   1491:
                   1492:                (void)AcpiEnterSleepState(ACPI_STATE_S5);
                   1493:
                   1494:                aprint_error_dev(sc->sc_dev, "WARNING: powerdown failed!\n");
1.10      tshiozak 1495:                break;
                   1496:        }
                   1497:
1.166     jruoho   1498:        sc->sc_sleepstate = ACPI_STATE_S0;
                   1499:
                   1500:        return rv;
1.1       thorpej  1501: }
1.13      augustss 1502:
1.159     jruoho   1503: /*
1.169     jruoho   1504:  * Sysctl.
1.159     jruoho   1505:  */
1.79      cube     1506: SYSCTL_SETUP(sysctl_acpi_setup, "sysctl hw.acpi subtree setup")
                   1507: {
1.165     jruoho   1508:        const struct sysctlnode *mnode, *rnode;
                   1509:        int err;
                   1510:
                   1511:        err = sysctl_createv(clog, 0, NULL, &rnode,
                   1512:            CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw",
                   1513:            NULL, NULL, 0, NULL, 0,
                   1514:            CTL_HW, CTL_EOL);
1.79      cube     1515:
1.165     jruoho   1516:        if (err != 0)
1.79      cube     1517:                return;
                   1518:
1.165     jruoho   1519:        err = sysctl_createv(clog, 0, &rnode, &rnode,
                   1520:            CTLFLAG_PERMANENT, CTLTYPE_NODE,
                   1521:            "acpi", SYSCTL_DESCR("ACPI subsystem parameters"),
1.79      cube     1522:            NULL, 0, NULL, 0,
1.165     jruoho   1523:            CTL_CREATE, CTL_EOL);
                   1524:
                   1525:        if (err != 0)
1.79      cube     1526:                return;
                   1527:
1.165     jruoho   1528:        (void)sysctl_createv(NULL, 0, &rnode, NULL,
                   1529:            CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
                   1530:            "root", SYSCTL_DESCR("ACPI root pointer"),
1.109     jmcneill 1531:            NULL, 0, &acpi_root_pointer, sizeof(acpi_root_pointer),
1.165     jruoho   1532:            CTL_CREATE, CTL_EOL);
                   1533:
                   1534:        (void)sysctl_createv(NULL, 0, &rnode, NULL,
                   1535:            CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_STRING,
                   1536:            "supported_states", SYSCTL_DESCR("Supported system states"),
1.166     jruoho   1537:            sysctl_hw_acpi_sleepstates, 0, NULL, 0,
1.165     jruoho   1538:            CTL_CREATE, CTL_EOL);
                   1539:
                   1540:        err = sysctl_createv(NULL, 0, NULL, &mnode,
                   1541:            CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep",
                   1542:            NULL, NULL, 0, NULL, 0,
                   1543:            CTL_MACHDEP, CTL_EOL);
1.86      jmcneill 1544:
1.165     jruoho   1545:        if (err == 0) {
                   1546:
                   1547:                (void)sysctl_createv(NULL, 0, &mnode, NULL,
                   1548:                    CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
                   1549:                    "sleep_state", SYSCTL_DESCR("System sleep state"),
                   1550:                    sysctl_hw_acpi_sleepstate, 0, NULL, 0,
                   1551:                    CTL_CREATE, CTL_EOL);
                   1552:        }
                   1553:
                   1554:        err = sysctl_createv(clog, 0, &rnode, &rnode,
                   1555:            CTLFLAG_PERMANENT, CTLTYPE_NODE,
                   1556:            "stat", SYSCTL_DESCR("ACPI statistics"),
                   1557:            NULL, 0, NULL, 0,
                   1558:            CTL_CREATE, CTL_EOL);
                   1559:
                   1560:        if (err != 0)
1.86      jmcneill 1561:                return;
1.165     jruoho   1562:
                   1563:        (void)sysctl_createv(clog, 0, &rnode, NULL,
                   1564:            CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
                   1565:            "gpe", SYSCTL_DESCR("Number of dispatched GPEs"),
                   1566:            NULL, 0, &AcpiGpeCount, sizeof(AcpiGpeCount),
                   1567:            CTL_CREATE, CTL_EOL);
                   1568:
                   1569:        (void)sysctl_createv(clog, 0, &rnode, NULL,
                   1570:            CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
                   1571:            "sci", SYSCTL_DESCR("Number of SCI interrupts"),
                   1572:            NULL, 0, &AcpiSciCount, sizeof(AcpiSciCount),
                   1573:            CTL_CREATE, CTL_EOL);
                   1574:
                   1575:        (void)sysctl_createv(clog, 0, &rnode, NULL,
                   1576:            CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
                   1577:            "fixed", SYSCTL_DESCR("Number of fixed events"),
                   1578:            sysctl_hw_acpi_fixedstats, 0, NULL, 0,
                   1579:            CTL_CREATE, CTL_EOL);
                   1580:
                   1581:        (void)sysctl_createv(clog, 0, &rnode, NULL,
                   1582:            CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
                   1583:            "method", SYSCTL_DESCR("Number of methods executed"),
                   1584:            NULL, 0, &AcpiMethodCount, sizeof(AcpiMethodCount),
                   1585:            CTL_CREATE, CTL_EOL);
                   1586:
                   1587:        CTASSERT(sizeof(AcpiGpeCount) == sizeof(uint64_t));
                   1588:        CTASSERT(sizeof(AcpiSciCount) == sizeof(uint64_t));
                   1589: }
                   1590:
                   1591: static int
                   1592: sysctl_hw_acpi_fixedstats(SYSCTLFN_ARGS)
                   1593: {
                   1594:        struct sysctlnode node;
                   1595:        uint64_t t;
                   1596:        int err, i;
                   1597:
                   1598:        for (i = t = 0; i < __arraycount(AcpiFixedEventCount); i++)
                   1599:                t += AcpiFixedEventCount[i];
                   1600:
                   1601:        node = *rnode;
                   1602:        node.sysctl_data = &t;
                   1603:
                   1604:        err = sysctl_lookup(SYSCTLFN_CALL(&node));
                   1605:
                   1606:        if (err || newp == NULL)
                   1607:                return err;
                   1608:
                   1609:        return 0;
1.86      jmcneill 1610: }
                   1611:
                   1612: static int
                   1613: sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS)
                   1614: {
1.166     jruoho   1615:        struct acpi_softc *sc = acpi_softc;
1.86      jmcneill 1616:        struct sysctlnode node;
1.165     jruoho   1617:        int err, t;
1.86      jmcneill 1618:
1.166     jruoho   1619:        if (acpi_softc == NULL)
                   1620:                return ENOSYS;
                   1621:
1.86      jmcneill 1622:        node = *rnode;
1.166     jruoho   1623:        t = sc->sc_sleepstate;
1.86      jmcneill 1624:        node.sysctl_data = &t;
1.165     jruoho   1625:
                   1626:        err = sysctl_lookup(SYSCTLFN_CALL(&node));
                   1627:
                   1628:        if (err || newp == NULL)
                   1629:                return err;
1.86      jmcneill 1630:
1.166     jruoho   1631:        if (t < ACPI_STATE_S0 || t > ACPI_STATE_S5)
                   1632:                return EINVAL;
                   1633:
                   1634:        acpi_enter_sleep_state(sc, t);
                   1635:
                   1636:        return 0;
                   1637: }
                   1638:
                   1639: static int
                   1640: sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS)
                   1641: {
                   1642:        struct acpi_softc *sc = acpi_softc;
                   1643:        struct sysctlnode node;
                   1644:        char t[3 * 6 + 1];
                   1645:        int err;
                   1646:
1.92      christos 1647:        if (acpi_softc == NULL)
                   1648:                return ENOSYS;
1.86      jmcneill 1649:
1.166     jruoho   1650:        (void)memset(t, '\0', sizeof(t));
                   1651:
                   1652:        (void)snprintf(t, sizeof(t), "%s%s%s%s%s%s",
                   1653:            ((sc->sc_sleepstates & __BIT(0)) != 0) ? "S0 " : "",
                   1654:            ((sc->sc_sleepstates & __BIT(1)) != 0) ? "S1 " : "",
                   1655:            ((sc->sc_sleepstates & __BIT(2)) != 0) ? "S2 " : "",
                   1656:            ((sc->sc_sleepstates & __BIT(3)) != 0) ? "S3 " : "",
                   1657:            ((sc->sc_sleepstates & __BIT(4)) != 0) ? "S4 " : "",
                   1658:            ((sc->sc_sleepstates & __BIT(5)) != 0) ? "S5 " : "");
                   1659:
                   1660:        node = *rnode;
                   1661:        node.sysctl_data = &t;
                   1662:
                   1663:        err = sysctl_lookup(SYSCTLFN_CALL(&node));
1.165     jruoho   1664:
1.166     jruoho   1665:        if (err || newp == NULL)
                   1666:                return err;
1.86      jmcneill 1667:
                   1668:        return 0;
1.79      cube     1669: }
1.108     jmcneill 1670:
1.169     jruoho   1671: /*
                   1672:  * Miscellaneous.
                   1673:  */
                   1674: ACPI_PHYSICAL_ADDRESS
                   1675: acpi_OsGetRootPointer(void)
                   1676: {
                   1677:        ACPI_PHYSICAL_ADDRESS PhysicalAddress;
                   1678:
                   1679:        /*
1.172     jruoho   1680:         * We let MD code handle this since there are multiple ways to do it:
1.169     jruoho   1681:         *
1.172     jruoho   1682:         *      IA-32: Use AcpiFindRootPointer() to locate the RSDP.
1.169     jruoho   1683:         *
1.172     jruoho   1684:         *      IA-64: Use the EFI.
1.169     jruoho   1685:         */
                   1686:        PhysicalAddress = acpi_md_OsGetRootPointer();
                   1687:
                   1688:        if (acpi_root_pointer == 0)
                   1689:                acpi_root_pointer = PhysicalAddress;
                   1690:
                   1691:        return PhysicalAddress;
                   1692: }
                   1693:
1.108     jmcneill 1694: static ACPI_TABLE_HEADER *
                   1695: acpi_map_rsdt(void)
                   1696: {
                   1697:        ACPI_PHYSICAL_ADDRESS paddr;
                   1698:        ACPI_TABLE_RSDP *rsdp;
                   1699:
                   1700:        paddr = AcpiOsGetRootPointer();
1.172     jruoho   1701:
                   1702:        if (paddr == 0)
1.108     jmcneill 1703:                return NULL;
1.172     jruoho   1704:
1.108     jmcneill 1705:        rsdp = AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_RSDP));
1.172     jruoho   1706:
                   1707:        if (rsdp == NULL)
1.108     jmcneill 1708:                return NULL;
1.172     jruoho   1709:
1.108     jmcneill 1710:        if (rsdp->Revision > 1 && rsdp->XsdtPhysicalAddress)
1.172     jruoho   1711:                paddr = rsdp->XsdtPhysicalAddress;
1.108     jmcneill 1712:        else
1.172     jruoho   1713:                paddr = rsdp->RsdtPhysicalAddress;
                   1714:
1.108     jmcneill 1715:        AcpiOsUnmapMemory(rsdp, sizeof(ACPI_TABLE_RSDP));
                   1716:
                   1717:        return AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_HEADER));
                   1718: }
                   1719:
                   1720: static void
                   1721: acpi_unmap_rsdt(ACPI_TABLE_HEADER *rsdt)
                   1722: {
1.172     jruoho   1723:
1.108     jmcneill 1724:        if (rsdt == NULL)
                   1725:                return;
                   1726:
                   1727:        AcpiOsUnmapMemory(rsdt, sizeof(ACPI_TABLE_HEADER));
                   1728: }

CVSweb <webmaster@jp.NetBSD.org>