xref: /netbsd-src/sys/dev/acpi/acpi.c (revision b62fc9e20372b08e1785ff6d769312d209fa2005)
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