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