xref: /netbsd-src/sys/dev/acpi/acpi.c (revision 9fd8799cb5ceb66c69f2eb1a6d26a1d587ba1f1e)
1 /*	$NetBSD: acpi.c,v 1.286 2020/11/08 14:16:59 jmcneill Exp $	*/
2 
3 /*-
4  * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Charles M. Hannum of By Noon Software, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * Copyright (c) 2003 Wasabi Systems, Inc.
34  * All rights reserved.
35  *
36  * Written by Frank van der Linden for Wasabi Systems, Inc.
37  *
38  * Redistribution and use in source and binary forms, with or without
39  * modification, are permitted provided that the following conditions
40  * are met:
41  * 1. Redistributions of source code must retain the above copyright
42  *    notice, this list of conditions and the following disclaimer.
43  * 2. Redistributions in binary form must reproduce the above copyright
44  *    notice, this list of conditions and the following disclaimer in the
45  *    documentation and/or other materials provided with the distribution.
46  * 3. All advertising materials mentioning features or use of this software
47  *    must display the following acknowledgement:
48  *      This product includes software developed for the NetBSD Project by
49  *      Wasabi Systems, Inc.
50  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
51  *    or promote products derived from this software without specific prior
52  *    written permission.
53  *
54  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
55  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
56  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
58  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
59  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
60  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
61  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
62  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
63  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
64  * POSSIBILITY OF SUCH DAMAGE.
65  */
66 
67 /*
68  * Copyright 2001, 2003 Wasabi Systems, Inc.
69  * All rights reserved.
70  *
71  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
72  *
73  * Redistribution and use in source and binary forms, with or without
74  * modification, are permitted provided that the following conditions
75  * are met:
76  * 1. Redistributions of source code must retain the above copyright
77  *    notice, this list of conditions and the following disclaimer.
78  * 2. Redistributions in binary form must reproduce the above copyright
79  *    notice, this list of conditions and the following disclaimer in the
80  *    documentation and/or other materials provided with the distribution.
81  * 3. All advertising materials mentioning features or use of this software
82  *    must display the following acknowledgement:
83  *	This product includes software developed for the NetBSD Project by
84  *	Wasabi Systems, Inc.
85  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
86  *    or promote products derived from this software without specific prior
87  *    written permission.
88  *
89  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
90  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
91  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
92  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
93  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
94  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
95  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
96  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
97  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
98  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
99  * POSSIBILITY OF SUCH DAMAGE.
100  */
101 
102 #include <sys/cdefs.h>
103 __KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.286 2020/11/08 14:16:59 jmcneill Exp $");
104 
105 #include "pci.h"
106 #include "opt_acpi.h"
107 #include "opt_pcifixup.h"
108 
109 #include <sys/param.h>
110 #include <sys/device.h>
111 #include <sys/kernel.h>
112 #include <sys/kmem.h>
113 #include <sys/malloc.h>
114 #include <sys/module.h>
115 #include <sys/mutex.h>
116 #include <sys/sysctl.h>
117 #include <sys/systm.h>
118 #include <sys/timetc.h>
119 
120 #include <dev/acpi/acpireg.h>
121 #include <dev/acpi/acpivar.h>
122 #include <dev/acpi/acpi_mcfg.h>
123 #include <dev/acpi/acpi_osd.h>
124 #include <dev/acpi/acpi_pci.h>
125 #include <dev/acpi/acpi_power.h>
126 #include <dev/acpi/acpi_timer.h>
127 #include <dev/acpi/acpi_wakedev.h>
128 
129 #include <machine/acpi_machdep.h>
130 
131 #include "ioconf.h"
132 
133 #define _COMPONENT	ACPI_BUS_COMPONENT
134 ACPI_MODULE_NAME	("acpi")
135 
136 /*
137  * The acpi_active variable is set when the ACPI subsystem is active.
138  * Machine-dependent code may wish to skip other steps (such as attaching
139  * subsystems that ACPI supercedes) when ACPI is active.
140  */
141 int		acpi_active = 0;
142 int		acpi_suspended = 0;
143 int		acpi_force_load = 0;
144 int		acpi_verbose_loaded = 0;
145 
146 struct acpi_softc	*acpi_softc = NULL;
147 static uint64_t		 acpi_root_pointer;
148 extern kmutex_t		 acpi_interrupt_list_mtx;
149 static ACPI_HANDLE	 acpi_scopes[4];
150 ACPI_TABLE_HEADER	*madt_header;
151 ACPI_TABLE_HEADER	*gtdt_header;
152 
153 /*
154  * This structure provides a context for the ACPI
155  * namespace walk performed in acpi_build_tree().
156  */
157 struct acpi_walkcontext {
158 	struct acpi_softc	*aw_sc;
159 	struct acpi_devnode	*aw_parent;
160 };
161 
162 /*
163  * Ignored HIDs.
164  */
165 static const char * const acpi_ignored_ids[] = {
166 #if defined(i386) || defined(x86_64)
167 	"ACPI0007",	/* ACPI CPUs do not attach to acpi(4) */
168 	"PNP0000",	/* AT interrupt controller is handled internally */
169 	"PNP0001",	/* EISA interrupt controller is handled internally */
170 	"PNP0200",	/* AT DMA controller is handled internally */
171 	"PNP0A??",	/* PCI Busses are handled internally */
172 	"PNP0B00",	/* AT RTC is handled internally */
173 	"PNP0C02",	/* PnP motherboard resources */
174 	"PNP0C0F",	/* ACPI PCI link devices are handled internally */
175 #endif
176 #if defined(x86_64)
177 	"PNP0C04",	/* FPU is handled internally */
178 #endif
179 #if defined(__aarch64__)
180 	"ACPI0004",	/* ACPI module devices are handled internally */
181 	"ACPI0007",	/* ACPI CPUs are attached via MADT GICC subtables */
182 	"PNP0C0F",	/* ACPI PCI link devices are handled internally */
183 #endif
184 	NULL
185 };
186 
187 /*
188  * Devices that should be attached early.
189  */
190 static const char * const acpi_early_ids[] = {
191 	"PNP0C09",	/* acpiec(4) */
192 	NULL
193 };
194 
195 static int		acpi_match(device_t, cfdata_t, void *);
196 static int		acpi_submatch(device_t, cfdata_t, const int *, void *);
197 static void		acpi_attach(device_t, device_t, void *);
198 static int		acpi_detach(device_t, int);
199 static void		acpi_childdet(device_t, device_t);
200 static bool		acpi_suspend(device_t, const pmf_qual_t *);
201 static bool		acpi_resume(device_t, const pmf_qual_t *);
202 
203 static void		acpi_build_tree(struct acpi_softc *);
204 static void		acpi_config_tree(struct acpi_softc *);
205 static void		acpi_config_dma(struct acpi_softc *);
206 static ACPI_STATUS	acpi_make_devnode(ACPI_HANDLE, uint32_t,
207 					  void *, void **);
208 static ACPI_STATUS	acpi_make_devnode_post(ACPI_HANDLE, uint32_t,
209 					       void *, void **);
210 static void		acpi_make_name(struct acpi_devnode *, uint32_t);
211 
212 static int		acpi_rescan(device_t, const char *, const int *);
213 static void		acpi_rescan_early(struct acpi_softc *);
214 static void		acpi_rescan_nodes(struct acpi_softc *);
215 static void		acpi_rescan_capabilities(device_t);
216 static int		acpi_print(void *aux, const char *);
217 
218 static void		acpi_notify_handler(ACPI_HANDLE, uint32_t, void *);
219 
220 static void		acpi_register_fixed_button(struct acpi_softc *, int);
221 static void		acpi_deregister_fixed_button(struct acpi_softc *, int);
222 static uint32_t		acpi_fixed_button_handler(void *);
223 static void		acpi_fixed_button_pressed(void *);
224 
225 static void		acpi_sleep_init(struct acpi_softc *);
226 
227 static int		sysctl_hw_acpi_fixedstats(SYSCTLFN_PROTO);
228 static int		sysctl_hw_acpi_sleepstate(SYSCTLFN_PROTO);
229 static int		sysctl_hw_acpi_sleepstates(SYSCTLFN_PROTO);
230 
231 static bool		  acpi_is_scope(struct acpi_devnode *);
232 static ACPI_TABLE_HEADER *acpi_map_rsdt(void);
233 static void		  acpi_unmap_rsdt(ACPI_TABLE_HEADER *);
234 
235 void			acpi_print_verbose_stub(struct acpi_softc *);
236 void			acpi_print_dev_stub(const char *);
237 
238 static void		acpi_activate_device(ACPI_HANDLE, ACPI_DEVICE_INFO **);
239 ACPI_STATUS		acpi_allocate_resources(ACPI_HANDLE);
240 
241 void (*acpi_print_verbose)(struct acpi_softc *) = acpi_print_verbose_stub;
242 void (*acpi_print_dev)(const char *) = acpi_print_dev_stub;
243 
244 bus_dma_tag_t		acpi_default_dma_tag(struct acpi_softc *, struct acpi_devnode *);
245 bus_dma_tag_t		acpi_default_dma64_tag(struct acpi_softc *, struct acpi_devnode *);
246 pci_chipset_tag_t	acpi_default_pci_chipset_tag(struct acpi_softc *, int, int);
247 
248 CFATTACH_DECL2_NEW(acpi, sizeof(struct acpi_softc),
249     acpi_match, acpi_attach, acpi_detach, NULL, acpi_rescan, acpi_childdet);
250 
251 /*
252  * Probe for ACPI support.
253  *
254  * This is called by the machine-dependent ACPI front-end.
255  * Note: this is not an autoconfiguration interface function.
256  */
257 int
258 acpi_probe(void)
259 {
260 	ACPI_TABLE_HEADER *rsdt;
261 	ACPI_STATUS rv;
262 	int quirks;
263 
264 	if (acpi_softc != NULL)
265 		panic("%s: already probed", __func__);
266 
267 	mutex_init(&acpi_interrupt_list_mtx, MUTEX_DEFAULT, IPL_NONE);
268 
269 	/*
270 	 * Start up ACPICA.
271 	 */
272 	AcpiGbl_EnableInterpreterSlack = true;
273 
274 	rv = AcpiInitializeSubsystem();
275 
276 	if (ACPI_FAILURE(rv)) {
277 		aprint_error("%s: failed to initialize subsystem\n", __func__);
278 		return 0;
279 	}
280 
281 	/*
282 	 * Allocate space for RSDT/XSDT and DSDT,
283 	 * but allow resizing if more tables exist.
284 	 */
285 	rv = AcpiInitializeTables(NULL, 2, true);
286 
287 	if (ACPI_FAILURE(rv)) {
288 		aprint_error("%s: failed to initialize tables\n", __func__);
289 		goto fail;
290 	}
291 
292 	rv = AcpiLoadTables();
293 
294 	if (ACPI_FAILURE(rv)) {
295 		aprint_error("%s: failed to load tables\n", __func__);
296 		goto fail;
297 	}
298 
299 	rsdt = acpi_map_rsdt();
300 
301 	if (rsdt == NULL) {
302 		aprint_error("%s: failed to map RSDT\n", __func__);
303 		goto fail;
304 	}
305 
306 	quirks = acpi_find_quirks();
307 
308 	if (acpi_force_load == 0 && (quirks & ACPI_QUIRK_BROKEN) != 0) {
309 
310 		aprint_normal("ACPI: BIOS is listed as broken:\n");
311 		aprint_normal("ACPI: X/RSDT: OemId <%6.6s,%8.8s,%08x>, "
312 		       "AslId <%4.4s,%08x>\n", rsdt->OemId, rsdt->OemTableId,
313 		        rsdt->OemRevision, rsdt->AslCompilerId,
314 		        rsdt->AslCompilerRevision);
315 		aprint_normal("ACPI: Not used. Set acpi_force_load to use.\n");
316 
317 		acpi_unmap_rsdt(rsdt);
318 		goto fail;
319 	}
320 
321 	if (acpi_force_load == 0 && (quirks & ACPI_QUIRK_OLDBIOS) != 0) {
322 
323 		aprint_normal("ACPI: BIOS is too old (%s). "
324 		    "Set acpi_force_load to use.\n",
325 		    pmf_get_platform("bios-date"));
326 
327 		acpi_unmap_rsdt(rsdt);
328 		goto fail;
329 	}
330 
331 	acpi_unmap_rsdt(rsdt);
332 
333 	rv = AcpiEnableSubsystem(~(ACPI_NO_HARDWARE_INIT|ACPI_NO_ACPI_ENABLE));
334 
335 	if (ACPI_FAILURE(rv)) {
336 		aprint_error("%s: failed to enable subsystem\n", __func__);
337 		goto fail;
338 	}
339 
340 	return 1;
341 
342 fail:
343 	(void)AcpiTerminate();
344 
345 	return 0;
346 }
347 
348 void
349 acpi_disable(void)
350 {
351 
352 	if (acpi_softc == NULL)
353 		return;
354 
355 	KASSERT(acpi_active != 0);
356 
357 	if (AcpiGbl_FADT.SmiCommand != 0)
358 		AcpiDisable();
359 }
360 
361 int
362 acpi_check(device_t parent, const char *ifattr)
363 {
364 	return (config_search_ia(acpi_submatch, parent, ifattr, NULL) != NULL);
365 }
366 
367 int
368 acpi_reset(void)
369 {
370 	struct acpi_softc *sc = acpi_softc;
371 	ACPI_GENERIC_ADDRESS *ResetReg;
372 	ACPI_PCI_ID PciId;
373 	ACPI_STATUS status;
374 
375 	if (sc == NULL)
376 		return ENXIO;
377 
378 	ResetReg = &AcpiGbl_FADT.ResetRegister;
379 
380 	/* Check if the reset register is supported */
381 	if (!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER) ||
382 	    !ResetReg->Address) {
383 		return ENOENT;
384 	}
385 
386 	switch (ResetReg->SpaceId) {
387 	case ACPI_ADR_SPACE_PCI_CONFIG:
388 		PciId.Segment = PciId.Bus = 0;
389 		PciId.Device = ACPI_GAS_PCI_DEV(ResetReg->Address);
390 		PciId.Function = ACPI_GAS_PCI_FUNC(ResetReg->Address);
391 		status = AcpiOsWritePciConfiguration(&PciId,
392 		    ACPI_GAS_PCI_REGOFF(ResetReg->Address),
393 		    AcpiGbl_FADT.ResetValue, ResetReg->BitWidth);
394 		break;
395 	case ACPI_ADR_SPACE_SYSTEM_IO:
396 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
397 		status = AcpiReset();
398 		break;
399 	default:
400 		status = AE_TYPE;
401 		break;
402 	}
403 
404 	return ACPI_FAILURE(status) ? EIO : 0;
405 }
406 
407 /*
408  * Autoconfiguration.
409  */
410 static int
411 acpi_match(device_t parent, cfdata_t match, void *aux)
412 {
413 	/*
414 	 * XXX: Nada; MD code has called acpi_probe().
415 	 */
416 	return 1;
417 }
418 
419 static int
420 acpi_submatch(device_t parent, cfdata_t cf, const int *locs, void *aux)
421 {
422 	struct cfattach *ca;
423 
424 	ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname);
425 
426 	return (ca == &acpi_ca);
427 }
428 
429 static void
430 acpi_attach(device_t parent, device_t self, void *aux)
431 {
432 	struct acpi_softc *sc = device_private(self);
433 	struct acpibus_attach_args *aa = aux;
434 	ACPI_TABLE_HEADER *rsdt;
435 	ACPI_STATUS rv;
436 
437 	aprint_naive("\n");
438 	aprint_normal(": Intel ACPICA %08x\n", ACPI_CA_VERSION);
439 
440 	if (acpi_softc != NULL)
441 		panic("%s: already attached", __func__);
442 
443 	rsdt = acpi_map_rsdt();
444 
445 	if (rsdt == NULL)
446 		aprint_error_dev(self, "X/RSDT: Not found\n");
447 	else {
448 		aprint_verbose_dev(self,
449 		    "X/RSDT: OemId <%6.6s,%8.8s,%08x>, AslId <%4.4s,%08x>\n",
450 		    rsdt->OemId, rsdt->OemTableId,
451 		    rsdt->OemRevision,
452 		    rsdt->AslCompilerId, rsdt->AslCompilerRevision);
453 	}
454 
455 	acpi_unmap_rsdt(rsdt);
456 
457 	sc->sc_dev = self;
458 	sc->sc_root = NULL;
459 
460 	sc->sc_sleepstate = ACPI_STATE_S0;
461 	sc->sc_quirks = acpi_find_quirks();
462 
463 	sysmon_power_settype("acpi");
464 
465 	sc->sc_iot = aa->aa_iot;
466 	sc->sc_memt = aa->aa_memt;
467 	sc->sc_pciflags = aa->aa_pciflags;
468 	sc->sc_ic = aa->aa_ic;
469 	sc->sc_dmat = aa->aa_dmat;
470 	sc->sc_dmat64 = aa->aa_dmat64;
471 
472 	SIMPLEQ_INIT(&sc->ad_head);
473 
474 	acpi_softc = sc;
475 
476 	if (pmf_device_register(self, acpi_suspend, acpi_resume) != true)
477 		aprint_error_dev(self, "couldn't establish power handler\n");
478 
479 	/*
480 	 * Bring ACPICA on-line.
481 	 */
482 
483 	rv = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION);
484 
485 	if (ACPI_FAILURE(rv))
486 		goto fail;
487 
488 	/*
489 	 * Early initialization of acpiec(4) via ECDT.
490 	 */
491 	(void)config_found_ia(self, "acpiecdtbus", aa, NULL);
492 
493 	rv = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION);
494 
495 	if (ACPI_FAILURE(rv))
496 		goto fail;
497 
498 	/*
499 	 * Scan the namespace and build our device tree.
500 	 */
501 	acpi_build_tree(sc);
502 
503 #if NPCI > 0
504 	/*
505 	 * Probe MCFG table
506 	 */
507 	acpimcfg_probe(sc);
508 #endif
509 
510 	acpi_md_callback(sc);
511 
512 	/*
513 	 * Early initialization of the _PDC control method
514 	 * that may load additional SSDT tables dynamically.
515 	 */
516 	(void)acpi_md_pdc();
517 
518 	/*
519 	 * Install global notify handlers.
520 	 */
521 	rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT,
522 	    ACPI_SYSTEM_NOTIFY, acpi_notify_handler, NULL);
523 
524 	if (ACPI_FAILURE(rv))
525 		goto fail;
526 
527 	rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT,
528 	    ACPI_DEVICE_NOTIFY, acpi_notify_handler, NULL);
529 
530 	if (ACPI_FAILURE(rv))
531 		goto fail;
532 
533 	acpi_active = 1;
534 
535 	if (!AcpiGbl_ReducedHardware) {
536 		/* Show SCI interrupt. */
537 		aprint_verbose_dev(self, "SCI interrupting at int %u\n",
538 		    AcpiGbl_FADT.SciInterrupt);
539 
540 		/*
541 		 * Install fixed-event handlers.
542 		 */
543 		acpi_register_fixed_button(sc, ACPI_EVENT_POWER_BUTTON);
544 		acpi_register_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON);
545 	}
546 
547 	acpitimer_init(sc);
548 	acpi_config_tree(sc);
549 	acpi_sleep_init(sc);
550 
551 #ifdef ACPI_DEBUG
552 	acpi_debug_init();
553 #endif
554 
555 	/*
556 	 * Print debug information.
557 	 */
558 	acpi_print_verbose(sc);
559 
560 	return;
561 
562 fail:
563 	aprint_error("%s: failed to initialize ACPI: %s\n",
564 	    __func__, AcpiFormatException(rv));
565 }
566 
567 /*
568  * XXX: This is incomplete.
569  */
570 static int
571 acpi_detach(device_t self, int flags)
572 {
573 	struct acpi_softc *sc = device_private(self);
574 	ACPI_STATUS rv;
575 	int rc;
576 
577 	rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT,
578 	    ACPI_SYSTEM_NOTIFY, acpi_notify_handler);
579 
580 	if (ACPI_FAILURE(rv))
581 		return EBUSY;
582 
583 	rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT,
584 	    ACPI_DEVICE_NOTIFY, acpi_notify_handler);
585 
586 	if (ACPI_FAILURE(rv))
587 		return EBUSY;
588 
589 	if ((rc = config_detach_children(self, flags)) != 0)
590 		return rc;
591 
592 	if ((rc = acpitimer_detach()) != 0)
593 		return rc;
594 
595 	if (!AcpiGbl_ReducedHardware) {
596 		acpi_deregister_fixed_button(sc, ACPI_EVENT_POWER_BUTTON);
597 		acpi_deregister_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON);
598 	}
599 
600 	pmf_device_deregister(self);
601 
602 	acpi_softc = NULL;
603 
604 	return 0;
605 }
606 
607 static void
608 acpi_childdet(device_t self, device_t child)
609 {
610 	struct acpi_softc *sc = device_private(self);
611 	struct acpi_devnode *ad;
612 
613 	if (sc->sc_apmbus == child)
614 		sc->sc_apmbus = NULL;
615 
616 	if (sc->sc_hpet == child)
617 		sc->sc_hpet = NULL;
618 
619 	if (sc->sc_wdrt == child)
620 		sc->sc_wdrt = NULL;
621 
622 	SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
623 
624 		if (ad->ad_device == child)
625 			ad->ad_device = NULL;
626 	}
627 }
628 
629 static bool
630 acpi_suspend(device_t dv, const pmf_qual_t *qual)
631 {
632 
633 	acpi_suspended = 1;
634 
635 	return true;
636 }
637 
638 static bool
639 acpi_resume(device_t dv, const pmf_qual_t *qual)
640 {
641 
642 	acpi_suspended = 0;
643 
644 	return true;
645 }
646 
647 /*
648  * Namespace scan.
649  */
650 static void
651 acpi_build_tree(struct acpi_softc *sc)
652 {
653 	struct acpi_walkcontext awc;
654 
655 	/*
656 	 * Get the root scope handles.
657 	 */
658 	KASSERT(__arraycount(acpi_scopes) == 4);
659 
660 	(void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_PR_", &acpi_scopes[0]);
661 	(void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &acpi_scopes[1]);
662 	(void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SI_", &acpi_scopes[2]);
663 	(void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_TZ_", &acpi_scopes[3]);
664 
665 	/*
666 	 * Make the root node.
667 	 */
668 	awc.aw_sc = sc;
669 	awc.aw_parent = NULL;
670 
671 	(void)acpi_make_devnode(ACPI_ROOT_OBJECT, 0, &awc, NULL);
672 
673 	KASSERT(sc->sc_root == NULL);
674 	KASSERT(awc.aw_parent != NULL);
675 
676 	sc->sc_root = awc.aw_parent;
677 
678 	/*
679 	 * Build the internal namespace.
680 	 */
681 	(void)AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, UINT32_MAX,
682 	    acpi_make_devnode, acpi_make_devnode_post, &awc, NULL);
683 
684 	/*
685 	 * Scan the internal namespace.
686 	 */
687 	(void)acpi_pcidev_scan(sc->sc_root);
688 }
689 
690 static void
691 acpi_config_tree(struct acpi_softc *sc)
692 {
693 	/*
694 	 * Assign bus_dma resources
695 	 */
696 	acpi_config_dma(sc);
697 
698 	/*
699 	 * Configure all everything found "at acpi?".
700 	 */
701 	(void)acpi_rescan(sc->sc_dev, NULL, NULL);
702 
703 	/*
704 	 * Update GPE information.
705 	 *
706 	 * Note that this must be called after
707 	 * all GPE handlers have been installed.
708 	 */
709 	(void)AcpiUpdateAllGpes();
710 
711 	/*
712 	 * Defer rest of the configuration.
713 	 */
714 	(void)config_defer(sc->sc_dev, acpi_rescan_capabilities);
715 }
716 
717 static void
718 acpi_config_dma(struct acpi_softc *sc)
719 {
720 	struct acpi_devnode *ad;
721 
722 	SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
723 
724 		if (ad->ad_device != NULL)
725 			continue;
726 
727 		if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE)
728 			continue;
729 
730 		ad->ad_dmat = acpi_get_dma_tag(sc, ad);
731 		ad->ad_dmat64 = acpi_get_dma64_tag(sc, ad);
732 	}
733 }
734 
735 static ACPI_STATUS
736 acpi_make_devnode(ACPI_HANDLE handle, uint32_t level,
737     void *context, void **status)
738 {
739 	struct acpi_walkcontext *awc = context;
740 	struct acpi_softc *sc = awc->aw_sc;
741 	struct acpi_devnode *ad;
742 	ACPI_DEVICE_INFO *devinfo;
743 	ACPI_OBJECT_TYPE type;
744 	ACPI_STATUS rv;
745 
746 	rv = AcpiGetObjectInfo(handle, &devinfo);
747 
748 	if (ACPI_FAILURE(rv))
749 		return AE_OK;	/* Do not terminate the walk. */
750 
751 	type = devinfo->Type;
752 
753 	switch (type) {
754 
755 	case ACPI_TYPE_DEVICE:
756 		acpi_activate_device(handle, &devinfo);
757 		/* FALLTHROUGH */
758 
759 	case ACPI_TYPE_PROCESSOR:
760 	case ACPI_TYPE_THERMAL:
761 	case ACPI_TYPE_POWER:
762 
763 		ad = kmem_zalloc(sizeof(*ad), KM_SLEEP);
764 
765 		ad->ad_device = NULL;
766 		ad->ad_notify = NULL;
767 		ad->ad_pciinfo = NULL;
768 		ad->ad_wakedev = NULL;
769 
770 		ad->ad_type = type;
771 		ad->ad_handle = handle;
772 		ad->ad_devinfo = devinfo;
773 
774 		ad->ad_root = sc->sc_dev;
775 		ad->ad_parent = awc->aw_parent;
776 
777 		acpi_match_node_init(ad);
778 		acpi_make_name(ad, devinfo->Name);
779 
780 		/*
781 		 * Identify wake GPEs from the _PRW. Note that
782 		 * AcpiUpdateAllGpes() must be called afterwards.
783 		 */
784 		if (ad->ad_devinfo->Type == ACPI_TYPE_DEVICE)
785 			acpi_wakedev_init(ad);
786 
787 		SIMPLEQ_INIT(&ad->ad_child_head);
788 		SIMPLEQ_INSERT_TAIL(&sc->ad_head, ad, ad_list);
789 
790 		if (ad->ad_parent != NULL) {
791 
792 			SIMPLEQ_INSERT_TAIL(&ad->ad_parent->ad_child_head,
793 			    ad, ad_child_list);
794 		}
795 
796 		awc->aw_parent = ad;
797 		break;
798 
799 	default:
800 		ACPI_FREE(devinfo);
801 		break;
802 	}
803 
804 	return AE_OK;
805 }
806 
807 static ACPI_STATUS
808 acpi_make_devnode_post(ACPI_HANDLE handle, uint32_t level,
809     void *context, void **status)
810 {
811 	struct acpi_walkcontext *awc = context;
812 
813 	KASSERT(awc != NULL);
814 	KASSERT(awc->aw_parent != NULL);
815 
816 	if (handle == awc->aw_parent->ad_handle)
817 		awc->aw_parent = awc->aw_parent->ad_parent;
818 
819 	return AE_OK;
820 }
821 
822 static void
823 acpi_make_name(struct acpi_devnode *ad, uint32_t name)
824 {
825 	ACPI_NAME_UNION *anu;
826 	int clear, i;
827 
828 	anu = (ACPI_NAME_UNION *)&name;
829 	ad->ad_name[4] = '\0';
830 
831 	for (i = 3, clear = 0; i >= 0; i--) {
832 
833 		if (clear == 0 && anu->Ascii[i] == '_')
834 			ad->ad_name[i] = '\0';
835 		else {
836 			ad->ad_name[i] = anu->Ascii[i];
837 			clear = 1;
838 		}
839 	}
840 
841 	if (ad->ad_name[0] == '\0')
842 		ad->ad_name[0] = '_';
843 }
844 
845 bus_dma_tag_t
846 acpi_default_dma_tag(struct acpi_softc *sc, struct acpi_devnode *ad)
847 {
848 	return sc->sc_dmat;
849 }
850 __weak_alias(acpi_get_dma_tag,acpi_default_dma_tag);
851 
852 bus_dma_tag_t
853 acpi_default_dma64_tag(struct acpi_softc *sc, struct acpi_devnode *ad)
854 {
855 	return sc->sc_dmat64;
856 }
857 __weak_alias(acpi_get_dma64_tag,acpi_default_dma64_tag);
858 
859 pci_chipset_tag_t
860 acpi_default_pci_chipset_tag(struct acpi_softc *sc, int seg, int bbn)
861 {
862 	return NULL;
863 }
864 __weak_alias(acpi_get_pci_chipset_tag,acpi_default_pci_chipset_tag);
865 
866 /*
867  * Device attachment.
868  */
869 static int
870 acpi_rescan(device_t self, const char *ifattr, const int *locators)
871 {
872 	struct acpi_softc *sc = device_private(self);
873 	struct acpi_attach_args aa;
874 
875 	/*
876 	 * Try to attach hpet(4) first via a specific table.
877 	 */
878 	aa.aa_memt = sc->sc_memt;
879 
880 	if (ifattr_match(ifattr, "acpihpetbus") && sc->sc_hpet == NULL)
881 		sc->sc_hpet = config_found_ia(sc->sc_dev,
882 		    "acpihpetbus", &aa, NULL);
883 
884 	/*
885 	 * A two-pass scan for acpinodebus.
886 	 */
887 	if (ifattr_match(ifattr, "acpinodebus")) {
888 		acpi_rescan_early(sc);
889 		acpi_rescan_nodes(sc);
890 	}
891 
892 	/*
893 	 * Attach APM emulation and acpiwdrt(4).
894 	 */
895 	if (ifattr_match(ifattr, "acpiapmbus") && sc->sc_apmbus == NULL)
896 		sc->sc_apmbus = config_found_ia(sc->sc_dev,
897 		    "acpiapmbus", NULL, NULL);
898 
899 	if (ifattr_match(ifattr, "acpiwdrtbus") && sc->sc_wdrt == NULL)
900 		sc->sc_wdrt = config_found_ia(sc->sc_dev,
901 		    "acpiwdrtbus", NULL, NULL);
902 
903 	return 0;
904 }
905 
906 static void
907 acpi_rescan_early(struct acpi_softc *sc)
908 {
909 	struct acpi_attach_args aa;
910 	struct acpi_devnode *ad;
911 
912 	/*
913 	 * First scan for devices such as acpiec(4) that
914 	 * should be always attached before anything else.
915 	 * We want these devices to attach regardless of
916 	 * the device status and other restrictions.
917 	 */
918 	SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
919 
920 		if (ad->ad_device != NULL)
921 			continue;
922 
923 		if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE)
924 			continue;
925 
926 		if (acpi_match_hid(ad->ad_devinfo, acpi_early_ids) == 0)
927 			continue;
928 
929 		aa.aa_node = ad;
930 		aa.aa_iot = sc->sc_iot;
931 		aa.aa_memt = sc->sc_memt;
932 		if (ad->ad_pciinfo != NULL) {
933 			aa.aa_pc = ad->ad_pciinfo->ap_pc;
934 			aa.aa_pciflags = sc->sc_pciflags;
935 		}
936 		aa.aa_ic = sc->sc_ic;
937 		aa.aa_dmat = ad->ad_dmat;
938 		aa.aa_dmat64 = ad->ad_dmat64;
939 
940 		ad->ad_device = config_found_ia(sc->sc_dev,
941 		    "acpinodebus", &aa, acpi_print);
942 	}
943 }
944 
945 static void
946 acpi_rescan_nodes(struct acpi_softc *sc)
947 {
948 	const char * const hpet_ids[] = { "PNP0103", NULL };
949 	struct acpi_attach_args aa;
950 	struct acpi_devnode *ad;
951 	ACPI_DEVICE_INFO *di;
952 
953 	SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
954 
955 		if (ad->ad_device != NULL)
956 			continue;
957 
958 		/*
959 		 * There is a bug in ACPICA: it defines the type
960 		 * of the scopes incorrectly for its own reasons.
961 		 */
962 		if (acpi_is_scope(ad) != false)
963 			continue;
964 
965 		di = ad->ad_devinfo;
966 
967 		/*
968 		 * We only attach devices which are present, enabled, and
969 		 * functioning properly. However, if a device is enabled,
970 		 * it is decoding resources and we should claim these,
971 		 * if possible. This requires changes to bus_space(9).
972 		 */
973 		if (di->Type == ACPI_TYPE_DEVICE &&
974 		    !acpi_device_present(ad->ad_handle)) {
975 			continue;
976 		}
977 
978 		if (di->Type == ACPI_TYPE_POWER)
979 			continue;
980 
981 		if (di->Type == ACPI_TYPE_PROCESSOR)
982 			continue;
983 
984 		if (acpi_match_hid(di, acpi_early_ids) != 0)
985 			continue;
986 
987 		if (acpi_match_hid(di, acpi_ignored_ids) != 0)
988 			continue;
989 
990 		if (acpi_match_hid(di, hpet_ids) != 0 && sc->sc_hpet != NULL)
991 			continue;
992 
993 		aa.aa_node = ad;
994 		aa.aa_iot = sc->sc_iot;
995 		aa.aa_memt = sc->sc_memt;
996 		if (ad->ad_pciinfo != NULL) {
997 			aa.aa_pc = ad->ad_pciinfo->ap_pc;
998 			aa.aa_pciflags = sc->sc_pciflags;
999 		}
1000 		aa.aa_ic = sc->sc_ic;
1001 		aa.aa_dmat = ad->ad_dmat;
1002 		aa.aa_dmat64 = ad->ad_dmat64;
1003 
1004 		ad->ad_device = config_found_ia(sc->sc_dev,
1005 		    "acpinodebus", &aa, acpi_print);
1006 	}
1007 }
1008 
1009 static void
1010 acpi_rescan_capabilities(device_t self)
1011 {
1012 	struct acpi_softc *sc = device_private(self);
1013 	struct acpi_devnode *ad;
1014 	ACPI_HANDLE tmp;
1015 	ACPI_STATUS rv;
1016 
1017 	SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
1018 
1019 		if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE)
1020 			continue;
1021 
1022 		/*
1023 		 * Scan power resource capabilities.
1024 		 *
1025 		 * If any power states are supported,
1026 		 * at least _PR0 and _PR3 must be present.
1027 		 */
1028 		rv = AcpiGetHandle(ad->ad_handle, "_PR0", &tmp);
1029 
1030 		if (ACPI_SUCCESS(rv)) {
1031 			ad->ad_flags |= ACPI_DEVICE_POWER;
1032 			acpi_power_add(ad);
1033 		}
1034 
1035 		/*
1036 		 * Scan wake-up capabilities.
1037 		 */
1038 		if (ad->ad_wakedev != NULL) {
1039 			ad->ad_flags |= ACPI_DEVICE_WAKEUP;
1040 			acpi_wakedev_add(ad);
1041 		}
1042 
1043 		/*
1044 		 * Scan docking stations.
1045 		 */
1046 		rv = AcpiGetHandle(ad->ad_handle, "_DCK", &tmp);
1047 
1048 		if (ACPI_SUCCESS(rv))
1049 			ad->ad_flags |= ACPI_DEVICE_DOCK;
1050 
1051 		/*
1052 		 * Scan devices that are ejectable.
1053 		 */
1054 		rv = AcpiGetHandle(ad->ad_handle, "_EJ0", &tmp);
1055 
1056 		if (ACPI_SUCCESS(rv))
1057 			ad->ad_flags |= ACPI_DEVICE_EJECT;
1058 	}
1059 }
1060 
1061 static int
1062 acpi_print(void *aux, const char *pnp)
1063 {
1064 	struct acpi_attach_args *aa = aux;
1065 	struct acpi_devnode *ad;
1066 	const char *hid, *uid;
1067 	ACPI_DEVICE_INFO *di;
1068 
1069 	ad = aa->aa_node;
1070 	di = ad->ad_devinfo;
1071 
1072 	hid = di->HardwareId.String;
1073 	uid = di->UniqueId.String;
1074 
1075 	if (pnp != NULL) {
1076 
1077 		if (di->Type != ACPI_TYPE_DEVICE) {
1078 
1079 			aprint_normal("%s (ACPI Object Type '%s') at %s",
1080 			    ad->ad_name, AcpiUtGetTypeName(ad->ad_type), pnp);
1081 
1082 			return UNCONF;
1083 		}
1084 
1085 		if ((di->Valid & ACPI_VALID_HID) == 0 || hid == NULL)
1086 			return 0;
1087 
1088 		aprint_normal("%s (%s) ", ad->ad_name, hid);
1089 		acpi_print_dev(hid);
1090 		aprint_normal("at %s", pnp);
1091 
1092 		return UNCONF;
1093 	}
1094 
1095 	aprint_normal(" (%s", ad->ad_name);
1096 
1097 	if ((di->Valid & ACPI_VALID_HID) != 0 && hid != NULL) {
1098 
1099 		aprint_normal(", %s", hid);
1100 
1101 		if ((di->Valid & ACPI_VALID_UID) != 0 && uid != NULL) {
1102 
1103 			if (uid[0] == '\0')
1104 				uid = "<null>";
1105 
1106 			aprint_normal("-%s", uid);
1107 		}
1108 	}
1109 
1110 	aprint_normal(")");
1111 
1112 	return UNCONF;
1113 }
1114 
1115 /*
1116  * Notify.
1117  */
1118 static void
1119 acpi_notify_handler(ACPI_HANDLE handle, uint32_t event, void *aux)
1120 {
1121 	struct acpi_softc *sc = acpi_softc;
1122 	struct acpi_devnode *ad;
1123 
1124 	KASSERT(sc != NULL);
1125 	KASSERT(aux == NULL);
1126 	KASSERT(acpi_active != 0);
1127 
1128 	if (acpi_suspended != 0)
1129 		return;
1130 
1131 	/*
1132 	 *  System: 0x00 - 0x7F.
1133 	 *  Device: 0x80 - 0xFF.
1134 	 */
1135 	switch (event) {
1136 
1137 	case ACPI_NOTIFY_BUS_CHECK:
1138 	case ACPI_NOTIFY_DEVICE_CHECK:
1139 	case ACPI_NOTIFY_DEVICE_WAKE:
1140 	case ACPI_NOTIFY_EJECT_REQUEST:
1141 	case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
1142 	case ACPI_NOTIFY_FREQUENCY_MISMATCH:
1143 	case ACPI_NOTIFY_BUS_MODE_MISMATCH:
1144 	case ACPI_NOTIFY_POWER_FAULT:
1145 	case ACPI_NOTIFY_CAPABILITIES_CHECK:
1146 	case ACPI_NOTIFY_DEVICE_PLD_CHECK:
1147 	case ACPI_NOTIFY_RESERVED:
1148 	case ACPI_NOTIFY_LOCALITY_UPDATE:
1149 		break;
1150 	}
1151 
1152 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "notification 0x%02X for "
1153 		"%s (%p)\n", event, acpi_name(handle), handle));
1154 
1155 	/*
1156 	 * We deliver notifications only to drivers
1157 	 * that have been successfully attached and
1158 	 * that have registered a handler with us.
1159 	 * The opaque pointer is always the device_t.
1160 	 */
1161 	SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
1162 
1163 		if (ad->ad_device == NULL)
1164 			continue;
1165 
1166 		if (ad->ad_notify == NULL)
1167 			continue;
1168 
1169 		if (ad->ad_handle != handle)
1170 			continue;
1171 
1172 		(*ad->ad_notify)(ad->ad_handle, event, ad->ad_device);
1173 
1174 		return;
1175 	}
1176 
1177 	aprint_debug_dev(sc->sc_dev, "unhandled notify 0x%02X "
1178 	    "for %s (%p)\n", event, acpi_name(handle), handle);
1179 }
1180 
1181 bool
1182 acpi_register_notify(struct acpi_devnode *ad, ACPI_NOTIFY_HANDLER notify)
1183 {
1184 	struct acpi_softc *sc = acpi_softc;
1185 
1186 	KASSERT(sc != NULL);
1187 	KASSERT(acpi_active != 0);
1188 
1189 	if (acpi_suspended != 0)
1190 		goto fail;
1191 
1192 	if (ad == NULL || notify == NULL)
1193 		goto fail;
1194 
1195 	ad->ad_notify = notify;
1196 
1197 	return true;
1198 
1199 fail:
1200 	aprint_error_dev(sc->sc_dev, "failed to register notify "
1201 	    "handler for %s (%p)\n", ad->ad_name, ad->ad_handle);
1202 
1203 	return false;
1204 }
1205 
1206 void
1207 acpi_deregister_notify(struct acpi_devnode *ad)
1208 {
1209 
1210 	ad->ad_notify = NULL;
1211 }
1212 
1213 /*
1214  * Fixed buttons.
1215  */
1216 static void
1217 acpi_register_fixed_button(struct acpi_softc *sc, int event)
1218 {
1219 	struct sysmon_pswitch *smpsw;
1220 	ACPI_STATUS rv;
1221 	int type;
1222 
1223 	switch (event) {
1224 
1225 	case ACPI_EVENT_POWER_BUTTON:
1226 
1227 		if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) != 0)
1228 			return;
1229 
1230 		type = PSWITCH_TYPE_POWER;
1231 		smpsw = &sc->sc_smpsw_power;
1232 		break;
1233 
1234 	case ACPI_EVENT_SLEEP_BUTTON:
1235 
1236 		if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) != 0)
1237 			return;
1238 
1239 		type = PSWITCH_TYPE_SLEEP;
1240 		smpsw = &sc->sc_smpsw_sleep;
1241 		break;
1242 
1243 	default:
1244 		rv = AE_TYPE;
1245 		goto fail;
1246 	}
1247 
1248 	smpsw->smpsw_type = type;
1249 	smpsw->smpsw_name = device_xname(sc->sc_dev);
1250 
1251 	if (sysmon_pswitch_register(smpsw) != 0) {
1252 		rv = AE_ERROR;
1253 		goto fail;
1254 	}
1255 
1256 	AcpiClearEvent(event);
1257 
1258 	rv = AcpiInstallFixedEventHandler(event,
1259 	    acpi_fixed_button_handler, smpsw);
1260 
1261 	if (ACPI_FAILURE(rv)) {
1262 		sysmon_pswitch_unregister(smpsw);
1263 		goto fail;
1264 	}
1265 
1266 	aprint_normal_dev(sc->sc_dev, "fixed %s button present\n",
1267 	    (type != PSWITCH_TYPE_SLEEP) ? "power" : "sleep");
1268 
1269 	return;
1270 
1271 fail:
1272 	aprint_error_dev(sc->sc_dev, "failed to register "
1273 	    "fixed event %d: %s\n", event, AcpiFormatException(rv));
1274 }
1275 
1276 static void
1277 acpi_deregister_fixed_button(struct acpi_softc *sc, int event)
1278 {
1279 	struct sysmon_pswitch *smpsw;
1280 	ACPI_STATUS rv;
1281 
1282 	switch (event) {
1283 
1284 	case ACPI_EVENT_POWER_BUTTON:
1285 		smpsw = &sc->sc_smpsw_power;
1286 
1287 		if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) != 0) {
1288 			KASSERT(smpsw->smpsw_type != PSWITCH_TYPE_POWER);
1289 			return;
1290 		}
1291 
1292 		break;
1293 
1294 	case ACPI_EVENT_SLEEP_BUTTON:
1295 		smpsw = &sc->sc_smpsw_sleep;
1296 
1297 		if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) != 0) {
1298 			KASSERT(smpsw->smpsw_type != PSWITCH_TYPE_SLEEP);
1299 			return;
1300 		}
1301 
1302 		break;
1303 
1304 	default:
1305 		rv = AE_TYPE;
1306 		goto fail;
1307 	}
1308 
1309 	rv = AcpiRemoveFixedEventHandler(event, acpi_fixed_button_handler);
1310 
1311 	if (ACPI_SUCCESS(rv)) {
1312 		sysmon_pswitch_unregister(smpsw);
1313 		return;
1314 	}
1315 
1316 fail:
1317 	aprint_error_dev(sc->sc_dev, "failed to deregister "
1318 	    "fixed event: %s\n", AcpiFormatException(rv));
1319 }
1320 
1321 static uint32_t
1322 acpi_fixed_button_handler(void *context)
1323 {
1324 	static const int handler = OSL_NOTIFY_HANDLER;
1325 	struct sysmon_pswitch *smpsw = context;
1326 
1327 	(void)AcpiOsExecute(handler, acpi_fixed_button_pressed, smpsw);
1328 
1329 	return ACPI_INTERRUPT_HANDLED;
1330 }
1331 
1332 static void
1333 acpi_fixed_button_pressed(void *context)
1334 {
1335 	struct sysmon_pswitch *smpsw = context;
1336 
1337 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s fixed button pressed\n",
1338 		(smpsw->smpsw_type != ACPI_EVENT_SLEEP_BUTTON) ?
1339 		"power" : "sleep"));
1340 
1341 	sysmon_pswitch_event(smpsw, PSWITCH_EVENT_PRESSED);
1342 }
1343 
1344 /*
1345  * Sleep.
1346  */
1347 static void
1348 acpi_sleep_init(struct acpi_softc *sc)
1349 {
1350 	uint8_t a, b, i;
1351 	ACPI_STATUS rv;
1352 
1353 	CTASSERT(ACPI_STATE_S0 == 0 && ACPI_STATE_S1 == 1);
1354 	CTASSERT(ACPI_STATE_S2 == 2 && ACPI_STATE_S3 == 3);
1355 	CTASSERT(ACPI_STATE_S4 == 4 && ACPI_STATE_S5 == 5);
1356 
1357 	/*
1358 	 * Evaluate supported sleep states.
1359 	 */
1360 	for (i = ACPI_STATE_S0; i <= ACPI_STATE_S5; i++) {
1361 
1362 		rv = AcpiGetSleepTypeData(i, &a, &b);
1363 
1364 		if (ACPI_SUCCESS(rv))
1365 			sc->sc_sleepstates |= __BIT(i);
1366 	}
1367 }
1368 
1369 /*
1370  * Must be called with interrupts enabled.
1371  */
1372 void
1373 acpi_enter_sleep_state(int state)
1374 {
1375 	struct acpi_softc *sc = acpi_softc;
1376 	ACPI_STATUS rv;
1377 
1378 	if (acpi_softc == NULL)
1379 		return;
1380 
1381 	if (state == sc->sc_sleepstate)
1382 		return;
1383 
1384 	if (state < ACPI_STATE_S0 || state > ACPI_STATE_S5)
1385 		return;
1386 
1387 	aprint_normal_dev(sc->sc_dev, "entering state S%d\n", state);
1388 
1389 	switch (state) {
1390 
1391 	case ACPI_STATE_S0:
1392 		sc->sc_sleepstate = ACPI_STATE_S0;
1393 		return;
1394 
1395 	case ACPI_STATE_S1:
1396 	case ACPI_STATE_S2:
1397 	case ACPI_STATE_S3:
1398 	case ACPI_STATE_S4:
1399 
1400 		if ((sc->sc_sleepstates & __BIT(state)) == 0) {
1401 			aprint_error_dev(sc->sc_dev, "sleep state "
1402 			    "S%d is not available\n", state);
1403 			return;
1404 		}
1405 
1406 		/*
1407 		 * Evaluate the _TTS method. This should be done before
1408 		 * pmf_system_suspend(9) and the evaluation of _PTS.
1409 		 * We should also re-evaluate this once we return to
1410 		 * S0 or if we abort the sleep state transition in the
1411 		 * middle (see ACPI 3.0, section 7.3.6). In reality,
1412 		 * however, the _TTS method is seldom seen in the field.
1413 		 */
1414 		rv = acpi_eval_set_integer(NULL, "\\_TTS", state);
1415 
1416 		if (ACPI_SUCCESS(rv))
1417 			aprint_debug_dev(sc->sc_dev, "evaluated _TTS\n");
1418 
1419 		if (state != ACPI_STATE_S1 &&
1420 		    pmf_system_suspend(PMF_Q_NONE) != true) {
1421 			aprint_error_dev(sc->sc_dev, "aborting suspend\n");
1422 			break;
1423 		}
1424 
1425 		/*
1426 		 * This will evaluate the  _PTS and _SST methods,
1427 		 * but unlike the documentation claims, not _GTS,
1428 		 * which is evaluated in AcpiEnterSleepState().
1429 		 * This must be called with interrupts enabled.
1430 		 */
1431 		rv = AcpiEnterSleepStatePrep(state);
1432 
1433 		if (ACPI_FAILURE(rv)) {
1434 			aprint_error_dev(sc->sc_dev, "failed to prepare "
1435 			    "S%d: %s\n", state, AcpiFormatException(rv));
1436 			break;
1437 		}
1438 
1439 		/*
1440 		 * After the _PTS method has been evaluated, we can
1441 		 * enable wake and evaluate _PSW (ACPI 4.0, p. 284).
1442 		 */
1443 		acpi_wakedev_commit(sc, state);
1444 
1445 		sc->sc_sleepstate = state;
1446 
1447 		if (state == ACPI_STATE_S1) {
1448 
1449 			/*
1450 			 * Before the transition to S1, CPU caches
1451 			 * must be flushed (see ACPI 4.0, 7.3.4.2).
1452 			 *
1453 			 * Note that interrupts must be off before
1454 			 * calling AcpiEnterSleepState(). Conversely,
1455 			 * AcpiLeaveSleepState() should always be
1456 			 * called with interrupts enabled.
1457 			 */
1458 			acpi_md_OsDisableInterrupt();
1459 
1460 			ACPI_FLUSH_CPU_CACHE();
1461 			rv = AcpiEnterSleepState(state);
1462 
1463 			if (ACPI_FAILURE(rv))
1464 				aprint_error_dev(sc->sc_dev, "failed to "
1465 				    "enter S1: %s\n", AcpiFormatException(rv));
1466 
1467 			/*
1468 			 * Clear fixed events and disable all GPEs before
1469 			 * interrupts are enabled.
1470 			 */
1471 			AcpiClearEvent(ACPI_EVENT_PMTIMER);
1472 			AcpiClearEvent(ACPI_EVENT_GLOBAL);
1473 			AcpiClearEvent(ACPI_EVENT_POWER_BUTTON);
1474 			AcpiClearEvent(ACPI_EVENT_SLEEP_BUTTON);
1475 			AcpiClearEvent(ACPI_EVENT_RTC);
1476 #if (!ACPI_REDUCED_HARDWARE)
1477 			AcpiHwDisableAllGpes();
1478 #endif
1479 
1480 			acpi_md_OsEnableInterrupt();
1481 			rv = AcpiLeaveSleepState(state);
1482 
1483 		} else {
1484 
1485 			(void)acpi_md_sleep(state);
1486 
1487 			if (state == ACPI_STATE_S4)
1488 				AcpiEnable();
1489 
1490 			(void)pmf_system_bus_resume(PMF_Q_NONE);
1491 			(void)AcpiLeaveSleepState(state);
1492 			(void)AcpiSetFirmwareWakingVector(0, 0);
1493 			(void)pmf_system_resume(PMF_Q_NONE);
1494 		}
1495 
1496 		/*
1497 		 * No wake GPEs should be enabled at runtime.
1498 		 */
1499 		acpi_wakedev_commit(sc, ACPI_STATE_S0);
1500 		break;
1501 
1502 	case ACPI_STATE_S5:
1503 
1504 		(void)acpi_eval_set_integer(NULL, "\\_TTS", ACPI_STATE_S5);
1505 
1506 		rv = AcpiEnterSleepStatePrep(ACPI_STATE_S5);
1507 
1508 		if (ACPI_FAILURE(rv)) {
1509 			aprint_error_dev(sc->sc_dev, "failed to prepare "
1510 			    "S%d: %s\n", state, AcpiFormatException(rv));
1511 			break;
1512 		}
1513 
1514 		(void)AcpiDisableAllGpes();
1515 
1516 		DELAY(1000000);
1517 
1518 		sc->sc_sleepstate = state;
1519 		acpi_md_OsDisableInterrupt();
1520 
1521 		(void)AcpiEnterSleepState(ACPI_STATE_S5);
1522 
1523 		aprint_error_dev(sc->sc_dev, "WARNING: powerdown failed!\n");
1524 
1525 		break;
1526 	}
1527 
1528 	sc->sc_sleepstate = ACPI_STATE_S0;
1529 
1530 	(void)acpi_eval_set_integer(NULL, "\\_TTS", ACPI_STATE_S0);
1531 }
1532 
1533 /*
1534  * Sysctl.
1535  */
1536 SYSCTL_SETUP(sysctl_acpi_setup, "sysctl hw.acpi subtree setup")
1537 {
1538 	const struct sysctlnode *rnode, *snode;
1539 	int err;
1540 
1541 	err = sysctl_createv(clog, 0, NULL, &rnode,
1542 	    CTLFLAG_PERMANENT, CTLTYPE_NODE,
1543 	    "acpi", SYSCTL_DESCR("ACPI subsystem parameters"),
1544 	    NULL, 0, NULL, 0,
1545 	    CTL_HW, CTL_CREATE, CTL_EOL);
1546 
1547 	if (err != 0)
1548 		return;
1549 
1550 	(void)sysctl_createv(NULL, 0, &rnode, NULL,
1551 	    CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
1552 	    "root", SYSCTL_DESCR("ACPI root pointer"),
1553 	    NULL, 0, &acpi_root_pointer, sizeof(acpi_root_pointer),
1554 	    CTL_CREATE, CTL_EOL);
1555 
1556 	err = sysctl_createv(clog, 0, &rnode, &snode,
1557 	    CTLFLAG_PERMANENT, CTLTYPE_NODE,
1558 	    "sleep", SYSCTL_DESCR("ACPI sleep"),
1559 	    NULL, 0, NULL, 0,
1560 	    CTL_CREATE, CTL_EOL);
1561 
1562 	if (err != 0)
1563 		return;
1564 
1565 	(void)sysctl_createv(NULL, 0, &snode, NULL,
1566 	    CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
1567 	    "state", SYSCTL_DESCR("System sleep state"),
1568 	    sysctl_hw_acpi_sleepstate, 0, NULL, 0,
1569 	    CTL_CREATE, CTL_EOL);
1570 
1571 	(void)sysctl_createv(NULL, 0, &snode, NULL,
1572 	    CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_STRING,
1573 	    "states", SYSCTL_DESCR("Supported sleep states"),
1574 	    sysctl_hw_acpi_sleepstates, 0, NULL, 0,
1575 	    CTL_CREATE, CTL_EOL);
1576 
1577 	err = sysctl_createv(clog, 0, &rnode, &rnode,
1578 	    CTLFLAG_PERMANENT, CTLTYPE_NODE,
1579 	    "stat", SYSCTL_DESCR("ACPI statistics"),
1580 	    NULL, 0, NULL, 0,
1581 	    CTL_CREATE, CTL_EOL);
1582 
1583 	if (err != 0)
1584 		return;
1585 
1586 	(void)sysctl_createv(clog, 0, &rnode, NULL,
1587 	    CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
1588 	    "gpe", SYSCTL_DESCR("Number of dispatched GPEs"),
1589 	    NULL, 0, &AcpiGpeCount, sizeof(AcpiGpeCount),
1590 	    CTL_CREATE, CTL_EOL);
1591 
1592 	(void)sysctl_createv(clog, 0, &rnode, NULL,
1593 	    CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
1594 	    "sci", SYSCTL_DESCR("Number of SCI interrupts"),
1595 	    NULL, 0, &AcpiSciCount, sizeof(AcpiSciCount),
1596 	    CTL_CREATE, CTL_EOL);
1597 
1598 	(void)sysctl_createv(clog, 0, &rnode, NULL,
1599 	    CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
1600 	    "fixed", SYSCTL_DESCR("Number of fixed events"),
1601 	    sysctl_hw_acpi_fixedstats, 0, NULL, 0,
1602 	    CTL_CREATE, CTL_EOL);
1603 
1604 	(void)sysctl_createv(clog, 0, &rnode, NULL,
1605 	    CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
1606 	    "method", SYSCTL_DESCR("Number of methods executed"),
1607 	    NULL, 0, &AcpiMethodCount, sizeof(AcpiMethodCount),
1608 	    CTL_CREATE, CTL_EOL);
1609 
1610 	CTASSERT(sizeof(AcpiGpeCount) == sizeof(uint64_t));
1611 	CTASSERT(sizeof(AcpiSciCount) == sizeof(uint64_t));
1612 }
1613 
1614 static int
1615 sysctl_hw_acpi_fixedstats(SYSCTLFN_ARGS)
1616 {
1617 	struct sysctlnode node;
1618 	uint64_t t;
1619 	int err, i;
1620 
1621 	for (i = t = 0; i < __arraycount(AcpiFixedEventCount); i++)
1622 		t += AcpiFixedEventCount[i];
1623 
1624 	node = *rnode;
1625 	node.sysctl_data = &t;
1626 
1627 	err = sysctl_lookup(SYSCTLFN_CALL(&node));
1628 
1629 	if (err || newp == NULL)
1630 		return err;
1631 
1632 	return 0;
1633 }
1634 
1635 static int
1636 sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS)
1637 {
1638 	struct acpi_softc *sc = acpi_softc;
1639 	struct sysctlnode node;
1640 	int err, t;
1641 
1642 	if (acpi_softc == NULL)
1643 		return ENOSYS;
1644 
1645 	node = *rnode;
1646 	t = sc->sc_sleepstate;
1647 	node.sysctl_data = &t;
1648 
1649 	err = sysctl_lookup(SYSCTLFN_CALL(&node));
1650 
1651 	if (err || newp == NULL)
1652 		return err;
1653 
1654 	if (t < ACPI_STATE_S0 || t > ACPI_STATE_S5)
1655 		return EINVAL;
1656 
1657 	acpi_enter_sleep_state(t);
1658 
1659 	return 0;
1660 }
1661 
1662 static int
1663 sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS)
1664 {
1665 	struct acpi_softc *sc = acpi_softc;
1666 	struct sysctlnode node;
1667 	char t[3 * 6 + 1];
1668 	int err;
1669 
1670 	if (acpi_softc == NULL)
1671 		return ENOSYS;
1672 
1673 	(void)memset(t, '\0', sizeof(t));
1674 
1675 	(void)snprintf(t, sizeof(t), "%s%s%s%s%s%s",
1676 	    ((sc->sc_sleepstates & __BIT(0)) != 0) ? "S0 " : "",
1677 	    ((sc->sc_sleepstates & __BIT(1)) != 0) ? "S1 " : "",
1678 	    ((sc->sc_sleepstates & __BIT(2)) != 0) ? "S2 " : "",
1679 	    ((sc->sc_sleepstates & __BIT(3)) != 0) ? "S3 " : "",
1680 	    ((sc->sc_sleepstates & __BIT(4)) != 0) ? "S4 " : "",
1681 	    ((sc->sc_sleepstates & __BIT(5)) != 0) ? "S5 " : "");
1682 
1683 	node = *rnode;
1684 	node.sysctl_data = &t;
1685 
1686 	err = sysctl_lookup(SYSCTLFN_CALL(&node));
1687 
1688 	if (err || newp == NULL)
1689 		return err;
1690 
1691 	return 0;
1692 }
1693 
1694 /*
1695  * Tables.
1696  */
1697 ACPI_PHYSICAL_ADDRESS
1698 acpi_OsGetRootPointer(void)
1699 {
1700 	ACPI_PHYSICAL_ADDRESS PhysicalAddress;
1701 
1702 	/*
1703 	 * We let MD code handle this since there are multiple ways to do it:
1704 	 *
1705 	 *	IA-32: Use AcpiFindRootPointer() to locate the RSDP.
1706 	 *
1707 	 *	IA-64: Use the EFI.
1708 	 */
1709 	PhysicalAddress = acpi_md_OsGetRootPointer();
1710 
1711 	if (acpi_root_pointer == 0)
1712 		acpi_root_pointer = PhysicalAddress;
1713 
1714 	return PhysicalAddress;
1715 }
1716 
1717 static ACPI_TABLE_HEADER *
1718 acpi_map_rsdt(void)
1719 {
1720 	ACPI_PHYSICAL_ADDRESS paddr;
1721 	ACPI_TABLE_RSDP *rsdp;
1722 
1723 	paddr = AcpiOsGetRootPointer();
1724 
1725 	if (paddr == 0)
1726 		return NULL;
1727 
1728 	rsdp = AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_RSDP));
1729 
1730 	if (rsdp == NULL)
1731 		return NULL;
1732 
1733 	if (rsdp->Revision > 1 && rsdp->XsdtPhysicalAddress)
1734 		paddr = rsdp->XsdtPhysicalAddress;
1735 	else
1736 		paddr = rsdp->RsdtPhysicalAddress;
1737 
1738 	AcpiOsUnmapMemory(rsdp, sizeof(ACPI_TABLE_RSDP));
1739 
1740 	return AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_HEADER));
1741 }
1742 
1743 /*
1744  * XXX: Refactor to be a generic function that unmaps tables.
1745  */
1746 static void
1747 acpi_unmap_rsdt(ACPI_TABLE_HEADER *rsdt)
1748 {
1749 
1750 	if (rsdt == NULL)
1751 		return;
1752 
1753 	AcpiOsUnmapMemory(rsdt, sizeof(ACPI_TABLE_HEADER));
1754 }
1755 
1756 /*
1757  * XXX: Refactor to be a generic function that maps tables.
1758  */
1759 ACPI_STATUS
1760 acpi_madt_map(void)
1761 {
1762 	ACPI_STATUS  rv;
1763 
1764 	if (madt_header != NULL)
1765 		return AE_ALREADY_EXISTS;
1766 
1767 	rv = AcpiGetTable(ACPI_SIG_MADT, 1, &madt_header);
1768 
1769 	if (ACPI_FAILURE(rv))
1770 		return rv;
1771 
1772 	return AE_OK;
1773 }
1774 
1775 void
1776 acpi_madt_unmap(void)
1777 {
1778 	madt_header = NULL;
1779 }
1780 
1781 ACPI_STATUS
1782 acpi_gtdt_map(void)
1783 {
1784 	ACPI_STATUS  rv;
1785 
1786 	if (gtdt_header != NULL)
1787 		return AE_ALREADY_EXISTS;
1788 
1789 	rv = AcpiGetTable(ACPI_SIG_GTDT, 1, &gtdt_header);
1790 
1791 	if (ACPI_FAILURE(rv))
1792 		return rv;
1793 
1794 	return AE_OK;
1795 }
1796 
1797 void
1798 acpi_gtdt_unmap(void)
1799 {
1800 	gtdt_header = NULL;
1801 }
1802 
1803 /*
1804  * XXX: Refactor to be a generic function that walks tables.
1805  */
1806 void
1807 acpi_madt_walk(ACPI_STATUS (*func)(ACPI_SUBTABLE_HEADER *, void *), void *aux)
1808 {
1809 	ACPI_SUBTABLE_HEADER *hdrp;
1810 	char *madtend, *where;
1811 
1812 	madtend = (char *)madt_header + madt_header->Length;
1813 	where = (char *)madt_header + sizeof (ACPI_TABLE_MADT);
1814 
1815 	while (where < madtend) {
1816 
1817 		hdrp = (ACPI_SUBTABLE_HEADER *)where;
1818 
1819 		if (hdrp->Length == 0 || ACPI_FAILURE(func(hdrp, aux)))
1820 			break;
1821 
1822 		where += hdrp->Length;
1823 	}
1824 }
1825 
1826 void
1827 acpi_gtdt_walk(ACPI_STATUS (*func)(ACPI_GTDT_HEADER *, void *), void *aux)
1828 {
1829 	ACPI_GTDT_HEADER *hdrp;
1830 	char *gtdtend, *where;
1831 
1832 	gtdtend = (char *)gtdt_header + gtdt_header->Length;
1833 	where = (char *)gtdt_header + sizeof (ACPI_TABLE_GTDT);
1834 
1835 	while (where < gtdtend) {
1836 
1837 		hdrp = (ACPI_GTDT_HEADER *)where;
1838 
1839 		if (hdrp->Length == 0 || ACPI_FAILURE(func(hdrp, aux)))
1840 			break;
1841 
1842 		where += hdrp->Length;
1843 	}
1844 }
1845 
1846 /*
1847  * Miscellaneous.
1848  */
1849 static bool
1850 acpi_is_scope(struct acpi_devnode *ad)
1851 {
1852 	int i;
1853 
1854 	/*
1855 	 * Return true if the node is a root scope.
1856 	 */
1857 	if (ad->ad_parent == NULL)
1858 		return false;
1859 
1860 	if (ad->ad_parent->ad_handle != ACPI_ROOT_OBJECT)
1861 		return false;
1862 
1863 	for (i = 0; i < __arraycount(acpi_scopes); i++) {
1864 
1865 		if (acpi_scopes[i] == NULL)
1866 			continue;
1867 
1868 		if (ad->ad_handle == acpi_scopes[i])
1869 			return true;
1870 	}
1871 
1872 	return false;
1873 }
1874 
1875 bool
1876 acpi_device_present(ACPI_HANDLE handle)
1877 {
1878 	ACPI_STATUS rv;
1879 	ACPI_INTEGER sta;
1880 
1881 	rv = acpi_eval_integer(handle, "_STA", &sta);
1882 
1883 	if (ACPI_FAILURE(rv)) {
1884 		/* No _STA method -> must be there */
1885 		return rv == AE_NOT_FOUND;
1886 	}
1887 
1888 	return (sta & ACPI_STA_OK) == ACPI_STA_OK;
1889 }
1890 
1891 /*
1892  * ACPIVERBOSE.
1893  */
1894 void
1895 acpi_load_verbose(void)
1896 {
1897 
1898 	if (acpi_verbose_loaded == 0)
1899 		module_autoload("acpiverbose", MODULE_CLASS_MISC);
1900 }
1901 
1902 void
1903 acpi_print_verbose_stub(struct acpi_softc *sc)
1904 {
1905 
1906 	acpi_load_verbose();
1907 
1908 	if (acpi_verbose_loaded != 0)
1909 		acpi_print_verbose(sc);
1910 }
1911 
1912 void
1913 acpi_print_dev_stub(const char *pnpstr)
1914 {
1915 
1916 	acpi_load_verbose();
1917 
1918 	if (acpi_verbose_loaded != 0)
1919 		acpi_print_dev(pnpstr);
1920 }
1921 
1922 MALLOC_DECLARE(M_ACPI); /* XXX: ACPI_ACTIVATE_DEV should use kmem(9). */
1923 
1924 /*
1925  * ACPI_ACTIVATE_DEV.
1926  */
1927 static void
1928 acpi_activate_device(ACPI_HANDLE handle, ACPI_DEVICE_INFO **di)
1929 {
1930 
1931 #ifndef ACPI_ACTIVATE_DEV
1932 	return;
1933 }
1934 #else
1935 	static const int valid = ACPI_VALID_HID;
1936 	ACPI_DEVICE_INFO *newdi;
1937 	ACPI_STATUS rv;
1938 
1939 
1940 	/*
1941 	 * If the device is valid and present,
1942 	 * but not enabled, try to activate it.
1943 	 */
1944 	if (((*di)->Valid & valid) != valid)
1945 		return;
1946 
1947 	if (!acpi_device_present(handle))
1948 		return;
1949 
1950 	rv = acpi_allocate_resources(handle);
1951 
1952 	if (ACPI_FAILURE(rv))
1953 		goto fail;
1954 
1955 	rv = AcpiGetObjectInfo(handle, &newdi);
1956 
1957 	if (ACPI_FAILURE(rv))
1958 		goto fail;
1959 
1960 	ACPI_FREE(*di);
1961 	*di = newdi;
1962 
1963 	aprint_verbose_dev(acpi_softc->sc_dev,
1964 	    "%s activated\n", (*di)->HardwareId.String);
1965 
1966 	return;
1967 
1968 fail:
1969 	aprint_error_dev(acpi_softc->sc_dev, "failed to "
1970 	    "activate %s\n", (*di)->HardwareId.String);
1971 }
1972 
1973 /*
1974  * XXX: This very incomplete.
1975  */
1976 ACPI_STATUS
1977 acpi_allocate_resources(ACPI_HANDLE handle)
1978 {
1979 	ACPI_BUFFER bufp, bufc, bufn;
1980 	ACPI_RESOURCE *resp, *resc, *resn;
1981 	ACPI_RESOURCE_IRQ *irq;
1982 #if 0
1983 	ACPI_RESOURCE_EXTENDED_IRQ *xirq;
1984 #endif
1985 	ACPI_STATUS rv;
1986 	uint delta;
1987 
1988 	rv = acpi_get(handle, &bufp, AcpiGetPossibleResources);
1989 	if (ACPI_FAILURE(rv))
1990 		goto out;
1991 	rv = acpi_get(handle, &bufc, AcpiGetCurrentResources);
1992 	if (ACPI_FAILURE(rv)) {
1993 		goto out1;
1994 	}
1995 
1996 	bufn.Length = 1000;
1997 	bufn.Pointer = resn = malloc(bufn.Length, M_ACPI, M_WAITOK);
1998 	resp = bufp.Pointer;
1999 	resc = bufc.Pointer;
2000 	while (resc->Type != ACPI_RESOURCE_TYPE_END_TAG &&
2001 	       resp->Type != ACPI_RESOURCE_TYPE_END_TAG) {
2002 		while (resc->Type != resp->Type && resp->Type != ACPI_RESOURCE_TYPE_END_TAG)
2003 			resp = ACPI_NEXT_RESOURCE(resp);
2004 		if (resp->Type == ACPI_RESOURCE_TYPE_END_TAG)
2005 			break;
2006 		/* Found identical Id */
2007 		resn->Type = resc->Type;
2008 		switch (resc->Type) {
2009 		case ACPI_RESOURCE_TYPE_IRQ:
2010 			memcpy(&resn->Data, &resp->Data,
2011 			       sizeof(ACPI_RESOURCE_IRQ));
2012 			irq = (ACPI_RESOURCE_IRQ *)&resn->Data;
2013 			irq->Interrupts[0] =
2014 			    ((ACPI_RESOURCE_IRQ *)&resp->Data)->
2015 			        Interrupts[irq->InterruptCount-1];
2016 			irq->InterruptCount = 1;
2017 			resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_IRQ);
2018 			break;
2019 		case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
2020 			memcpy(&resn->Data, &resp->Data,
2021 			       sizeof(ACPI_RESOURCE_EXTENDED_IRQ));
2022 #if 0
2023 			xirq = (ACPI_RESOURCE_EXTENDED_IRQ *)&resn->Data;
2024 			/*
2025 			 * XXX:	Not duplicating the interrupt logic above
2026 			 *	because its not clear what it accomplishes.
2027 			 */
2028 			xirq->Interrupts[0] =
2029 			    ((ACPI_RESOURCE_EXT_IRQ *)&resp->Data)->
2030 			    Interrupts[irq->NumberOfInterrupts-1];
2031 			xirq->NumberOfInterrupts = 1;
2032 #endif
2033 			resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_EXTENDED_IRQ);
2034 			break;
2035 		case ACPI_RESOURCE_TYPE_IO:
2036 			memcpy(&resn->Data, &resp->Data,
2037 			       sizeof(ACPI_RESOURCE_IO));
2038 			resn->Length = resp->Length;
2039 			break;
2040 		default:
2041 			aprint_error_dev(acpi_softc->sc_dev,
2042 			    "%s: invalid type %u\n", __func__, resc->Type);
2043 			rv = AE_BAD_DATA;
2044 			goto out2;
2045 		}
2046 		resc = ACPI_NEXT_RESOURCE(resc);
2047 		resn = ACPI_NEXT_RESOURCE(resn);
2048 		resp = ACPI_NEXT_RESOURCE(resp);
2049 		delta = (uint8_t *)resn - (uint8_t *)bufn.Pointer;
2050 		if (delta >=
2051 		    bufn.Length-ACPI_RS_SIZE(ACPI_RESOURCE_DATA)) {
2052 			bufn.Length *= 2;
2053 			bufn.Pointer = realloc(bufn.Pointer, bufn.Length,
2054 					       M_ACPI, M_WAITOK);
2055 			resn = (ACPI_RESOURCE *)((uint8_t *)bufn.Pointer +
2056 			    delta);
2057 		}
2058 	}
2059 
2060 	if (resc->Type != ACPI_RESOURCE_TYPE_END_TAG) {
2061 		aprint_error_dev(acpi_softc->sc_dev,
2062 		    "%s: resc not exhausted\n", __func__);
2063 		rv = AE_BAD_DATA;
2064 		goto out3;
2065 	}
2066 
2067 	resn->Type = ACPI_RESOURCE_TYPE_END_TAG;
2068 	rv = AcpiSetCurrentResources(handle, &bufn);
2069 
2070 	if (ACPI_FAILURE(rv))
2071 		aprint_error_dev(acpi_softc->sc_dev, "%s: failed to set "
2072 		    "resources: %s\n", __func__, AcpiFormatException(rv));
2073 
2074 out3:
2075 	free(bufn.Pointer, M_ACPI);
2076 out2:
2077 	ACPI_FREE(bufc.Pointer);
2078 out1:
2079 	ACPI_FREE(bufp.Pointer);
2080 out:
2081 	return rv;
2082 }
2083 
2084 #endif	/* ACPI_ACTIVATE_DEV */
2085