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