Sat Apr 24 13:42:19 2010 UTC ()
Fix a bug involving acpitz(4) accidentally attaching to the _TZ_ scope.

This in turn was caused by a bug in ACPICA, which reports the types of _SB_
and _TZ_ scopes incorrectly for its own internal reasons (utglobal.c):

  /*
   * Predefined ACPI Names (Built-in to the Interpreter)
   *
   * NOTES:
   * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run
   *    during the initialization sequence.
   * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to
   *    perform a Notify() operation on it.
   */

Thanks to cegger@ for noticing the bug and testing a fix.


(jruoho)
diff -r1.184 -r1.185 src/sys/dev/acpi/acpi.c

cvs diff -r1.184 -r1.185 src/sys/dev/acpi/acpi.c (expand / switch to unified diff)

--- src/sys/dev/acpi/acpi.c 2010/04/23 18:51:31 1.184
+++ src/sys/dev/acpi/acpi.c 2010/04/24 13:42:18 1.185
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: acpi.c,v 1.184 2010/04/23 18:51:31 jruoho Exp $ */ 1/* $NetBSD: acpi.c,v 1.185 2010/04/24 13:42:18 jruoho Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc. 4 * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum of By Noon Software, Inc. 8 * by Charles M. Hannum of By Noon Software, Inc.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -55,27 +55,27 @@ @@ -55,27 +55,27 @@
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
56 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 56 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 57 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 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 61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
64 * POSSIBILITY OF SUCH DAMAGE. 64 * POSSIBILITY OF SUCH DAMAGE.
65 */ 65 */
66 66
67#include <sys/cdefs.h> 67#include <sys/cdefs.h>
68__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.184 2010/04/23 18:51:31 jruoho Exp $"); 68__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.185 2010/04/24 13:42:18 jruoho Exp $");
69 69
70#include "opt_acpi.h" 70#include "opt_acpi.h"
71#include "opt_pcifixup.h" 71#include "opt_pcifixup.h"
72 72
73#include <sys/param.h> 73#include <sys/param.h>
74#include <sys/device.h> 74#include <sys/device.h>
75#include <sys/kernel.h> 75#include <sys/kernel.h>
76#include <sys/malloc.h> 76#include <sys/malloc.h>
77#include <sys/mutex.h> 77#include <sys/mutex.h>
78#include <sys/sysctl.h> 78#include <sys/sysctl.h>
79#include <sys/systm.h> 79#include <sys/systm.h>
80 80
81#include <dev/acpi/acpireg.h> 81#include <dev/acpi/acpireg.h>
@@ -117,26 +117,27 @@ static int acpi_dbgr = 0x00; @@ -117,26 +117,27 @@ static int acpi_dbgr = 0x00;
117 117
118/* 118/*
119 * This is a flag we set when the ACPI subsystem is active. Machine 119 * This is a flag we set when the ACPI subsystem is active. Machine
120 * dependent code may wish to skip other steps (such as attaching 120 * dependent code may wish to skip other steps (such as attaching
121 * subsystems that ACPI supercedes) when ACPI is active. 121 * subsystems that ACPI supercedes) when ACPI is active.
122 */ 122 */
123int acpi_active; 123int acpi_active;
124int acpi_force_load; 124int acpi_force_load;
125int acpi_suspended = 0; 125int acpi_suspended = 0;
126 126
127struct acpi_softc *acpi_softc; 127struct acpi_softc *acpi_softc;
128static uint64_t acpi_root_pointer; 128static uint64_t acpi_root_pointer;
129extern kmutex_t acpi_interrupt_list_mtx; 129extern kmutex_t acpi_interrupt_list_mtx;
 130static ACPI_HANDLE acpi_scopes[4];
130 131
131/* 132/*
132 * This structure provides a context for the ACPI 133 * This structure provides a context for the ACPI
133 * namespace walk performed in acpi_build_tree(). 134 * namespace walk performed in acpi_build_tree().
134 */ 135 */
135struct acpi_walkcontext { 136struct acpi_walkcontext {
136 struct acpi_softc *aw_sc; 137 struct acpi_softc *aw_sc;
137 struct acpi_devnode *aw_parent; 138 struct acpi_devnode *aw_parent;
138}; 139};
139 140
140/* 141/*
141 * Ignored HIDs. 142 * Ignored HIDs.
142 */ 143 */
@@ -193,28 +194,29 @@ static int acpi_print(void *aux, const  @@ -193,28 +194,29 @@ static int acpi_print(void *aux, const
193static void acpi_notify_handler(ACPI_HANDLE, uint32_t, void *); 194static void acpi_notify_handler(ACPI_HANDLE, uint32_t, void *);
194 195
195static void acpi_register_fixed_button(struct acpi_softc *, int); 196static void acpi_register_fixed_button(struct acpi_softc *, int);
196static void acpi_deregister_fixed_button(struct acpi_softc *, int); 197static void acpi_deregister_fixed_button(struct acpi_softc *, int);
197static uint32_t acpi_fixed_button_handler(void *); 198static uint32_t acpi_fixed_button_handler(void *);
198static void acpi_fixed_button_pressed(void *); 199static void acpi_fixed_button_pressed(void *);
199 200
200static void acpi_sleep_init(struct acpi_softc *); 201static void acpi_sleep_init(struct acpi_softc *);
201 202
202static int sysctl_hw_acpi_fixedstats(SYSCTLFN_ARGS); 203static int sysctl_hw_acpi_fixedstats(SYSCTLFN_ARGS);
203static int sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS); 204static int sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS);
204static int sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS); 205static int sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS);
205 206
 207static bool acpi_is_scope(struct acpi_devnode *);
206static ACPI_TABLE_HEADER *acpi_map_rsdt(void); 208static ACPI_TABLE_HEADER *acpi_map_rsdt(void);
207static void acpi_unmap_rsdt(ACPI_TABLE_HEADER *); 209static void acpi_unmap_rsdt(ACPI_TABLE_HEADER *);
208 210
209extern struct cfdriver acpi_cd; 211extern struct cfdriver acpi_cd;
210 212
211CFATTACH_DECL2_NEW(acpi, sizeof(struct acpi_softc), 213CFATTACH_DECL2_NEW(acpi, sizeof(struct acpi_softc),
212 acpi_match, acpi_attach, acpi_detach, NULL, acpi_rescan, acpi_childdet); 214 acpi_match, acpi_attach, acpi_detach, NULL, acpi_rescan, acpi_childdet);
213 215
214/* 216/*
215 * Probe for ACPI support. 217 * Probe for ACPI support.
216 * 218 *
217 * This is called by the machine-dependent ACPI front-end. 219 * This is called by the machine-dependent ACPI front-end.
218 * Note: this is not an autoconfiguration interface function. 220 * Note: this is not an autoconfiguration interface function.
219 */ 221 */
220int 222int
@@ -574,39 +576,58 @@ acpi_resume(device_t dv, const pmf_qual_ @@ -574,39 +576,58 @@ acpi_resume(device_t dv, const pmf_qual_
574 acpi_suspended = 0; 576 acpi_suspended = 0;
575 577
576 return true; 578 return true;
577} 579}
578 580
579/* 581/*
580 * Namespace scan. 582 * Namespace scan.
581 */ 583 */
582static void 584static void
583acpi_build_tree(struct acpi_softc *sc) 585acpi_build_tree(struct acpi_softc *sc)
584{ 586{
585 struct acpi_walkcontext awc; 587 struct acpi_walkcontext awc;
586 588
 589 /*
 590 * Get the root scope handles.
 591 */
 592 KASSERT(__arraycount(acpi_scopes) == 4);
 593
 594 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_PR_", &acpi_scopes[0]);
 595 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_PB_", &acpi_scopes[1]);
 596 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_PI_", &acpi_scopes[2]);
 597 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_TZ_", &acpi_scopes[3]);
 598
 599 /*
 600 * Make the root node.
 601 */
587 awc.aw_sc = sc; 602 awc.aw_sc = sc;
588 awc.aw_parent = NULL; 603 awc.aw_parent = NULL;
589 604
590 (void)acpi_make_devnode(ACPI_ROOT_OBJECT, 0, &awc, NULL); 605 (void)acpi_make_devnode(ACPI_ROOT_OBJECT, 0, &awc, NULL);
591 606
592 KASSERT(sc->sc_root == NULL); 607 KASSERT(sc->sc_root == NULL);
593 KASSERT(awc.aw_parent != NULL); 608 KASSERT(awc.aw_parent != NULL);
594 609
595 sc->sc_root = awc.aw_parent; 610 sc->sc_root = awc.aw_parent;
596 611
 612 /*
 613 * Build the internal namespace.
 614 */
597 (void)AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, UINT32_MAX, 615 (void)AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, UINT32_MAX,
598 acpi_make_devnode, acpi_make_devnode_post, &awc, NULL); 616 acpi_make_devnode, acpi_make_devnode_post, &awc, NULL);
599 617
 618 /*
 619 * Scan the internal namespace.
 620 */
600 acpi_rescan1(sc, NULL, NULL); 621 acpi_rescan1(sc, NULL, NULL);
601 acpi_rescan_capabilities(sc); 622 acpi_rescan_capabilities(sc);
602 623
603 (void)acpi_pcidev_scan(sc->sc_root); 624 (void)acpi_pcidev_scan(sc->sc_root);
604 625
605#ifdef ACPIVERBOSE 626#ifdef ACPIVERBOSE
606 aprint_normal("\n"); 627 aprint_normal("\n");
607 acpi_print_tree(sc->sc_root, 0); 628 acpi_print_tree(sc->sc_root, 0);
608#endif 629#endif
609} 630}
610 631
611#ifdef ACPIVERBOSE 632#ifdef ACPIVERBOSE
612static void 633static void
@@ -954,80 +975,87 @@ acpi_rescan1(struct acpi_softc *sc, cons @@ -954,80 +975,87 @@ acpi_rescan1(struct acpi_softc *sc, cons
954} 975}
955 976
956static void 977static void
957acpi_rescan_nodes(struct acpi_softc *sc) 978acpi_rescan_nodes(struct acpi_softc *sc)
958{ 979{
959 struct acpi_attach_args aa; 980 struct acpi_attach_args aa;
960 struct acpi_devnode *ad; 981 struct acpi_devnode *ad;
961 982
962 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 983 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
963 984
964 if (ad->ad_device != NULL) 985 if (ad->ad_device != NULL)
965 continue; 986 continue;
966 987
967 aa.aa_node = ad; 988 /*
968 aa.aa_iot = sc->sc_iot; 989 * There is a bug in ACPICA: it defines the type
969 aa.aa_memt = sc->sc_memt; 990 * of the scopes incorrectly for its own reasons.
970 aa.aa_pc = sc->sc_pc; 991 */
971 aa.aa_pciflags = sc->sc_pciflags; 992 if (acpi_is_scope(ad) != false)
972 aa.aa_ic = sc->sc_ic; 993 continue;
973 994
974 /* 995 /*
975 * XXX: We only attach devices which are present, enabled, and 996 * We only attach devices which are present, enabled, and
976 * functioning properly. However, if a device is enabled, 997 * functioning properly. However, if a device is enabled,
977 * it is decoding resources and we should claim these, 998 * it is decoding resources and we should claim these,
978 * if possible. This requires changes to bus_space(9). 999 * if possible. This requires changes to bus_space(9).
979 */ 1000 */
980 if (ad->ad_devinfo->Type == ACPI_TYPE_DEVICE) { 1001 if (ad->ad_devinfo->Type == ACPI_TYPE_DEVICE) {
981 1002
982 if ((ad->ad_devinfo->Valid & ACPI_VALID_STA) == 1003 if ((ad->ad_devinfo->Valid & ACPI_VALID_STA) ==
983 ACPI_VALID_STA && 1004 ACPI_VALID_STA &&
984 (ad->ad_devinfo->CurrentStatus & 1005 (ad->ad_devinfo->CurrentStatus &
985 (ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED| 1006 (ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED|
986 ACPI_STA_DEV_OK)) != 1007 ACPI_STA_DEV_OK)) !=
987 (ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED| 1008 (ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED|
988 ACPI_STA_DEV_OK)) 1009 ACPI_STA_DEV_OK))
989 continue; 1010 continue;
990 } 1011 }
991 1012
992 /* 1013 /*
993 * XXX: The same problem as above. As for example 1014 * The same problem as above. As for example
994 * thermal zones and power resources do not 1015 * thermal zones and power resources do not
995 * have a valid HID, only evaluate devices. 1016 * have a valid HID, only evaluate devices.
996 */ 1017 */
997 if (ad->ad_devinfo->Type == ACPI_TYPE_DEVICE && 1018 if (ad->ad_devinfo->Type == ACPI_TYPE_DEVICE &&
998 (ad->ad_devinfo->Valid & ACPI_VALID_HID) == 0) 1019 (ad->ad_devinfo->Valid & ACPI_VALID_HID) == 0)
999 continue; 1020 continue;
1000 1021
1001 /* 1022 /*
1002 * Handled internally. 1023 * Handled internally.
1003 */ 1024 */
1004 if (ad->ad_devinfo->Type == ACPI_TYPE_PROCESSOR) 1025 if (ad->ad_devinfo->Type == ACPI_TYPE_PROCESSOR)
1005 continue; 1026 continue;
1006 1027
1007 /* 1028 /*
1008 * Ditto, but bind power resources. 1029 * Ditto, but bind power resources.
1009 */ 1030 */
1010 if (ad->ad_devinfo->Type == ACPI_TYPE_POWER) { 1031 if (ad->ad_devinfo->Type == ACPI_TYPE_POWER) {
1011 acpi_power_res_add(ad); 1032 acpi_power_res_add(ad);
1012 continue; 1033 continue;
1013 } 1034 }
1014 1035
1015 /* 1036 /*
1016 * Skip ignored HIDs. 1037 * Skip ignored HIDs.
1017 */ 1038 */
1018 if (acpi_match_hid(ad->ad_devinfo, acpi_ignored_ids)) 1039 if (acpi_match_hid(ad->ad_devinfo, acpi_ignored_ids))
1019 continue; 1040 continue;
1020 1041
 1042 aa.aa_node = ad;
 1043 aa.aa_iot = sc->sc_iot;
 1044 aa.aa_memt = sc->sc_memt;
 1045 aa.aa_pc = sc->sc_pc;
 1046 aa.aa_pciflags = sc->sc_pciflags;
 1047 aa.aa_ic = sc->sc_ic;
 1048
1021 ad->ad_device = config_found_ia(sc->sc_dev, 1049 ad->ad_device = config_found_ia(sc->sc_dev,
1022 "acpinodebus", &aa, acpi_print); 1050 "acpinodebus", &aa, acpi_print);
1023 } 1051 }
1024} 1052}
1025 1053
1026#define ACPI_STA_DEV_VALID \ 1054#define ACPI_STA_DEV_VALID \
1027 (ACPI_STA_DEV_PRESENT | ACPI_STA_DEV_ENABLED | ACPI_STA_DEV_OK) 1055 (ACPI_STA_DEV_PRESENT | ACPI_STA_DEV_ENABLED | ACPI_STA_DEV_OK)
1028 1056
1029static void 1057static void
1030acpi_rescan_capabilities(struct acpi_softc *sc) 1058acpi_rescan_capabilities(struct acpi_softc *sc)
1031{ 1059{
1032 struct acpi_devnode *ad; 1060 struct acpi_devnode *ad;
1033 ACPI_DEVICE_INFO *di; 1061 ACPI_DEVICE_INFO *di;
@@ -1656,26 +1684,52 @@ sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS @@ -1656,26 +1684,52 @@ sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS
1656 node.sysctl_data = &t; 1684 node.sysctl_data = &t;
1657 1685
1658 err = sysctl_lookup(SYSCTLFN_CALL(&node)); 1686 err = sysctl_lookup(SYSCTLFN_CALL(&node));
1659 1687
1660 if (err || newp == NULL) 1688 if (err || newp == NULL)
1661 return err; 1689 return err;
1662 1690
1663 return 0; 1691 return 0;
1664} 1692}
1665 1693
1666/* 1694/*
1667 * Miscellaneous. 1695 * Miscellaneous.
1668 */ 1696 */
 1697static bool
 1698acpi_is_scope(struct acpi_devnode *ad)
 1699{
 1700 int i;
 1701
 1702 /*
 1703 * Return true if the node is a root scope.
 1704 */
 1705 if (ad->ad_parent == NULL)
 1706 return false;
 1707
 1708 if (ad->ad_parent->ad_handle != ACPI_ROOT_OBJECT)
 1709 return false;
 1710
 1711 for (i = 0; i < __arraycount(acpi_scopes); i++) {
 1712
 1713 if (acpi_scopes[i] == NULL)
 1714 continue;
 1715
 1716 if (ad->ad_handle == acpi_scopes[i])
 1717 return true;
 1718 }
 1719
 1720 return false;
 1721}
 1722
1669ACPI_PHYSICAL_ADDRESS 1723ACPI_PHYSICAL_ADDRESS
1670acpi_OsGetRootPointer(void) 1724acpi_OsGetRootPointer(void)
1671{ 1725{
1672 ACPI_PHYSICAL_ADDRESS PhysicalAddress; 1726 ACPI_PHYSICAL_ADDRESS PhysicalAddress;
1673 1727
1674 /* 1728 /*
1675 * We let MD code handle this since there are multiple ways to do it: 1729 * We let MD code handle this since there are multiple ways to do it:
1676 * 1730 *
1677 * IA-32: Use AcpiFindRootPointer() to locate the RSDP. 1731 * IA-32: Use AcpiFindRootPointer() to locate the RSDP.
1678 * 1732 *
1679 * IA-64: Use the EFI. 1733 * IA-64: Use the EFI.
1680 */ 1734 */
1681 PhysicalAddress = acpi_md_OsGetRootPointer(); 1735 PhysicalAddress = acpi_md_OsGetRootPointer();