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