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