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

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

CVSweb <webmaster@jp.NetBSD.org>