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