1 /* $NetBSD: acpi.c,v 1.141 2010/01/08 00:09:44 dyoung Exp $ */
4 * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum of By Noon Software, Inc.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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.
33 * Copyright 2001, 2003 Wasabi Systems, Inc.
34 * All rights reserved.
36 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
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
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.
68 * Autoconfiguration support for the Intel ACPI Component Architecture
69 * ACPI reference implementation.
72 #include <sys/cdefs.h>
73 __KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.141 2010/01/08 00:09:44 dyoung Exp $");
76 #include "opt_pcifixup.h"
78 #include <sys/param.h>
79 #include <sys/systm.h>
80 #include <sys/device.h>
81 #include <sys/malloc.h>
82 #include <sys/mutex.h>
83 #include <sys/kernel.h>
85 #include <sys/sysctl.h>
87 #include <dev/acpi/acpica.h>
88 #include <dev/acpi/acpireg.h>
89 #include <dev/acpi/acpivar.h>
90 #include <dev/acpi/acpi_osd.h>
91 #include <dev/acpi/acpi_timer.h>
92 #include <dev/acpi/acpi_wakedev.h>
93 #include <dev/acpi/acpi_pci.h>
95 #include <dev/acpi/acpidevs_data.h>
98 #define _COMPONENT ACPI_TOOLS
99 ACPI_MODULE_NAME ("acpi")
101 #if defined(ACPI_PCI_FIXUP)
102 #error The option ACPI_PCI_FIXUP has been obsoleted by PCI_INTR_FIXUP_DISABLED. Please adjust your kernel configuration file.
105 #ifdef PCI_INTR_FIXUP_DISABLED
106 #include <dev/pci/pcidevs.h>
109 MALLOC_DECLARE(M_ACPI
);
111 #include <machine/acpi_machdep.h>
114 #define ACPI_DBGR_INIT 0x01
115 #define ACPI_DBGR_TABLES 0x02
116 #define ACPI_DBGR_ENABLE 0x04
117 #define ACPI_DBGR_PROBE 0x08
118 #define ACPI_DBGR_RUNNING 0x10
120 static int acpi_dbgr
= 0x00;
123 static ACPI_TABLE_DESC acpi_initial_tables
[128];
125 static int acpi_match(device_t
, cfdata_t
, void *);
126 static void acpi_attach(device_t
, device_t
, void *);
127 static void acpi_childdet(device_t
, device_t
);
128 static int acpi_detach(device_t
, int);
130 static int acpi_rescan(device_t
, const char *, const int *);
131 static void acpi_rescan1(struct acpi_softc
*, const char *, const int *);
132 static void acpi_rescan_nodes(struct acpi_softc
*);
134 static int acpi_print(void *aux
, const char *);
136 static int sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS
);
138 extern struct cfdriver acpi_cd
;
140 CFATTACH_DECL2_NEW(acpi
, sizeof(struct acpi_softc
),
141 acpi_match
, acpi_attach
, acpi_detach
, NULL
, acpi_rescan
, acpi_childdet
);
144 * This is a flag we set when the ACPI subsystem is active. Machine
145 * dependent code may wish to skip other steps (such as attaching
146 * subsystems that ACPI supercedes) when ACPI is active.
150 int acpi_suspended
= 0;
153 * Pointer to the ACPI subsystem's state. There can be only
156 struct acpi_softc
*acpi_softc
;
161 extern kmutex_t acpi_interrupt_list_mtx
;
166 static const char * const acpi_ignored_ids
[] = {
167 #if defined(i386) || defined(x86_64)
168 "PNP0000", /* AT interrupt controller is handled internally */
169 "PNP0200", /* AT DMA controller is handled internally */
170 "PNP0A??", /* PCI Busses are handled internally */
171 "PNP0B00", /* AT RTC is handled internally */
172 "PNP0C01", /* No "System Board" driver */
173 "PNP0C02", /* No "PnP motherboard register resources" driver */
174 "PNP0C0F", /* ACPI PCI link devices are handled internally */
175 "INT0800", /* Intel HW RNG is handled internally */
178 "PNP0C04", /* FPU is handled internally */
184 * sysctl-related information
187 static uint64_t acpi_root_pointer
; /* found as hw.acpi.root */
188 static int acpi_sleepstate
= ACPI_STATE_S0
;
189 static char acpi_supported_states
[3 * 6 + 1] = "";
194 static void acpi_build_tree(struct acpi_softc
*);
195 static ACPI_STATUS
acpi_make_devnode(ACPI_HANDLE
, UINT32
, void *, void **);
197 static void acpi_enable_fixed_events(struct acpi_softc
*);
199 static ACPI_TABLE_HEADER
*acpi_map_rsdt(void);
200 static void acpi_unmap_rsdt(ACPI_TABLE_HEADER
*);
201 static int is_available_state(struct acpi_softc
*, int);
203 static bool acpi_suspend(device_t
, pmf_qual_t
);
204 static bool acpi_resume(device_t
, pmf_qual_t
);
209 * Probe for ACPI support. This is called by the
210 * machine-dependent ACPI front-end. All of the
211 * actual work is done by ACPICA.
213 * NOTE: This is not an autoconfiguration interface function.
219 ACPI_TABLE_HEADER
*rsdt
;
223 panic("acpi_probe: ACPI has already been probed");
226 mutex_init(&acpi_interrupt_list_mtx
, MUTEX_DEFAULT
, IPL_NONE
);
232 if (acpi_dbgr
& ACPI_DBGR_INIT
)
236 AcpiGbl_AllMethodsSerialized
= FALSE
;
237 AcpiGbl_EnableInterpreterSlack
= TRUE
;
239 rv
= AcpiInitializeSubsystem();
240 if (ACPI_FAILURE(rv
)) {
241 printf("ACPI: unable to initialize ACPICA: %s\n",
242 AcpiFormatException(rv
));
246 rv
= AcpiInitializeTables(acpi_initial_tables
, 128, 0);
247 if (ACPI_FAILURE(rv
)) {
249 printf("ACPI: unable to initialize ACPI tables: %s\n",
250 AcpiFormatException(rv
));
256 rv
= AcpiReallocateRootTable();
257 if (ACPI_FAILURE(rv
)) {
258 printf("ACPI: unable to reallocate root table: %s\n",
259 AcpiFormatException(rv
));
265 if (acpi_dbgr
& ACPI_DBGR_TABLES
)
269 rv
= AcpiLoadTables();
270 if (ACPI_FAILURE(rv
)) {
271 printf("ACPI: unable to load tables: %s\n",
272 AcpiFormatException(rv
));
277 rsdt
= acpi_map_rsdt();
279 printf("ACPI: unable to map RSDT\n");
284 if (!acpi_force_load
&& (acpi_find_quirks() & ACPI_QUIRK_BROKEN
)) {
285 printf("ACPI: BIOS implementation in listed as broken:\n");
286 printf("ACPI: X/RSDT: OemId <%6.6s,%8.8s,%08x>, "
287 "AslId <%4.4s,%08x>\n",
288 rsdt
->OemId
, rsdt
->OemTableId
,
291 rsdt
->AslCompilerRevision
);
292 printf("ACPI: not used. set acpi_force_load to use anyway.\n");
293 acpi_unmap_rsdt(rsdt
);
298 acpi_unmap_rsdt(rsdt
);
301 /* Install the default address space handlers. */
302 rv
= AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT
,
303 ACPI_ADR_SPACE_SYSTEM_MEMORY
, ACPI_DEFAULT_HANDLER
, NULL
, NULL
);
304 if (ACPI_FAILURE(rv
)) {
305 printf("ACPI: unable to initialize SystemMemory handler: %s\n",
306 AcpiFormatException(rv
));
310 rv
= AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT
,
311 ACPI_ADR_SPACE_SYSTEM_IO
, ACPI_DEFAULT_HANDLER
, NULL
, NULL
);
312 if (ACPI_FAILURE(rv
)) {
313 printf("ACPI: unable to initialize SystemIO handler: %s\n",
314 AcpiFormatException(rv
));
318 rv
= AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT
,
319 ACPI_ADR_SPACE_PCI_CONFIG
, ACPI_DEFAULT_HANDLER
, NULL
, NULL
);
320 if (ACPI_FAILURE(rv
)) {
321 printf("ACPI: unable to initialize PciConfig handler: %s\n",
322 AcpiFormatException(rv
));
328 rv
= AcpiEnableSubsystem(~(ACPI_NO_HARDWARE_INIT
|ACPI_NO_ACPI_ENABLE
));
329 if (ACPI_FAILURE(rv
)) {
330 printf("ACPI: unable to enable: %s\n", AcpiFormatException(rv
));
336 * Looks like we have ACPI!
343 acpi_submatch(device_t parent
, cfdata_t cf
, const int *locs
, void *aux
)
347 ca
= config_cfattach_lookup(cf
->cf_name
, cf
->cf_atname
);
348 return (ca
== &acpi_ca
);
352 acpi_check(device_t parent
, const char *ifattr
)
354 return (config_search_ia(acpi_submatch
, parent
, ifattr
, NULL
) != NULL
);
357 ACPI_PHYSICAL_ADDRESS
358 acpi_OsGetRootPointer(void)
360 ACPI_PHYSICAL_ADDRESS PhysicalAddress
;
363 * IA-32: Use AcpiFindRootPointer() to locate the RSDP.
365 * IA-64: Use the EFI.
367 * We let MD code handle this since there are multiple
371 PhysicalAddress
= acpi_md_OsGetRootPointer();
373 if (acpi_root_pointer
== 0)
374 acpi_root_pointer
= PhysicalAddress
;
376 return PhysicalAddress
;
382 * Autoconfiguration `match' routine.
385 acpi_match(device_t parent
, cfdata_t match
, void *aux
)
388 * XXX Check other locators? Hard to know -- machine
389 * dependent code has already checked for the presence
390 * of ACPI by calling acpi_probe(), so I suppose we
391 * don't really have to do anything else.
396 /* Remove references to child devices.
398 * XXX Need to reclaim any resources?
401 acpi_childdet(device_t self
, device_t child
)
403 struct acpi_softc
*sc
= device_private(self
);
404 struct acpi_scope
*as
;
405 struct acpi_devnode
*ad
;
407 if (sc
->sc_apmbus
== child
)
408 sc
->sc_apmbus
= NULL
;
410 TAILQ_FOREACH(as
, &sc
->sc_scopes
, as_list
) {
411 TAILQ_FOREACH(ad
, &as
->as_devnodes
, ad_list
) {
412 if (ad
->ad_device
== child
)
413 ad
->ad_device
= NULL
;
421 * Autoconfiguration `attach' routine. Finish initializing
422 * ACPICA (some initialization was done in acpi_probe(),
423 * which was required to check for the presence of ACPI),
424 * and enable the ACPI subsystem.
427 acpi_attach(device_t parent
, device_t self
, void *aux
)
429 struct acpi_softc
*sc
= device_private(self
);
430 struct acpibus_attach_args
*aa
= aux
;
432 ACPI_TABLE_HEADER
*rsdt
;
435 aprint_normal(": Intel ACPICA %08x\n", ACPI_CA_VERSION
);
437 if (acpi_softc
!= NULL
)
438 panic("acpi_attach: ACPI has already been attached");
440 sysmon_power_settype("acpi");
442 rsdt
= acpi_map_rsdt();
446 "X/RSDT: OemId <%6.6s,%8.8s,%08x>, AslId <%4.4s,%08x>\n",
447 rsdt
->OemId
, rsdt
->OemTableId
,
449 rsdt
->AslCompilerId
, rsdt
->AslCompilerRevision
);
451 aprint_error_dev(self
, "X/RSDT: Not found\n");
452 acpi_unmap_rsdt(rsdt
);
455 sc
->sc_quirks
= acpi_find_quirks();
457 sc
->sc_iot
= aa
->aa_iot
;
458 sc
->sc_memt
= aa
->aa_memt
;
459 sc
->sc_pc
= aa
->aa_pc
;
460 sc
->sc_pciflags
= aa
->aa_pciflags
;
461 sc
->sc_ic
= aa
->aa_ic
;
466 * Register null power management handler
468 if (!pmf_device_register(self
, acpi_suspend
, acpi_resume
))
469 aprint_error_dev(self
, "couldn't establish power handler\n");
472 * Bring ACPI on-line.
475 if (acpi_dbgr
& ACPI_DBGR_ENABLE
)
479 #define ACPI_ENABLE_PHASE1 \
480 (ACPI_NO_HANDLER_INIT | ACPI_NO_EVENT_INIT)
481 #define ACPI_ENABLE_PHASE2 \
482 (ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE | \
483 ACPI_NO_ADDRESS_SPACE_INIT)
485 rv
= AcpiEnableSubsystem(ACPI_ENABLE_PHASE1
);
486 if (ACPI_FAILURE(rv
)) {
487 aprint_error_dev(self
, "unable to enable ACPI: %s\n",
488 AcpiFormatException(rv
));
494 rv
= AcpiEnableSubsystem(ACPI_ENABLE_PHASE2
);
495 if (ACPI_FAILURE(rv
)) {
496 aprint_error_dev(self
, "unable to enable ACPI: %s\n",
497 AcpiFormatException(rv
));
501 /* early EC handler initialization if ECDT table is available */
502 config_found_ia(self
, "acpiecdtbus", NULL
, NULL
);
504 rv
= AcpiInitializeObjects(ACPI_FULL_INITIALIZATION
);
505 if (ACPI_FAILURE(rv
)) {
506 aprint_error_dev(self
,
507 "unable to initialize ACPI objects: %s\n",
508 AcpiFormatException(rv
));
513 /* Our current state is "awake". */
514 sc
->sc_sleepstate
= ACPI_STATE_S0
;
516 /* Show SCI interrupt. */
517 aprint_verbose_dev(self
, "SCI interrupting at int %d\n",
518 AcpiGbl_FADT
.SciInterrupt
);
521 * Check for fixed-hardware features.
523 acpi_enable_fixed_events(sc
);
527 * Scan the namespace and build our device tree.
530 if (acpi_dbgr
& ACPI_DBGR_PROBE
)
535 snprintf(acpi_supported_states
, sizeof(acpi_supported_states
),
537 is_available_state(sc
, ACPI_STATE_S0
) ? "S0 " : "",
538 is_available_state(sc
, ACPI_STATE_S1
) ? "S1 " : "",
539 is_available_state(sc
, ACPI_STATE_S2
) ? "S2 " : "",
540 is_available_state(sc
, ACPI_STATE_S3
) ? "S3 " : "",
541 is_available_state(sc
, ACPI_STATE_S4
) ? "S4 " : "",
542 is_available_state(sc
, ACPI_STATE_S5
) ? "S5 " : "");
545 if (acpi_dbgr
& ACPI_DBGR_RUNNING
)
551 acpi_detach(device_t self
, int flags
)
556 if (acpi_dbgr
& ACPI_DBGR_RUNNING
)
560 if ((rc
= config_detach_children(self
, flags
)) != 0)
564 if (acpi_dbgr
& ACPI_DBGR_PROBE
)
568 if ((rc
= acpitimer_detach()) != 0)
573 * Bring ACPI on-line.
576 if (acpi_dbgr
& ACPI_DBGR_ENABLE
)
580 #define ACPI_ENABLE_PHASE1 \
581 (ACPI_NO_HANDLER_INIT | ACPI_NO_EVENT_INIT)
582 #define ACPI_ENABLE_PHASE2 \
583 (ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE | \
584 ACPI_NO_ADDRESS_SPACE_INIT)
586 rv
= AcpiEnableSubsystem(ACPI_ENABLE_PHASE1
);
587 if (ACPI_FAILURE(rv
)) {
588 aprint_error_dev(self
, "unable to enable ACPI: %s\n",
589 AcpiFormatException(rv
));
593 rv
= AcpiEnableSubsystem(ACPI_ENABLE_PHASE2
);
594 if (ACPI_FAILURE(rv
)) {
595 aprint_error_dev(self
, "unable to enable ACPI: %s\n",
596 AcpiFormatException(rv
));
600 /* early EC handler initialization if ECDT table is available */
601 config_found_ia(self
, "acpiecdtbus", NULL
, NULL
);
603 rv
= AcpiInitializeObjects(ACPI_FULL_INITIALIZATION
);
604 if (ACPI_FAILURE(rv
)) {
605 aprint_error_dev(self
,
606 "unable to initialize ACPI objects: %s\n",
607 AcpiFormatException(rv
));
612 acpi_enable_fixed_events(sc
);
615 pmf_device_deregister(self
);
618 sysmon_power_settype("acpi");
626 acpi_suspend(device_t dv
, pmf_qual_t qual
)
633 acpi_resume(device_t dv
, pmf_qual_t qual
)
646 acpi_disable(struct acpi_softc
*sc
)
648 ACPI_STATUS rv
= AE_OK
;
652 if (ACPI_SUCCESS(rv
))
659 struct acpi_make_devnode_state
{
660 struct acpi_softc
*softc
;
661 struct acpi_scope
*scope
;
667 * Scan relevant portions of the ACPI namespace and attach
671 acpi_build_tree(struct acpi_softc
*sc
)
673 static const char *scopes
[] = {
674 "\\_PR_", /* ACPI 1.0 processor namespace */
675 "\\_SB_", /* system bus namespace */
676 "\\_SI_", /* system indicator namespace */
677 "\\_TZ_", /* ACPI 1.0 thermal zone namespace */
680 struct acpi_make_devnode_state state
;
681 struct acpi_scope
*as
;
686 TAILQ_INIT(&sc
->sc_scopes
);
691 * Scan the namespace and build our tree.
693 for (i
= 0; scopes
[i
] != NULL
; i
++) {
694 as
= malloc(sizeof(*as
), M_ACPI
, M_WAITOK
);
695 as
->as_name
= scopes
[i
];
696 TAILQ_INIT(&as
->as_devnodes
);
698 TAILQ_INSERT_TAIL(&sc
->sc_scopes
, as
, as_list
);
702 rv
= AcpiGetHandle(ACPI_ROOT_OBJECT
, scopes
[i
],
704 if (ACPI_SUCCESS(rv
)) {
705 AcpiWalkNamespace(ACPI_TYPE_ANY
, parent
, 100,
706 acpi_make_devnode
, &state
, NULL
);
710 acpi_rescan1(sc
, NULL
, NULL
);
712 acpi_wakedev_scan(sc
);
714 acpi_pcidev_scan(sc
);
718 acpi_rescan(device_t self
, const char *ifattr
, const int *locators
)
720 struct acpi_softc
*sc
= device_private(self
);
722 acpi_rescan1(sc
, ifattr
, locators
);
727 acpi_rescan1(struct acpi_softc
*sc
, const char *ifattr
, const int *locators
)
729 if (ifattr_match(ifattr
, "acpinodebus"))
730 acpi_rescan_nodes(sc
);
732 if (ifattr_match(ifattr
, "acpiapmbus") && sc
->sc_apmbus
== NULL
) {
733 sc
->sc_apmbus
= config_found_ia(sc
->sc_dev
, "acpiapmbus", NULL
,
739 acpi_rescan_nodes(struct acpi_softc
*sc
)
741 struct acpi_scope
*as
;
743 TAILQ_FOREACH(as
, &sc
->sc_scopes
, as_list
) {
744 struct acpi_devnode
*ad
;
746 /* Now, for this namespace, try to attach the devices. */
747 TAILQ_FOREACH(ad
, &as
->as_devnodes
, ad_list
) {
748 struct acpi_attach_args aa
;
750 if (ad
->ad_device
!= NULL
)
754 aa
.aa_iot
= sc
->sc_iot
;
755 aa
.aa_memt
= sc
->sc_memt
;
756 aa
.aa_pc
= sc
->sc_pc
;
757 aa
.aa_pciflags
= sc
->sc_pciflags
;
758 aa
.aa_ic
= sc
->sc_ic
;
760 if (ad
->ad_devinfo
->Type
== ACPI_TYPE_DEVICE
) {
762 * XXX We only attach devices which are:
766 * - functioning properly
768 * However, if enabled, it's decoding resources,
769 * so we should claim them, if possible.
770 * Requires changes to bus_space(9).
772 if ((ad
->ad_devinfo
->Valid
& ACPI_VALID_STA
) ==
774 (ad
->ad_devinfo
->CurrentStatus
&
775 (ACPI_STA_DEV_PRESENT
|ACPI_STA_DEV_ENABLED
|
777 (ACPI_STA_DEV_PRESENT
|ACPI_STA_DEV_ENABLED
|
783 * XXX Same problem as above...
785 * Do this check only for devices, as e.g.
786 * a Thermal Zone doesn't have a HID.
788 if (ad
->ad_devinfo
->Type
== ACPI_TYPE_DEVICE
&&
789 (ad
->ad_devinfo
->Valid
& ACPI_VALID_HID
) == 0)
795 if (ad
->ad_devinfo
->Type
== ACPI_TYPE_PROCESSOR
||
796 ad
->ad_devinfo
->Type
== ACPI_TYPE_POWER
)
802 if (acpi_match_hid(ad
->ad_devinfo
, acpi_ignored_ids
))
805 ad
->ad_device
= config_found_ia(sc
->sc_dev
,
806 "acpinodebus", &aa
, acpi_print
);
811 #ifdef ACPI_ACTIVATE_DEV
813 acpi_activate_device(ACPI_HANDLE handle
, ACPI_DEVICE_INFO
**di
)
816 ACPI_DEVICE_INFO
*newdi
;
819 aprint_normal("acpi_activate_device: %s, old status=%x\n",
820 (*di
)->HardwareId
.Value
, (*di
)->CurrentStatus
);
823 rv
= acpi_allocate_resources(handle
);
824 if (ACPI_FAILURE(rv
)) {
825 aprint_error("acpi: activate failed for %s\n",
826 (*di
)->HardwareId
.String
);
828 aprint_verbose("acpi: activated %s\n",
829 (*di
)->HardwareId
.String
);
832 (void)AcpiGetObjectInfo(handle
, &newdi
);
837 aprint_normal("acpi_activate_device: %s, new status=%x\n",
838 (*di
)->HardwareId
.Value
, (*di
)->CurrentStatus
);
841 #endif /* ACPI_ACTIVATE_DEV */
846 * Make an ACPI devnode.
849 acpi_make_devnode(ACPI_HANDLE handle
, UINT32 level
, void *context
,
852 struct acpi_make_devnode_state
*state
= context
;
853 #if defined(ACPI_DEBUG) || defined(ACPI_EXTRA_DEBUG)
854 struct acpi_softc
*sc
= state
->softc
;
856 struct acpi_scope
*as
= state
->scope
;
857 struct acpi_devnode
*ad
;
858 ACPI_OBJECT_TYPE type
;
859 ACPI_DEVICE_INFO
*devinfo
;
861 ACPI_NAME_UNION
*anu
;
864 rv
= AcpiGetType(handle
, &type
);
865 if (ACPI_SUCCESS(rv
)) {
866 rv
= AcpiGetObjectInfo(handle
, &devinfo
);
867 if (ACPI_FAILURE(rv
)) {
869 aprint_normal_dev(sc
->sc_dev
,
870 "AcpiGetObjectInfo failed: %s\n",
871 AcpiFormatException(rv
));
873 goto out
; /* XXX why return OK */
877 case ACPI_TYPE_DEVICE
:
878 #ifdef ACPI_ACTIVATE_DEV
879 if ((devinfo
->Valid
& (ACPI_VALID_STA
|ACPI_VALID_HID
)) ==
880 (ACPI_VALID_STA
|ACPI_VALID_HID
) &&
881 (devinfo
->CurrentStatus
&
882 (ACPI_STA_DEV_PRESENT
|ACPI_STA_DEV_ENABLED
)) ==
883 ACPI_STA_DEV_PRESENT
)
884 acpi_activate_device(handle
, &devinfo
);
889 case ACPI_TYPE_PROCESSOR
:
890 case ACPI_TYPE_THERMAL
:
891 case ACPI_TYPE_POWER
:
892 ad
= malloc(sizeof(*ad
), M_ACPI
, M_NOWAIT
|M_ZERO
);
896 ad
->ad_devinfo
= devinfo
;
897 ad
->ad_handle
= handle
;
898 ad
->ad_level
= level
;
902 anu
= (ACPI_NAME_UNION
*)&devinfo
->Name
;
903 ad
->ad_name
[4] = '\0';
904 for (i
= 3, clear
= 0; i
>= 0; i
--) {
905 if (!clear
&& anu
->Ascii
[i
] == '_')
906 ad
->ad_name
[i
] = '\0';
908 ad
->ad_name
[i
] = anu
->Ascii
[i
];
912 if (ad
->ad_name
[0] == '\0')
913 ad
->ad_name
[0] = '_';
915 TAILQ_INSERT_TAIL(&as
->as_devnodes
, ad
, ad_list
);
917 if (type
== ACPI_TYPE_DEVICE
&&
918 (ad
->ad_devinfo
->Valid
& ACPI_VALID_HID
) == 0)
921 #ifdef ACPI_EXTRA_DEBUG
922 aprint_normal_dev(sc
->sc_dev
,
923 "HID %s found in scope %s level %d\n",
924 ad
->ad_devinfo
->HardwareId
.String
,
925 as
->as_name
, ad
->ad_level
);
926 if (ad
->ad_devinfo
->Valid
& ACPI_VALID_UID
)
927 aprint_normal(" UID %s\n",
928 ad
->ad_devinfo
->UniqueId
.String
);
929 if (ad
->ad_devinfo
->Valid
& ACPI_VALID_ADR
)
930 aprint_normal(" ADR 0x%016" PRIx64
"\n",
931 ad
->ad_devinfo
->Address
);
932 if (ad
->ad_devinfo
->Valid
& ACPI_VALID_STA
)
933 aprint_normal(" STA 0x%08x\n",
934 ad
->ad_devinfo
->CurrentStatus
);
945 * Autoconfiguration print routine for ACPI node bus.
948 acpi_print(void *aux
, const char *pnp
)
950 struct acpi_attach_args
*aa
= aux
;
954 if (aa
->aa_node
->ad_devinfo
->Valid
& ACPI_VALID_HID
) {
956 aa
->aa_node
->ad_devinfo
->HardwareId
.String
;
959 aprint_normal("%s (%s) ", aa
->aa_node
->ad_name
,
962 rv
= acpi_eval_struct(aa
->aa_node
->ad_handle
,
964 if (ACPI_SUCCESS(rv
)) {
965 ACPI_OBJECT
*obj
= buf
.Pointer
;
967 case ACPI_TYPE_STRING
:
968 aprint_normal("[%s] ", obj
->String
.Pointer
);
970 case ACPI_TYPE_BUFFER
:
971 aprint_normal("buffer %p ", obj
->Buffer
.Pointer
);
974 aprint_normal("type %d ",obj
->Type
);
977 ACPI_FREE(buf
.Pointer
);
983 for (i
= 0; i
< __arraycount(acpi_knowndevs
);
985 if (strcmp(acpi_knowndevs
[i
].pnp
,
987 aprint_normal("[%s] ",
988 acpi_knowndevs
[i
].str
);
994 aprint_normal("at %s", pnp
);
995 } else if (aa
->aa_node
->ad_devinfo
->Type
!= ACPI_TYPE_DEVICE
) {
996 aprint_normal("%s (ACPI Object Type '%s' "
997 "[0x%02x]) ", aa
->aa_node
->ad_name
,
998 AcpiUtGetTypeName(aa
->aa_node
->ad_devinfo
->Type
),
999 aa
->aa_node
->ad_devinfo
->Type
);
1000 aprint_normal("at %s", pnp
);
1004 aprint_normal(" (%s", aa
->aa_node
->ad_name
);
1005 if (aa
->aa_node
->ad_devinfo
->Valid
& ACPI_VALID_HID
) {
1006 aprint_normal(", %s", aa
->aa_node
->ad_devinfo
->HardwareId
.String
);
1007 if (aa
->aa_node
->ad_devinfo
->Valid
& ACPI_VALID_UID
) {
1010 uid
= aa
->aa_node
->ad_devinfo
->UniqueId
.String
;
1013 aprint_normal("-%s", uid
);
1022 /*****************************************************************************
1023 * ACPI fixed-hardware feature handlers
1024 *****************************************************************************/
1026 static UINT32
acpi_fixed_button_handler(void *);
1027 static void acpi_fixed_button_pressed(void *);
1030 * acpi_enable_fixed_events:
1032 * Enable any fixed-hardware feature handlers.
1035 acpi_enable_fixed_events(struct acpi_softc
*sc
)
1037 static int beenhere
;
1040 KASSERT(beenhere
== 0);
1044 * Check for fixed-hardware buttons.
1047 if ((AcpiGbl_FADT
.Flags
& ACPI_FADT_POWER_BUTTON
) == 0) {
1048 aprint_verbose_dev(sc
->sc_dev
,
1049 "fixed-feature power button present\n");
1050 sc
->sc_smpsw_power
.smpsw_name
= device_xname(sc
->sc_dev
);
1051 sc
->sc_smpsw_power
.smpsw_type
= PSWITCH_TYPE_POWER
;
1052 if (sysmon_pswitch_register(&sc
->sc_smpsw_power
) != 0) {
1053 aprint_error_dev(sc
->sc_dev
,
1054 "unable to register fixed power "
1055 "button with sysmon\n");
1057 rv
= AcpiInstallFixedEventHandler(
1058 ACPI_EVENT_POWER_BUTTON
,
1059 acpi_fixed_button_handler
, &sc
->sc_smpsw_power
);
1060 if (ACPI_FAILURE(rv
)) {
1061 aprint_error_dev(sc
->sc_dev
,
1062 "unable to install handler "
1063 "for fixed power button: %s\n",
1064 AcpiFormatException(rv
));
1069 if ((AcpiGbl_FADT
.Flags
& ACPI_FADT_SLEEP_BUTTON
) == 0) {
1070 aprint_verbose_dev(sc
->sc_dev
,
1071 "fixed-feature sleep button present\n");
1072 sc
->sc_smpsw_sleep
.smpsw_name
= device_xname(sc
->sc_dev
);
1073 sc
->sc_smpsw_sleep
.smpsw_type
= PSWITCH_TYPE_SLEEP
;
1074 if (sysmon_pswitch_register(&sc
->sc_smpsw_power
) != 0) {
1075 aprint_error_dev(sc
->sc_dev
,
1076 "unable to register fixed sleep "
1077 "button with sysmon\n");
1079 rv
= AcpiInstallFixedEventHandler(
1080 ACPI_EVENT_SLEEP_BUTTON
,
1081 acpi_fixed_button_handler
, &sc
->sc_smpsw_sleep
);
1082 if (ACPI_FAILURE(rv
)) {
1083 aprint_error_dev(sc
->sc_dev
,
1084 "unable to install handler "
1085 "for fixed sleep button: %s\n",
1086 AcpiFormatException(rv
));
1093 * acpi_fixed_button_handler:
1095 * Event handler for the fixed buttons.
1098 acpi_fixed_button_handler(void *context
)
1100 struct sysmon_pswitch
*smpsw
= context
;
1103 #ifdef ACPI_BUT_DEBUG
1104 printf("%s: fixed button handler\n", smpsw
->smpsw_name
);
1107 rv
= AcpiOsExecute(OSL_NOTIFY_HANDLER
,
1108 acpi_fixed_button_pressed
, smpsw
);
1109 if (ACPI_FAILURE(rv
))
1110 printf("%s: WARNING: unable to queue fixed button pressed "
1111 "callback: %s\n", smpsw
->smpsw_name
,
1112 AcpiFormatException(rv
));
1114 return ACPI_INTERRUPT_HANDLED
;
1118 * acpi_fixed_button_pressed:
1120 * Deal with a fixed button being pressed.
1123 acpi_fixed_button_pressed(void *context
)
1125 struct sysmon_pswitch
*smpsw
= context
;
1127 #ifdef ACPI_BUT_DEBUG
1128 printf("%s: fixed button pressed, calling sysmon\n",
1132 sysmon_pswitch_event(smpsw
, PSWITCH_EVENT_PRESSED
);
1135 /*****************************************************************************
1136 * ACPI utility routines.
1137 *****************************************************************************/
1140 * acpi_eval_integer:
1142 * Evaluate an integer object.
1145 acpi_eval_integer(ACPI_HANDLE handle
, const char *path
, ACPI_INTEGER
*valp
)
1152 handle
= ACPI_ROOT_OBJECT
;
1154 buf
.Pointer
= ¶m
;
1155 buf
.Length
= sizeof(param
);
1157 rv
= AcpiEvaluateObjectTyped(handle
, path
, NULL
, &buf
,
1159 if (ACPI_SUCCESS(rv
))
1160 *valp
= param
.Integer
.Value
;
1166 acpi_eval_set_integer(ACPI_HANDLE handle
, const char *path
, ACPI_INTEGER arg
)
1168 ACPI_OBJECT param_arg
;
1169 ACPI_OBJECT_LIST param_args
;
1172 handle
= ACPI_ROOT_OBJECT
;
1174 param_arg
.Type
= ACPI_TYPE_INTEGER
;
1175 param_arg
.Integer
.Value
= arg
;
1177 param_args
.Count
= 1;
1178 param_args
.Pointer
= ¶m_arg
;
1180 return AcpiEvaluateObject(handle
, path
, ¶m_args
, NULL
);
1186 * Evaluate a (Unicode) string object.
1189 acpi_eval_string(ACPI_HANDLE handle
, const char *path
, char **stringp
)
1195 handle
= ACPI_ROOT_OBJECT
;
1198 buf
.Length
= ACPI_ALLOCATE_LOCAL_BUFFER
;
1200 rv
= AcpiEvaluateObjectTyped(handle
, path
, NULL
, &buf
, ACPI_TYPE_STRING
);
1201 if (ACPI_SUCCESS(rv
)) {
1202 ACPI_OBJECT
*param
= buf
.Pointer
;
1203 const char *ptr
= param
->String
.Pointer
;
1204 size_t len
= param
->String
.Length
;
1205 if ((*stringp
= ACPI_ALLOCATE(len
)) == NULL
)
1208 (void)memcpy(*stringp
, ptr
, len
);
1219 * Evaluate a more complex structure.
1220 * Caller must free buf.Pointer by ACPI_FREE().
1223 acpi_eval_struct(ACPI_HANDLE handle
, const char *path
, ACPI_BUFFER
*bufp
)
1228 handle
= ACPI_ROOT_OBJECT
;
1230 bufp
->Pointer
= NULL
;
1231 bufp
->Length
= ACPI_ALLOCATE_LOCAL_BUFFER
;
1233 rv
= AcpiEvaluateObject(handle
, path
, NULL
, bufp
);
1239 * acpi_foreach_package_object:
1241 * Iterate over all objects in a in a packages and pass then all
1242 * to a function. If the called function returns non AE_OK, the
1243 * iteration is stopped and that value is returned.
1247 acpi_foreach_package_object(ACPI_OBJECT
*pkg
,
1248 ACPI_STATUS (*func
)(ACPI_OBJECT
*, void *),
1251 ACPI_STATUS rv
= AE_OK
;
1254 if (pkg
== NULL
|| pkg
->Type
!= ACPI_TYPE_PACKAGE
)
1255 return AE_BAD_PARAMETER
;
1257 for (i
= 0; i
< pkg
->Package
.Count
; i
++) {
1258 rv
= (*func
)(&pkg
->Package
.Elements
[i
], arg
);
1259 if (ACPI_FAILURE(rv
))
1267 acpi_name(ACPI_HANDLE handle
)
1269 static char buffer
[80];
1273 buf
.Length
= sizeof(buffer
);
1274 buf
.Pointer
= buffer
;
1276 rv
= AcpiGetName(handle
, ACPI_FULL_PATHNAME
, &buf
);
1277 if (ACPI_FAILURE(rv
))
1278 return "(unknown acpi path)";
1285 * Fetch data info the specified (empty) ACPI buffer.
1286 * Caller must free buf.Pointer by ACPI_FREE().
1289 acpi_get(ACPI_HANDLE handle
, ACPI_BUFFER
*buf
,
1290 ACPI_STATUS (*getit
)(ACPI_HANDLE
, ACPI_BUFFER
*))
1292 buf
->Pointer
= NULL
;
1293 buf
->Length
= ACPI_ALLOCATE_LOCAL_BUFFER
;
1295 return (*getit
)(handle
, buf
);
1302 * Match given ids against _HID and _CIDs
1305 acpi_match_hid(ACPI_DEVICE_INFO
*ad
, const char * const *ids
)
1310 if (ad
->Valid
& ACPI_VALID_HID
) {
1311 if (pmatch(ad
->HardwareId
.String
, *ids
, NULL
) == 2)
1315 if (ad
->Valid
& ACPI_VALID_CID
) {
1316 for (i
= 0; i
< ad
->CompatibleIdList
.Count
; i
++) {
1317 if (pmatch(ad
->CompatibleIdList
.Ids
[i
].String
, *ids
, NULL
) == 2)
1328 * acpi_wake_gpe_helper
1330 * Set/unset GPE as both Runtime and Wake
1333 acpi_wake_gpe_helper(ACPI_HANDLE handle
, bool enable
)
1337 ACPI_OBJECT
*p
, *elt
;
1339 rv
= acpi_eval_struct(handle
, METHOD_NAME__PRW
, &buf
);
1340 if (ACPI_FAILURE(rv
))
1341 return; /* just ignore */
1344 if (p
->Type
!= ACPI_TYPE_PACKAGE
|| p
->Package
.Count
< 2)
1345 goto out
; /* just ignore */
1347 elt
= p
->Package
.Elements
;
1349 /* TBD: package support */
1351 AcpiSetGpeType(NULL
, elt
[0].Integer
.Value
,
1352 ACPI_GPE_TYPE_WAKE_RUN
);
1353 AcpiEnableGpe(NULL
, elt
[0].Integer
.Value
, ACPI_NOT_ISR
);
1355 AcpiDisableGpe(NULL
, elt
[0].Integer
.Value
, ACPI_NOT_ISR
);
1358 ACPI_FREE(buf
.Pointer
);
1362 * acpi_clear_wake_gpe
1364 * Clear GPE as both Runtime and Wake
1367 acpi_clear_wake_gpe(ACPI_HANDLE handle
)
1369 acpi_wake_gpe_helper(handle
, false);
1375 * Set GPE as both Runtime and Wake
1378 acpi_set_wake_gpe(ACPI_HANDLE handle
)
1380 acpi_wake_gpe_helper(handle
, true);
1384 /*****************************************************************************
1385 * ACPI sleep support.
1386 *****************************************************************************/
1389 is_available_state(struct acpi_softc
*sc
, int state
)
1391 UINT8 type_a
, type_b
;
1393 return ACPI_SUCCESS(AcpiGetSleepTypeData((UINT8
)state
,
1398 * acpi_enter_sleep_state:
1400 * enter to the specified sleep state.
1404 acpi_enter_sleep_state(struct acpi_softc
*sc
, int state
)
1407 ACPI_STATUS ret
= AE_OK
;
1409 if (state
== acpi_sleepstate
)
1412 aprint_normal_dev(sc
->sc_dev
, "entering state %d\n", state
);
1421 if (!is_available_state(sc
, state
)) {
1422 aprint_error_dev(sc
->sc_dev
,
1423 "ACPI S%d not available on this platform\n", state
);
1427 acpi_wakedev_commit(sc
);
1429 if (state
!= ACPI_STATE_S1
&& !pmf_system_suspend(PMF_Q_NONE
)) {
1430 aprint_error_dev(sc
->sc_dev
, "aborting suspend\n");
1434 ret
= AcpiEnterSleepStatePrep(state
);
1435 if (ACPI_FAILURE(ret
)) {
1436 aprint_error_dev(sc
->sc_dev
,
1437 "failed preparing to sleep (%s)\n",
1438 AcpiFormatException(ret
));
1442 acpi_sleepstate
= state
;
1443 if (state
== ACPI_STATE_S1
) {
1444 /* just enter the state */
1445 acpi_md_OsDisableInterrupt();
1446 ret
= AcpiEnterSleepState((UINT8
)state
);
1447 if (ACPI_FAILURE(ret
))
1448 aprint_error_dev(sc
->sc_dev
,
1449 "failed to enter sleep state S1: %s\n",
1450 AcpiFormatException(ret
));
1451 AcpiLeaveSleepState((UINT8
)state
);
1453 err
= acpi_md_sleep(state
);
1454 if (state
== ACPI_STATE_S4
)
1456 pmf_system_bus_resume(PMF_Q_NONE
);
1457 AcpiLeaveSleepState((UINT8
)state
);
1458 pmf_system_resume(PMF_Q_NONE
);
1463 ret
= AcpiEnterSleepStatePrep(ACPI_STATE_S5
);
1464 if (ACPI_FAILURE(ret
)) {
1465 aprint_error_dev(sc
->sc_dev
,
1466 "failed preparing to sleep (%s)\n",
1467 AcpiFormatException(ret
));
1471 acpi_sleepstate
= state
;
1472 acpi_md_OsDisableInterrupt();
1473 AcpiEnterSleepState(ACPI_STATE_S5
);
1474 aprint_error_dev(sc
->sc_dev
, "WARNING powerdown failed!\n");
1478 acpi_sleepstate
= ACPI_STATE_S0
;
1482 #if defined(ACPI_ACTIVATE_DEV)
1483 /* XXX This very incomplete */
1485 acpi_allocate_resources(ACPI_HANDLE handle
)
1487 ACPI_BUFFER bufp
, bufc
, bufn
;
1488 ACPI_RESOURCE
*resp
, *resc
, *resn
;
1489 ACPI_RESOURCE_IRQ
*irq
;
1490 ACPI_RESOURCE_EXTENDED_IRQ
*xirq
;
1494 rv
= acpi_get(handle
, &bufp
, AcpiGetPossibleResources
);
1495 if (ACPI_FAILURE(rv
))
1497 rv
= acpi_get(handle
, &bufc
, AcpiGetCurrentResources
);
1498 if (ACPI_FAILURE(rv
)) {
1503 bufn
.Pointer
= resn
= malloc(bufn
.Length
, M_ACPI
, M_WAITOK
);
1504 resp
= bufp
.Pointer
;
1505 resc
= bufc
.Pointer
;
1506 while (resc
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
&&
1507 resp
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
) {
1508 while (resc
->Type
!= resp
->Type
&& resp
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
)
1509 resp
= ACPI_NEXT_RESOURCE(resp
);
1510 if (resp
->Type
== ACPI_RESOURCE_TYPE_END_TAG
)
1512 /* Found identical Id */
1513 resn
->Type
= resc
->Type
;
1514 switch (resc
->Type
) {
1515 case ACPI_RESOURCE_TYPE_IRQ
:
1516 memcpy(&resn
->Data
, &resp
->Data
,
1517 sizeof(ACPI_RESOURCE_IRQ
));
1518 irq
= (ACPI_RESOURCE_IRQ
*)&resn
->Data
;
1519 irq
->Interrupts
[0] =
1520 ((ACPI_RESOURCE_IRQ
*)&resp
->Data
)->
1521 Interrupts
[irq
->InterruptCount
-1];
1522 irq
->InterruptCount
= 1;
1523 resn
->Length
= ACPI_RS_SIZE(ACPI_RESOURCE_IRQ
);
1525 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ
:
1526 memcpy(&resn
->Data
, &resp
->Data
,
1527 sizeof(ACPI_RESOURCE_EXTENDED_IRQ
));
1528 xirq
= (ACPI_RESOURCE_EXTENDED_IRQ
*)&resn
->Data
;
1531 * XXX not duplicating the interrupt logic above
1532 * because its not clear what it accomplishes.
1534 xirq
->Interrupts
[0] =
1535 ((ACPI_RESOURCE_EXT_IRQ
*)&resp
->Data
)->
1536 Interrupts
[irq
->NumberOfInterrupts
-1];
1537 xirq
->NumberOfInterrupts
= 1;
1539 resn
->Length
= ACPI_RS_SIZE(ACPI_RESOURCE_EXTENDED_IRQ
);
1541 case ACPI_RESOURCE_TYPE_IO
:
1542 memcpy(&resn
->Data
, &resp
->Data
,
1543 sizeof(ACPI_RESOURCE_IO
));
1544 resn
->Length
= resp
->Length
;
1547 printf("acpi_allocate_resources: res=%d\n", resc
->Type
);
1551 resc
= ACPI_NEXT_RESOURCE(resc
);
1552 resn
= ACPI_NEXT_RESOURCE(resn
);
1553 resp
= ACPI_NEXT_RESOURCE(resp
);
1554 delta
= (UINT8
*)resn
- (UINT8
*)bufn
.Pointer
;
1556 bufn
.Length
-ACPI_RS_SIZE(ACPI_RESOURCE_DATA
)) {
1558 bufn
.Pointer
= realloc(bufn
.Pointer
, bufn
.Length
,
1560 resn
= (ACPI_RESOURCE
*)((UINT8
*)bufn
.Pointer
+ delta
);
1563 if (resc
->Type
!= ACPI_RESOURCE_TYPE_END_TAG
) {
1564 printf("acpi_allocate_resources: resc not exhausted\n");
1569 resn
->Type
= ACPI_RESOURCE_TYPE_END_TAG
;
1570 rv
= AcpiSetCurrentResources(handle
, &bufn
);
1571 if (ACPI_FAILURE(rv
)) {
1572 printf("acpi_allocate_resources: AcpiSetCurrentResources %s\n",
1573 AcpiFormatException(rv
));
1577 free(bufn
.Pointer
, M_ACPI
);
1579 ACPI_FREE(bufc
.Pointer
);
1581 ACPI_FREE(bufp
.Pointer
);
1585 #endif /* ACPI_ACTIVATE_DEV */
1587 SYSCTL_SETUP(sysctl_acpi_setup
, "sysctl hw.acpi subtree setup")
1589 const struct sysctlnode
*node
;
1590 const struct sysctlnode
*ssnode
;
1592 if (sysctl_createv(clog
, 0, NULL
, NULL
,
1594 CTLTYPE_NODE
, "hw", NULL
,
1596 CTL_HW
, CTL_EOL
) != 0)
1599 if (sysctl_createv(clog
, 0, NULL
, &node
,
1601 CTLTYPE_NODE
, "acpi", NULL
,
1603 CTL_HW
, CTL_CREATE
, CTL_EOL
) != 0)
1606 sysctl_createv(NULL
, 0, NULL
, NULL
, CTLFLAG_READONLY
,
1607 CTLTYPE_QUAD
, "root",
1608 SYSCTL_DESCR("ACPI root pointer"),
1609 NULL
, 0, &acpi_root_pointer
, sizeof(acpi_root_pointer
),
1610 CTL_HW
, node
->sysctl_num
, CTL_CREATE
, CTL_EOL
);
1611 sysctl_createv(NULL
, 0, NULL
, NULL
, CTLFLAG_READONLY
,
1612 CTLTYPE_STRING
, "supported_states",
1613 SYSCTL_DESCR("Supported ACPI system states"),
1614 NULL
, 0, acpi_supported_states
, 0,
1615 CTL_HW
, node
->sysctl_num
, CTL_CREATE
, CTL_EOL
);
1617 /* ACPI sleepstate sysctl */
1618 if (sysctl_createv(NULL
, 0, NULL
, &node
,
1620 CTLTYPE_NODE
, "machdep", NULL
,
1621 NULL
, 0, NULL
, 0, CTL_MACHDEP
, CTL_EOL
) != 0)
1623 if (sysctl_createv(NULL
, 0, &node
, &ssnode
,
1624 CTLFLAG_READWRITE
, CTLTYPE_INT
, "sleep_state",
1625 NULL
, sysctl_hw_acpi_sleepstate
, 0, NULL
, 0, CTL_CREATE
,
1631 sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS
)
1634 struct sysctlnode node
;
1637 t
= acpi_sleepstate
;
1638 node
.sysctl_data
= &t
;
1639 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
1640 if (error
|| newp
== NULL
)
1643 if (acpi_softc
== NULL
)
1646 acpi_enter_sleep_state(acpi_softc
, t
);
1651 static ACPI_TABLE_HEADER
*
1654 ACPI_PHYSICAL_ADDRESS paddr
;
1655 ACPI_TABLE_RSDP
*rsdp
;
1657 paddr
= AcpiOsGetRootPointer();
1659 printf("ACPI: couldn't get root pointer\n");
1662 rsdp
= AcpiOsMapMemory(paddr
, sizeof(ACPI_TABLE_RSDP
));
1664 printf("ACPI: couldn't map RSDP\n");
1667 if (rsdp
->Revision
> 1 && rsdp
->XsdtPhysicalAddress
)
1668 paddr
= (ACPI_PHYSICAL_ADDRESS
)rsdp
->XsdtPhysicalAddress
;
1670 paddr
= (ACPI_PHYSICAL_ADDRESS
)rsdp
->RsdtPhysicalAddress
;
1671 AcpiOsUnmapMemory(rsdp
, sizeof(ACPI_TABLE_RSDP
));
1673 return AcpiOsMapMemory(paddr
, sizeof(ACPI_TABLE_HEADER
));
1677 acpi_unmap_rsdt(ACPI_TABLE_HEADER
*rsdt
)
1682 AcpiOsUnmapMemory(rsdt
, sizeof(ACPI_TABLE_HEADER
));