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