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