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