Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/acpi Fix a bug involving acpitz(4) accidentally atta...



details:   https://anonhg.NetBSD.org/src/rev/da8eeb8dfb1d
branches:  trunk
changeset: 754238:da8eeb8dfb1d
user:      jruoho <jruoho%NetBSD.org@localhost>
date:      Sat Apr 24 13:42:18 2010 +0000

description:
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.

diffstat:

 sys/dev/acpi/acpi.c |  86 +++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 70 insertions(+), 16 deletions(-)

diffs (162 lines):

diff -r 5e5df8be0c47 -r da8eeb8dfb1d sys/dev/acpi/acpi.c
--- a/sys/dev/acpi/acpi.c       Sat Apr 24 11:26:15 2010 +0000
+++ b/sys/dev/acpi/acpi.c       Sat Apr 24 13:42:18 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: acpi.c,v 1.184 2010/04/23 18:51:31 jruoho Exp $        */
+/*     $NetBSD: acpi.c,v 1.185 2010/04/24 13:42:18 jruoho Exp $        */
 
 /*-
  * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.184 2010/04/23 18:51:31 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.185 2010/04/24 13:42:18 jruoho Exp $");
 
 #include "opt_acpi.h"
 #include "opt_pcifixup.h"
@@ -127,6 +127,7 @@
 struct acpi_softc *acpi_softc;
 static uint64_t acpi_root_pointer;
 extern kmutex_t acpi_interrupt_list_mtx;
+static ACPI_HANDLE acpi_scopes[4];
 
 /*
  * This structure provides a context for the ACPI
@@ -203,8 +204,9 @@
 static int             sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS);
 static int             sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS);
 
+static bool              acpi_is_scope(struct acpi_devnode *);
 static ACPI_TABLE_HEADER *acpi_map_rsdt(void);
-static void            acpi_unmap_rsdt(ACPI_TABLE_HEADER *);
+static void              acpi_unmap_rsdt(ACPI_TABLE_HEADER *);
 
 extern struct cfdriver acpi_cd;
 
@@ -584,6 +586,19 @@
 {
        struct acpi_walkcontext awc;
 
+       /*
+        * Get the root scope handles.
+        */
+       KASSERT(__arraycount(acpi_scopes) == 4);
+
+       (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_PR_", &acpi_scopes[0]);
+       (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_PB_", &acpi_scopes[1]);
+       (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_PI_", &acpi_scopes[2]);
+       (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_TZ_", &acpi_scopes[3]);
+
+       /*
+        * Make the root node.
+        */
        awc.aw_sc = sc;
        awc.aw_parent = NULL;
 
@@ -594,9 +609,15 @@
 
        sc->sc_root = awc.aw_parent;
 
+       /*
+        * Build the internal namespace.
+        */
        (void)AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, UINT32_MAX,
            acpi_make_devnode, acpi_make_devnode_post, &awc, NULL);
 
+       /*
+        * Scan the internal namespace.
+        */
        acpi_rescan1(sc, NULL, NULL);
        acpi_rescan_capabilities(sc);
 
@@ -964,18 +985,18 @@
                if (ad->ad_device != NULL)
                        continue;
 
-               aa.aa_node = ad;
-               aa.aa_iot = sc->sc_iot;
-               aa.aa_memt = sc->sc_memt;
-               aa.aa_pc = sc->sc_pc;
-               aa.aa_pciflags = sc->sc_pciflags;
-               aa.aa_ic = sc->sc_ic;
+               /*
+                * There is a bug in ACPICA: it defines the type
+                * of the scopes incorrectly for its own reasons.
+                */
+               if (acpi_is_scope(ad) != false)
+                       continue;
 
                /*
-                * XXX: We only attach devices which are present, enabled, and
-                *      functioning properly. However, if a device is enabled,
-                *      it is decoding resources and we should claim these,
-                *      if possible. This requires changes to bus_space(9).
+                * We only attach devices which are present, enabled, and
+                * functioning properly. However, if a device is enabled,
+                * it is decoding resources and we should claim these,
+                * if possible. This requires changes to bus_space(9).
                 */
                if (ad->ad_devinfo->Type == ACPI_TYPE_DEVICE) {
 
@@ -990,9 +1011,9 @@
                }
 
                /*
-                * XXX: The same problem as above. As for example
-                *      thermal zones and power resources do not
-                *      have a valid HID, only evaluate devices.
+                * The same problem as above. As for example
+                * thermal zones and power resources do not
+                * have a valid HID, only evaluate devices.
                 */
                if (ad->ad_devinfo->Type == ACPI_TYPE_DEVICE &&
                    (ad->ad_devinfo->Valid & ACPI_VALID_HID) == 0)
@@ -1018,6 +1039,13 @@
                if (acpi_match_hid(ad->ad_devinfo, acpi_ignored_ids))
                        continue;
 
+               aa.aa_node = ad;
+               aa.aa_iot = sc->sc_iot;
+               aa.aa_memt = sc->sc_memt;
+               aa.aa_pc = sc->sc_pc;
+               aa.aa_pciflags = sc->sc_pciflags;
+               aa.aa_ic = sc->sc_ic;
+
                ad->ad_device = config_found_ia(sc->sc_dev,
                    "acpinodebus", &aa, acpi_print);
        }
@@ -1666,6 +1694,32 @@
 /*
  * Miscellaneous.
  */
+static bool
+acpi_is_scope(struct acpi_devnode *ad)
+{
+       int i;
+
+       /*
+        * Return true if the node is a root scope.
+        */
+       if (ad->ad_parent == NULL)
+               return false;
+
+       if (ad->ad_parent->ad_handle != ACPI_ROOT_OBJECT)
+               return false;
+
+       for (i = 0; i < __arraycount(acpi_scopes); i++) {
+
+               if (acpi_scopes[i] == NULL)
+                       continue;
+
+               if (ad->ad_handle == acpi_scopes[i])
+                       return true;
+       }
+
+       return false;
+}
+
 ACPI_PHYSICAL_ADDRESS
 acpi_OsGetRootPointer(void)
 {



Home | Main Index | Thread Index | Old Index