[ACPI]
authorCameron Gutman <aicommander@gmail.com>
Thu, 29 Sep 2011 20:57:14 +0000 (20:57 +0000)
committerCameron Gutman <aicommander@gmail.com>
Thu, 29 Sep 2011 20:57:14 +0000 (20:57 +0000)
- Update ACPICA from 20091214 to 20110922
- Rewrite a large portion of the OSL code
- Perform a full initialization of ACPI objects (don't skip devices and events)
- Please retest ACPI bugs after this commit

svn path=/trunk/; revision=53895

179 files changed:
reactos/drivers/bus/acpi/CMakeLists.txt
reactos/drivers/bus/acpi/acpi.rbuild
reactos/drivers/bus/acpi/acpica/acpica.rbuild
reactos/drivers/bus/acpi/acpica/dispatcher/dsargs.c [new file with mode: 0644]
reactos/drivers/bus/acpi/acpica/dispatcher/dscontrol.c [new file with mode: 0644]
reactos/drivers/bus/acpi/acpica/dispatcher/dsfield.c
reactos/drivers/bus/acpi/acpica/dispatcher/dsinit.c
reactos/drivers/bus/acpi/acpica/dispatcher/dsmethod.c
reactos/drivers/bus/acpi/acpica/dispatcher/dsmthdat.c
reactos/drivers/bus/acpi/acpica/dispatcher/dsobject.c
reactos/drivers/bus/acpi/acpica/dispatcher/dsopcode.c
reactos/drivers/bus/acpi/acpica/dispatcher/dsutils.c
reactos/drivers/bus/acpi/acpica/dispatcher/dswexec.c
reactos/drivers/bus/acpi/acpica/dispatcher/dswload.c
reactos/drivers/bus/acpi/acpica/dispatcher/dswload2.c [new file with mode: 0644]
reactos/drivers/bus/acpi/acpica/dispatcher/dswscope.c
reactos/drivers/bus/acpi/acpica/dispatcher/dswstate.c
reactos/drivers/bus/acpi/acpica/events/evevent.c
reactos/drivers/bus/acpi/acpica/events/evglock.c [new file with mode: 0644]
reactos/drivers/bus/acpi/acpica/events/evgpe.c
reactos/drivers/bus/acpi/acpica/events/evgpeblk.c
reactos/drivers/bus/acpi/acpica/events/evgpeinit.c [new file with mode: 0644]
reactos/drivers/bus/acpi/acpica/events/evgpeutil.c [new file with mode: 0644]
reactos/drivers/bus/acpi/acpica/events/evmisc.c
reactos/drivers/bus/acpi/acpica/events/evregion.c
reactos/drivers/bus/acpi/acpica/events/evrgnini.c
reactos/drivers/bus/acpi/acpica/events/evsci.c
reactos/drivers/bus/acpi/acpica/events/evxface.c
reactos/drivers/bus/acpi/acpica/events/evxfevnt.c
reactos/drivers/bus/acpi/acpica/events/evxfgpe.c [new file with mode: 0644]
reactos/drivers/bus/acpi/acpica/events/evxfregn.c
reactos/drivers/bus/acpi/acpica/executer/exconfig.c
reactos/drivers/bus/acpi/acpica/executer/exconvrt.c
reactos/drivers/bus/acpi/acpica/executer/excreate.c
reactos/drivers/bus/acpi/acpica/executer/exdebug.c [new file with mode: 0644]
reactos/drivers/bus/acpi/acpica/executer/exdump.c
reactos/drivers/bus/acpi/acpica/executer/exfield.c
reactos/drivers/bus/acpi/acpica/executer/exfldio.c
reactos/drivers/bus/acpi/acpica/executer/exmisc.c
reactos/drivers/bus/acpi/acpica/executer/exmutex.c
reactos/drivers/bus/acpi/acpica/executer/exnames.c
reactos/drivers/bus/acpi/acpica/executer/exoparg1.c
reactos/drivers/bus/acpi/acpica/executer/exoparg2.c
reactos/drivers/bus/acpi/acpica/executer/exoparg3.c
reactos/drivers/bus/acpi/acpica/executer/exoparg6.c
reactos/drivers/bus/acpi/acpica/executer/exprep.c
reactos/drivers/bus/acpi/acpica/executer/exregion.c
reactos/drivers/bus/acpi/acpica/executer/exresnte.c
reactos/drivers/bus/acpi/acpica/executer/exresolv.c
reactos/drivers/bus/acpi/acpica/executer/exresop.c
reactos/drivers/bus/acpi/acpica/executer/exstore.c
reactos/drivers/bus/acpi/acpica/executer/exstoren.c
reactos/drivers/bus/acpi/acpica/executer/exstorob.c
reactos/drivers/bus/acpi/acpica/executer/exsystem.c
reactos/drivers/bus/acpi/acpica/executer/exutils.c
reactos/drivers/bus/acpi/acpica/hardware/hwacpi.c
reactos/drivers/bus/acpi/acpica/hardware/hwgpe.c
reactos/drivers/bus/acpi/acpica/hardware/hwpci.c [new file with mode: 0644]
reactos/drivers/bus/acpi/acpica/hardware/hwregs.c
reactos/drivers/bus/acpi/acpica/hardware/hwsleep.c
reactos/drivers/bus/acpi/acpica/hardware/hwtimer.c
reactos/drivers/bus/acpi/acpica/hardware/hwvalid.c
reactos/drivers/bus/acpi/acpica/hardware/hwxface.c
reactos/drivers/bus/acpi/acpica/include/acapps.h
reactos/drivers/bus/acpi/acpica/include/accommon.h
reactos/drivers/bus/acpi/acpica/include/acconfig.h
reactos/drivers/bus/acpi/acpica/include/acdebug.h
reactos/drivers/bus/acpi/acpica/include/acdisasm.h
reactos/drivers/bus/acpi/acpica/include/acdispat.h
reactos/drivers/bus/acpi/acpica/include/acevents.h
reactos/drivers/bus/acpi/acpica/include/acexcep.h
reactos/drivers/bus/acpi/acpica/include/acglobal.h
reactos/drivers/bus/acpi/acpica/include/achware.h
reactos/drivers/bus/acpi/acpica/include/acinterp.h
reactos/drivers/bus/acpi/acpica/include/aclocal.h
reactos/drivers/bus/acpi/acpica/include/acmacros.h
reactos/drivers/bus/acpi/acpica/include/acnames.h
reactos/drivers/bus/acpi/acpica/include/acnamesp.h
reactos/drivers/bus/acpi/acpica/include/acobject.h
reactos/drivers/bus/acpi/acpica/include/acopcode.h
reactos/drivers/bus/acpi/acpica/include/acoutput.h
reactos/drivers/bus/acpi/acpica/include/acparser.h
reactos/drivers/bus/acpi/acpica/include/acpi.h
reactos/drivers/bus/acpi/acpica/include/acpiosxf.h
reactos/drivers/bus/acpi/acpica/include/acpixf.h
reactos/drivers/bus/acpi/acpica/include/acpredef.h
reactos/drivers/bus/acpi/acpica/include/acresrc.h
reactos/drivers/bus/acpi/acpica/include/acrestyp.h
reactos/drivers/bus/acpi/acpica/include/acstruct.h
reactos/drivers/bus/acpi/acpica/include/actables.h
reactos/drivers/bus/acpi/acpica/include/actbl.h
reactos/drivers/bus/acpi/acpica/include/actbl1.h
reactos/drivers/bus/acpi/acpica/include/actbl2.h
reactos/drivers/bus/acpi/acpica/include/actypes.h
reactos/drivers/bus/acpi/acpica/include/acutils.h
reactos/drivers/bus/acpi/acpica/include/amlcode.h
reactos/drivers/bus/acpi/acpica/include/amlresrc.h
reactos/drivers/bus/acpi/acpica/include/platform/accygwin.h
reactos/drivers/bus/acpi/acpica/include/platform/acefi.h
reactos/drivers/bus/acpi/acpica/include/platform/acenv.h
reactos/drivers/bus/acpi/acpica/include/platform/acfreebsd.h
reactos/drivers/bus/acpi/acpica/include/platform/acgcc.h
reactos/drivers/bus/acpi/acpica/include/platform/acintel.h
reactos/drivers/bus/acpi/acpica/include/platform/aclinux.h
reactos/drivers/bus/acpi/acpica/include/platform/acmsvc.h
reactos/drivers/bus/acpi/acpica/include/platform/acnetbsd.h
reactos/drivers/bus/acpi/acpica/include/platform/acos2.h
reactos/drivers/bus/acpi/acpica/include/platform/acwin.h
reactos/drivers/bus/acpi/acpica/include/platform/acwin64.h
reactos/drivers/bus/acpi/acpica/namespace/nsaccess.c
reactos/drivers/bus/acpi/acpica/namespace/nsalloc.c
reactos/drivers/bus/acpi/acpica/namespace/nsdump.c
reactos/drivers/bus/acpi/acpica/namespace/nsdumpdv.c
reactos/drivers/bus/acpi/acpica/namespace/nseval.c
reactos/drivers/bus/acpi/acpica/namespace/nsinit.c
reactos/drivers/bus/acpi/acpica/namespace/nsload.c
reactos/drivers/bus/acpi/acpica/namespace/nsnames.c
reactos/drivers/bus/acpi/acpica/namespace/nsobject.c
reactos/drivers/bus/acpi/acpica/namespace/nsparse.c
reactos/drivers/bus/acpi/acpica/namespace/nspredef.c
reactos/drivers/bus/acpi/acpica/namespace/nsrepair.c
reactos/drivers/bus/acpi/acpica/namespace/nsrepair2.c
reactos/drivers/bus/acpi/acpica/namespace/nssearch.c
reactos/drivers/bus/acpi/acpica/namespace/nsutils.c
reactos/drivers/bus/acpi/acpica/namespace/nswalk.c
reactos/drivers/bus/acpi/acpica/namespace/nsxfeval.c
reactos/drivers/bus/acpi/acpica/namespace/nsxfname.c
reactos/drivers/bus/acpi/acpica/namespace/nsxfobj.c
reactos/drivers/bus/acpi/acpica/parser/psargs.c
reactos/drivers/bus/acpi/acpica/parser/psloop.c
reactos/drivers/bus/acpi/acpica/parser/psopcode.c
reactos/drivers/bus/acpi/acpica/parser/psparse.c
reactos/drivers/bus/acpi/acpica/parser/psscope.c
reactos/drivers/bus/acpi/acpica/parser/pstree.c
reactos/drivers/bus/acpi/acpica/parser/psutils.c
reactos/drivers/bus/acpi/acpica/parser/pswalk.c
reactos/drivers/bus/acpi/acpica/parser/psxface.c
reactos/drivers/bus/acpi/acpica/resources/rsaddr.c
reactos/drivers/bus/acpi/acpica/resources/rscalc.c
reactos/drivers/bus/acpi/acpica/resources/rscreate.c
reactos/drivers/bus/acpi/acpica/resources/rsdump.c
reactos/drivers/bus/acpi/acpica/resources/rsinfo.c
reactos/drivers/bus/acpi/acpica/resources/rsio.c
reactos/drivers/bus/acpi/acpica/resources/rsirq.c
reactos/drivers/bus/acpi/acpica/resources/rslist.c
reactos/drivers/bus/acpi/acpica/resources/rsmemory.c
reactos/drivers/bus/acpi/acpica/resources/rsmisc.c
reactos/drivers/bus/acpi/acpica/resources/rsutils.c
reactos/drivers/bus/acpi/acpica/resources/rsxface.c
reactos/drivers/bus/acpi/acpica/tables/tbfadt.c
reactos/drivers/bus/acpi/acpica/tables/tbfind.c
reactos/drivers/bus/acpi/acpica/tables/tbinstal.c
reactos/drivers/bus/acpi/acpica/tables/tbutils.c
reactos/drivers/bus/acpi/acpica/tables/tbxface.c
reactos/drivers/bus/acpi/acpica/tables/tbxfroot.c
reactos/drivers/bus/acpi/acpica/utilities/utalloc.c
reactos/drivers/bus/acpi/acpica/utilities/utcache.c
reactos/drivers/bus/acpi/acpica/utilities/utclib.c
reactos/drivers/bus/acpi/acpica/utilities/utcopy.c
reactos/drivers/bus/acpi/acpica/utilities/utdebug.c
reactos/drivers/bus/acpi/acpica/utilities/utdecode.c [new file with mode: 0644]
reactos/drivers/bus/acpi/acpica/utilities/utdelete.c
reactos/drivers/bus/acpi/acpica/utilities/uteval.c
reactos/drivers/bus/acpi/acpica/utilities/utglobal.c
reactos/drivers/bus/acpi/acpica/utilities/utids.c
reactos/drivers/bus/acpi/acpica/utilities/utinit.c
reactos/drivers/bus/acpi/acpica/utilities/utlock.c
reactos/drivers/bus/acpi/acpica/utilities/utmath.c
reactos/drivers/bus/acpi/acpica/utilities/utmisc.c
reactos/drivers/bus/acpi/acpica/utilities/utmutex.c
reactos/drivers/bus/acpi/acpica/utilities/utobject.c
reactos/drivers/bus/acpi/acpica/utilities/utosi.c [new file with mode: 0644]
reactos/drivers/bus/acpi/acpica/utilities/utresrc.c
reactos/drivers/bus/acpi/acpica/utilities/utstate.c
reactos/drivers/bus/acpi/acpica/utilities/uttrack.c
reactos/drivers/bus/acpi/acpica/utilities/utxface.c
reactos/drivers/bus/acpi/acpica/utilities/utxferror.c [new file with mode: 0644]
reactos/drivers/bus/acpi/busmgr/bus.c
reactos/drivers/bus/acpi/osl.c

index 903ee9e..9b22dbd 100644 (file)
@@ -8,6 +8,8 @@ if(ARCH MATCHES amd64)
 endif()
 
 add_library(acpica
+    acpica/dispatcher/dsargs.c
+    acpica/dispatcher/dscontrol.c
     acpica/dispatcher/dsfield.c
     acpica/dispatcher/dsinit.c
     acpica/dispatcher/dsmethod.c
@@ -17,21 +19,27 @@ add_library(acpica
     acpica/dispatcher/dsutils.c
     acpica/dispatcher/dswexec.c
     acpica/dispatcher/dswload.c
+    acpica/dispatcher/dswload2.c
     acpica/dispatcher/dswscope.c
     acpica/dispatcher/dswstate.c
     acpica/events/evevent.c
+    acpica/events/evglock.c
     acpica/events/evgpe.c
     acpica/events/evgpeblk.c
+    acpica/events/evgpeinit.c
+    acpica/events/evgpeutil.c
     acpica/events/evmisc.c
     acpica/events/evregion.c
     acpica/events/evrgnini.c
     acpica/events/evsci.c
     acpica/events/evxface.c
     acpica/events/evxfevnt.c
+    acpica/events/evxfgpe.c
     acpica/events/evxfregn.c
     acpica/executer/exconfig.c
     acpica/executer/exconvrt.c
     acpica/executer/excreate.c
+    acpica/executer/exdebug.c
     acpica/executer/exdump.c
     acpica/executer/exfield.c
     acpica/executer/exfldio.c
@@ -54,6 +62,7 @@ add_library(acpica
     acpica/executer/exutils.c
     acpica/hardware/hwacpi.c
     acpica/hardware/hwgpe.c
+    acpica/hardware/hwpci.c
     acpica/hardware/hwregs.c
     acpica/hardware/hwsleep.c
     acpica/hardware/hwtimer.c
@@ -110,6 +119,7 @@ add_library(acpica
     acpica/utilities/utclib.c
     acpica/utilities/utcopy.c
     acpica/utilities/utdebug.c
+    acpica/utilities/utdecode.c
     acpica/utilities/utdelete.c
     acpica/utilities/uteval.c
     acpica/utilities/utglobal.c
@@ -120,12 +130,14 @@ add_library(acpica
     acpica/utilities/utmisc.c
     acpica/utilities/utmutex.c
     acpica/utilities/utobject.c
+    acpica/utilities/utosi.c
     acpica/utilities/utresrc.c
     acpica/utilities/utstate.c
     acpica/utilities/uttrack.c
-    acpica/utilities/utxface.c)
+    acpica/utilities/utxface.c
+    acpica/utilities/utxferror.c)
 
-allow_warnings(acpica)
+set_target_properties(acpica PROPERTIES COMPILE_DEFINITIONS "ACPI_USE_LOCAL_CACHE")
 add_dependencies(acpica bugcodes)
 
 add_library(acpi SHARED
@@ -143,9 +155,8 @@ add_library(acpi SHARED
     buspdo.c
     main.c)
 
-allow_warnings(acpi)
 set_module_type(acpi kernelmodedriver)
-target_link_libraries(acpi wdmguid acpica)
+target_link_libraries(acpi wdmguid acpica ${PSEH_LIB})
 add_importlibs(acpi ntoskrnl hal)
 add_cd_file(TARGET acpi DESTINATION reactos/system32/drivers NO_CAB FOR all)
 
index a33498a..a534187 100644 (file)
@@ -17,7 +17,7 @@
        </group>
 </if>
 
-<module name="acpi" type="kernelmodedriver" installbase="system32/drivers" installname="acpi.sys" allowwarnings="true">
+<module name="acpi" type="kernelmodedriver" installbase="system32/drivers" installname="acpi.sys">
        <bootstrap installbase="$(CDOUTPUT)/system32/drivers" />
        <include base="acpi">include</include>
        <include base="acpica">include</include>
@@ -25,6 +25,7 @@
        <library>hal</library>
        <library>wdmguid</library>
        <library>acpica</library>
+    <library>pseh</library>
        <directory name="busmgr">
                <file>bus.c</file>
                <file>button.c</file>
index 719e125..6f4f93e 100644 (file)
@@ -1,8 +1,11 @@
 <?xml version="1.0"?>
 <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
-<module name="acpica" type="staticlibrary" allowwarnings="true">
+<module name="acpica" type="staticlibrary">
+    <define name="ACPI_USE_LOCAL_CACHE"/>
        <include base="acpica">include</include>
        <directory name="dispatcher">
+               <file>dsargs.c</file>
+               <file>dscontrol.c</file>
                <file>dsfield.c</file>
                <file>dsinit.c</file>
                <file>dsmethod.c</file>
                <file>dsutils.c</file>
                <file>dswexec.c</file>
                <file>dswload.c</file>
+               <file>dswload2.c</file>
                <file>dswscope.c</file>
                <file>dswstate.c</file>
        </directory>
        <directory name="events">
                <file>evevent.c</file>
+               <file>evglock.c</file>
                <file>evgpe.c</file>
                <file>evgpeblk.c</file>
+               <file>evgpeinit.c</file>
+               <file>evgpeutil.c</file>
                <file>evmisc.c</file>
                <file>evregion.c</file>
                <file>evrgnini.c</file>
                <file>evsci.c</file>
                <file>evxface.c</file>
                <file>evxfevnt.c</file>
+               <file>evxfgpe.c</file>
                <file>evxfregn.c</file>
        </directory>
        <directory name="executer">
                <file>exconfig.c</file>
                <file>exconvrt.c</file>
                <file>excreate.c</file>
+               <file>exdebug.c</file>
                <file>exdump.c</file>
                <file>exfield.c</file>
                <file>exfldio.c</file>
@@ -55,6 +64,7 @@
        <directory name="hardware">
                <file>hwacpi.c</file>
                <file>hwgpe.c</file>
+               <file>hwpci.c</file>
                <file>hwregs.c</file>
                <file>hwsleep.c</file>
                <file>hwtimer.c</file>
                <file>utclib.c</file>
                <file>utcopy.c</file>
                <file>utdebug.c</file>
+               <file>utdecode.c</file>
                <file>utdelete.c</file>
                <file>uteval.c</file>
                <file>utglobal.c</file>
                <file>utmisc.c</file>
                <file>utmutex.c</file>
                <file>utobject.c</file>
+               <file>utosi.c</file>
                <file>utresrc.c</file>
                <file>utstate.c</file>
                <file>uttrack.c</file>
                <file>utxface.c</file>
+               <file>utxferror.c</file>
        </directory>
 </module>
diff --git a/reactos/drivers/bus/acpi/acpica/dispatcher/dsargs.c b/reactos/drivers/bus/acpi/acpica/dispatcher/dsargs.c
new file mode 100644 (file)
index 0000000..44cc41b
--- /dev/null
@@ -0,0 +1,502 @@
+/******************************************************************************
+ *
+ * Module Name: dsargs - Support for execution of dynamic arguments for static
+ *                       objects (regions, fields, buffer fields, etc.)
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * 1. Copyright Notice
+ *
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
+ * All rights reserved.
+ *
+ * 2. License
+ *
+ * 2.1. This is your license from Intel Corp. under its intellectual property
+ * rights.  You may have additional license terms from the party that provided
+ * you this software, covering your right to use that party's intellectual
+ * property rights.
+ *
+ * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
+ * copy of the source code appearing in this file ("Covered Code") an
+ * irrevocable, perpetual, worldwide license under Intel's copyrights in the
+ * base code distributed originally by Intel ("Original Intel Code") to copy,
+ * make derivatives, distribute, use and display any portion of the Covered
+ * Code in any form, with the right to sublicense such rights; and
+ *
+ * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
+ * license (with the right to sublicense), under only those claims of Intel
+ * patents that are infringed by the Original Intel Code, to make, use, sell,
+ * offer to sell, and import the Covered Code and derivative works thereof
+ * solely to the minimum extent necessary to exercise the above copyright
+ * license, and in no event shall the patent license extend to any additions
+ * to or modifications of the Original Intel Code.  No other license or right
+ * is granted directly or by implication, estoppel or otherwise;
+ *
+ * The above copyright and patent license is granted only if the following
+ * conditions are met:
+ *
+ * 3. Conditions
+ *
+ * 3.1. Redistribution of Source with Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification with rights to further distribute source must include
+ * the above Copyright Notice, the above License, this list of Conditions,
+ * and the following Disclaimer and Export Compliance provision.  In addition,
+ * Licensee must cause all Covered Code to which Licensee contributes to
+ * contain a file documenting the changes Licensee made to create that Covered
+ * Code and the date of any change.  Licensee must include in that file the
+ * documentation of any changes made by any predecessor Licensee.  Licensee
+ * must include a prominent statement that the modification is derived,
+ * directly or indirectly, from Original Intel Code.
+ *
+ * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification without rights to further distribute source must
+ * include the following Disclaimer and Export Compliance provision in the
+ * documentation and/or other materials provided with distribution.  In
+ * addition, Licensee may not authorize further sublicense of source of any
+ * portion of the Covered Code, and must include terms to the effect that the
+ * license from Licensee to its licensee is limited to the intellectual
+ * property embodied in the software Licensee provides to its licensee, and
+ * not to intellectual property embodied in modifications its licensee may
+ * make.
+ *
+ * 3.3. Redistribution of Executable. Redistribution in executable form of any
+ * substantial portion of the Covered Code or modification must reproduce the
+ * above Copyright Notice, and the following Disclaimer and Export Compliance
+ * provision in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3.4. Intel retains all right, title, and interest in and to the Original
+ * Intel Code.
+ *
+ * 3.5. Neither the name Intel nor any other trademark owned or controlled by
+ * Intel shall be used in advertising or otherwise to promote the sale, use or
+ * other dealings in products derived from or relating to the Covered Code
+ * without prior written authorization from Intel.
+ *
+ * 4. Disclaimer and Export Compliance
+ *
+ * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
+ * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
+ * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
+ * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
+ * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
+ * PARTICULAR PURPOSE.
+ *
+ * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
+ * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
+ * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
+ * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
+ * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
+ * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
+ * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
+ * LIMITED REMEDY.
+ *
+ * 4.3. Licensee shall not export, either directly or indirectly, any of this
+ * software or system incorporating such software without first obtaining any
+ * required license or other approval from the U. S. Department of Commerce or
+ * any other agency or department of the United States Government.  In the
+ * event Licensee exports any such software from the United States or
+ * re-exports any such software from a foreign destination, Licensee shall
+ * ensure that the distribution and export/re-export of the software is in
+ * compliance with all laws, regulations, orders, or other restrictions of the
+ * U.S. Export Administration Regulations. Licensee agrees that neither it nor
+ * any of its subsidiaries will export/re-export any technical data, process,
+ * software, or service, directly or indirectly, to any country for which the
+ * United States government or any agency thereof requires an export license,
+ * other governmental approval, or letter of assurance, without first obtaining
+ * such license, approval or letter.
+ *
+ *****************************************************************************/
+
+#define __DSARGS_C__
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acparser.h"
+#include "amlcode.h"
+#include "acdispat.h"
+#include "acnamesp.h"
+
+#define _COMPONENT          ACPI_DISPATCHER
+        ACPI_MODULE_NAME    ("dsargs")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDsExecuteArguments (
+    ACPI_NAMESPACE_NODE     *Node,
+    ACPI_NAMESPACE_NODE     *ScopeNode,
+    UINT32                  AmlLength,
+    UINT8                   *AmlStart);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsExecuteArguments
+ *
+ * PARAMETERS:  Node                - Object NS node
+ *              ScopeNode           - Parent NS node
+ *              AmlLength           - Length of executable AML
+ *              AmlStart            - Pointer to the AML
+ *
+ * RETURN:      Status.
+ *
+ * DESCRIPTION: Late (deferred) execution of region or field arguments
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsExecuteArguments (
+    ACPI_NAMESPACE_NODE     *Node,
+    ACPI_NAMESPACE_NODE     *ScopeNode,
+    UINT32                  AmlLength,
+    UINT8                   *AmlStart)
+{
+    ACPI_STATUS             Status;
+    ACPI_PARSE_OBJECT       *Op;
+    ACPI_WALK_STATE         *WalkState;
+
+
+    ACPI_FUNCTION_TRACE (DsExecuteArguments);
+
+
+    /* Allocate a new parser op to be the root of the parsed tree */
+
+    Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
+    if (!Op)
+    {
+        return_ACPI_STATUS (AE_NO_MEMORY);
+    }
+
+    /* Save the Node for use in AcpiPsParseAml */
+
+    Op->Common.Node = ScopeNode;
+
+    /* Create and initialize a new parser state */
+
+    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
+    if (!WalkState)
+    {
+        Status = AE_NO_MEMORY;
+        goto Cleanup;
+    }
+
+    Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
+                    AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
+    if (ACPI_FAILURE (Status))
+    {
+        AcpiDsDeleteWalkState (WalkState);
+        goto Cleanup;
+    }
+
+    /* Mark this parse as a deferred opcode */
+
+    WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP;
+    WalkState->DeferredNode = Node;
+
+    /* Pass1: Parse the entire declaration */
+
+    Status = AcpiPsParseAml (WalkState);
+    if (ACPI_FAILURE (Status))
+    {
+        goto Cleanup;
+    }
+
+    /* Get and init the Op created above */
+
+    Op->Common.Node = Node;
+    AcpiPsDeleteParseTree (Op);
+
+    /* Evaluate the deferred arguments */
+
+    Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
+    if (!Op)
+    {
+        return_ACPI_STATUS (AE_NO_MEMORY);
+    }
+
+    Op->Common.Node = ScopeNode;
+
+    /* Create and initialize a new parser state */
+
+    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
+    if (!WalkState)
+    {
+        Status = AE_NO_MEMORY;
+        goto Cleanup;
+    }
+
+    /* Execute the opcode and arguments */
+
+    Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
+                    AmlLength, NULL, ACPI_IMODE_EXECUTE);
+    if (ACPI_FAILURE (Status))
+    {
+        AcpiDsDeleteWalkState (WalkState);
+        goto Cleanup;
+    }
+
+    /* Mark this execution as a deferred opcode */
+
+    WalkState->DeferredNode = Node;
+    Status = AcpiPsParseAml (WalkState);
+
+Cleanup:
+    AcpiPsDeleteParseTree (Op);
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsGetBufferFieldArguments
+ *
+ * PARAMETERS:  ObjDesc         - A valid BufferField object
+ *
+ * RETURN:      Status.
+ *
+ * DESCRIPTION: Get BufferField Buffer and Index. This implements the late
+ *              evaluation of these field attributes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetBufferFieldArguments (
+    ACPI_OPERAND_OBJECT     *ObjDesc)
+{
+    ACPI_OPERAND_OBJECT     *ExtraDesc;
+    ACPI_NAMESPACE_NODE     *Node;
+    ACPI_STATUS             Status;
+
+
+    ACPI_FUNCTION_TRACE_PTR (DsGetBufferFieldArguments, ObjDesc);
+
+
+    if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
+    {
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    /* Get the AML pointer (method object) and BufferField node */
+
+    ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
+    Node = ObjDesc->BufferField.Node;
+
+    ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_BUFFER_FIELD,
+        Node, NULL));
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
+        AcpiUtGetNodeName (Node)));
+
+    /* Execute the AML code for the TermArg arguments */
+
+    Status = AcpiDsExecuteArguments (Node, Node->Parent,
+                ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsGetBankFieldArguments
+ *
+ * PARAMETERS:  ObjDesc         - A valid BankField object
+ *
+ * RETURN:      Status.
+ *
+ * DESCRIPTION: Get BankField BankValue. This implements the late
+ *              evaluation of these field attributes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetBankFieldArguments (
+    ACPI_OPERAND_OBJECT     *ObjDesc)
+{
+    ACPI_OPERAND_OBJECT     *ExtraDesc;
+    ACPI_NAMESPACE_NODE     *Node;
+    ACPI_STATUS             Status;
+
+
+    ACPI_FUNCTION_TRACE_PTR (DsGetBankFieldArguments, ObjDesc);
+
+
+    if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
+    {
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    /* Get the AML pointer (method object) and BankField node */
+
+    ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
+    Node = ObjDesc->BankField.Node;
+
+    ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_LOCAL_BANK_FIELD,
+        Node, NULL));
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
+        AcpiUtGetNodeName (Node)));
+
+    /* Execute the AML code for the TermArg arguments */
+
+    Status = AcpiDsExecuteArguments (Node, Node->Parent,
+                ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsGetBufferArguments
+ *
+ * PARAMETERS:  ObjDesc         - A valid Buffer object
+ *
+ * RETURN:      Status.
+ *
+ * DESCRIPTION: Get Buffer length and initializer byte list. This implements
+ *              the late evaluation of these attributes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetBufferArguments (
+    ACPI_OPERAND_OBJECT     *ObjDesc)
+{
+    ACPI_NAMESPACE_NODE     *Node;
+    ACPI_STATUS             Status;
+
+
+    ACPI_FUNCTION_TRACE_PTR (DsGetBufferArguments, ObjDesc);
+
+
+    if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
+    {
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    /* Get the Buffer node */
+
+    Node = ObjDesc->Buffer.Node;
+    if (!Node)
+    {
+        ACPI_ERROR ((AE_INFO,
+            "No pointer back to namespace node in buffer object %p", ObjDesc));
+        return_ACPI_STATUS (AE_AML_INTERNAL);
+    }
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
+
+    /* Execute the AML code for the TermArg arguments */
+
+    Status = AcpiDsExecuteArguments (Node, Node,
+                ObjDesc->Buffer.AmlLength, ObjDesc->Buffer.AmlStart);
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsGetPackageArguments
+ *
+ * PARAMETERS:  ObjDesc         - A valid Package object
+ *
+ * RETURN:      Status.
+ *
+ * DESCRIPTION: Get Package length and initializer byte list. This implements
+ *              the late evaluation of these attributes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetPackageArguments (
+    ACPI_OPERAND_OBJECT     *ObjDesc)
+{
+    ACPI_NAMESPACE_NODE     *Node;
+    ACPI_STATUS             Status;
+
+
+    ACPI_FUNCTION_TRACE_PTR (DsGetPackageArguments, ObjDesc);
+
+
+    if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
+    {
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    /* Get the Package node */
+
+    Node = ObjDesc->Package.Node;
+    if (!Node)
+    {
+        ACPI_ERROR ((AE_INFO,
+            "No pointer back to namespace node in package %p", ObjDesc));
+        return_ACPI_STATUS (AE_AML_INTERNAL);
+    }
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n"));
+
+    /* Execute the AML code for the TermArg arguments */
+
+    Status = AcpiDsExecuteArguments (Node, Node,
+                ObjDesc->Package.AmlLength, ObjDesc->Package.AmlStart);
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsGetRegionArguments
+ *
+ * PARAMETERS:  ObjDesc         - A valid region object
+ *
+ * RETURN:      Status.
+ *
+ * DESCRIPTION: Get region address and length. This implements the late
+ *              evaluation of these region attributes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetRegionArguments (
+    ACPI_OPERAND_OBJECT     *ObjDesc)
+{
+    ACPI_NAMESPACE_NODE     *Node;
+    ACPI_STATUS             Status;
+    ACPI_OPERAND_OBJECT     *ExtraDesc;
+
+
+    ACPI_FUNCTION_TRACE_PTR (DsGetRegionArguments, ObjDesc);
+
+
+    if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
+    {
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
+    if (!ExtraDesc)
+    {
+        return_ACPI_STATUS (AE_NOT_EXIST);
+    }
+
+    /* Get the Region node */
+
+    Node = ObjDesc->Region.Node;
+
+    ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_REGION, Node, NULL));
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
+        AcpiUtGetNodeName (Node), ExtraDesc->Extra.AmlStart));
+
+    /* Execute the argument AML */
+
+    Status = AcpiDsExecuteArguments (Node, Node->Parent,
+                ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
+    return_ACPI_STATUS (Status);
+}
diff --git a/reactos/drivers/bus/acpi/acpica/dispatcher/dscontrol.c b/reactos/drivers/bus/acpi/acpica/dispatcher/dscontrol.c
new file mode 100644 (file)
index 0000000..41435e0
--- /dev/null
@@ -0,0 +1,496 @@
+/******************************************************************************
+ *
+ * Module Name: dscontrol - Support for execution control opcodes -
+ *                          if/else/while/return
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * 1. Copyright Notice
+ *
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
+ * All rights reserved.
+ *
+ * 2. License
+ *
+ * 2.1. This is your license from Intel Corp. under its intellectual property
+ * rights.  You may have additional license terms from the party that provided
+ * you this software, covering your right to use that party's intellectual
+ * property rights.
+ *
+ * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
+ * copy of the source code appearing in this file ("Covered Code") an
+ * irrevocable, perpetual, worldwide license under Intel's copyrights in the
+ * base code distributed originally by Intel ("Original Intel Code") to copy,
+ * make derivatives, distribute, use and display any portion of the Covered
+ * Code in any form, with the right to sublicense such rights; and
+ *
+ * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
+ * license (with the right to sublicense), under only those claims of Intel
+ * patents that are infringed by the Original Intel Code, to make, use, sell,
+ * offer to sell, and import the Covered Code and derivative works thereof
+ * solely to the minimum extent necessary to exercise the above copyright
+ * license, and in no event shall the patent license extend to any additions
+ * to or modifications of the Original Intel Code.  No other license or right
+ * is granted directly or by implication, estoppel or otherwise;
+ *
+ * The above copyright and patent license is granted only if the following
+ * conditions are met:
+ *
+ * 3. Conditions
+ *
+ * 3.1. Redistribution of Source with Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification with rights to further distribute source must include
+ * the above Copyright Notice, the above License, this list of Conditions,
+ * and the following Disclaimer and Export Compliance provision.  In addition,
+ * Licensee must cause all Covered Code to which Licensee contributes to
+ * contain a file documenting the changes Licensee made to create that Covered
+ * Code and the date of any change.  Licensee must include in that file the
+ * documentation of any changes made by any predecessor Licensee.  Licensee
+ * must include a prominent statement that the modification is derived,
+ * directly or indirectly, from Original Intel Code.
+ *
+ * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification without rights to further distribute source must
+ * include the following Disclaimer and Export Compliance provision in the
+ * documentation and/or other materials provided with distribution.  In
+ * addition, Licensee may not authorize further sublicense of source of any
+ * portion of the Covered Code, and must include terms to the effect that the
+ * license from Licensee to its licensee is limited to the intellectual
+ * property embodied in the software Licensee provides to its licensee, and
+ * not to intellectual property embodied in modifications its licensee may
+ * make.
+ *
+ * 3.3. Redistribution of Executable. Redistribution in executable form of any
+ * substantial portion of the Covered Code or modification must reproduce the
+ * above Copyright Notice, and the following Disclaimer and Export Compliance
+ * provision in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3.4. Intel retains all right, title, and interest in and to the Original
+ * Intel Code.
+ *
+ * 3.5. Neither the name Intel nor any other trademark owned or controlled by
+ * Intel shall be used in advertising or otherwise to promote the sale, use or
+ * other dealings in products derived from or relating to the Covered Code
+ * without prior written authorization from Intel.
+ *
+ * 4. Disclaimer and Export Compliance
+ *
+ * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
+ * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
+ * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
+ * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
+ * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
+ * PARTICULAR PURPOSE.
+ *
+ * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
+ * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
+ * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
+ * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
+ * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
+ * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
+ * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
+ * LIMITED REMEDY.
+ *
+ * 4.3. Licensee shall not export, either directly or indirectly, any of this
+ * software or system incorporating such software without first obtaining any
+ * required license or other approval from the U. S. Department of Commerce or
+ * any other agency or department of the United States Government.  In the
+ * event Licensee exports any such software from the United States or
+ * re-exports any such software from a foreign destination, Licensee shall
+ * ensure that the distribution and export/re-export of the software is in
+ * compliance with all laws, regulations, orders, or other restrictions of the
+ * U.S. Export Administration Regulations. Licensee agrees that neither it nor
+ * any of its subsidiaries will export/re-export any technical data, process,
+ * software, or service, directly or indirectly, to any country for which the
+ * United States government or any agency thereof requires an export license,
+ * other governmental approval, or letter of assurance, without first obtaining
+ * such license, approval or letter.
+ *
+ *****************************************************************************/
+
+#define __DSCONTROL_C__
+
+#include "acpi.h"
+#include "accommon.h"
+#include "amlcode.h"
+#include "acdispat.h"
+#include "acinterp.h"
+
+#define _COMPONENT          ACPI_DISPATCHER
+        ACPI_MODULE_NAME    ("dscontrol")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsExecBeginControlOp
+ *
+ * PARAMETERS:  WalkList        - The list that owns the walk stack
+ *              Op              - The control Op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Handles all control ops encountered during control method
+ *              execution.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsExecBeginControlOp (
+    ACPI_WALK_STATE         *WalkState,
+    ACPI_PARSE_OBJECT       *Op)
+{
+    ACPI_STATUS             Status = AE_OK;
+    ACPI_GENERIC_STATE      *ControlState;
+
+
+    ACPI_FUNCTION_NAME (DsExecBeginControlOp);
+
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n",
+        Op, Op->Common.AmlOpcode, WalkState));
+
+    switch (Op->Common.AmlOpcode)
+    {
+    case AML_WHILE_OP:
+
+        /*
+         * If this is an additional iteration of a while loop, continue.
+         * There is no need to allocate a new control state.
+         */
+        if (WalkState->ControlState)
+        {
+            if (WalkState->ControlState->Control.AmlPredicateStart ==
+                (WalkState->ParserState.Aml - 1))
+            {
+                /* Reset the state to start-of-loop */
+
+                WalkState->ControlState->Common.State =
+                    ACPI_CONTROL_CONDITIONAL_EXECUTING;
+                break;
+            }
+        }
+
+        /*lint -fallthrough */
+
+    case AML_IF_OP:
+
+        /*
+         * IF/WHILE: Create a new control state to manage these
+         * constructs. We need to manage these as a stack, in order
+         * to handle nesting.
+         */
+        ControlState = AcpiUtCreateControlState ();
+        if (!ControlState)
+        {
+            Status = AE_NO_MEMORY;
+            break;
+        }
+        /*
+         * Save a pointer to the predicate for multiple executions
+         * of a loop
+         */
+        ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1;
+        ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd;
+        ControlState->Control.Opcode = Op->Common.AmlOpcode;
+
+
+        /* Push the control state on this walk's control stack */
+
+        AcpiUtPushGenericState (&WalkState->ControlState, ControlState);
+        break;
+
+    case AML_ELSE_OP:
+
+        /* Predicate is in the state object */
+        /* If predicate is true, the IF was executed, ignore ELSE part */
+
+        if (WalkState->LastPredicate)
+        {
+            Status = AE_CTRL_TRUE;
+        }
+
+        break;
+
+    case AML_RETURN_OP:
+
+        break;
+
+    default:
+        break;
+    }
+
+    return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsExecEndControlOp
+ *
+ * PARAMETERS:  WalkList        - The list that owns the walk stack
+ *              Op              - The control Op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Handles all control ops encountered during control method
+ *              execution.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsExecEndControlOp (
+    ACPI_WALK_STATE         *WalkState,
+    ACPI_PARSE_OBJECT       *Op)
+{
+    ACPI_STATUS             Status = AE_OK;
+    ACPI_GENERIC_STATE      *ControlState;
+
+
+    ACPI_FUNCTION_NAME (DsExecEndControlOp);
+
+
+    switch (Op->Common.AmlOpcode)
+    {
+    case AML_IF_OP:
+
+        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op));
+
+        /*
+         * Save the result of the predicate in case there is an
+         * ELSE to come
+         */
+        WalkState->LastPredicate =
+            (BOOLEAN) WalkState->ControlState->Common.Value;
+
+        /*
+         * Pop the control state that was created at the start
+         * of the IF and free it
+         */
+        ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
+        AcpiUtDeleteGenericState (ControlState);
+        break;
+
+
+    case AML_ELSE_OP:
+
+        break;
+
+
+    case AML_WHILE_OP:
+
+        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op));
+
+        ControlState = WalkState->ControlState;
+        if (ControlState->Common.Value)
+        {
+            /* Predicate was true, the body of the loop was just executed */
+
+            /*
+             * This loop counter mechanism allows the interpreter to escape
+             * possibly infinite loops. This can occur in poorly written AML
+             * when the hardware does not respond within a while loop and the
+             * loop does not implement a timeout.
+             */
+            ControlState->Control.LoopCount++;
+            if (ControlState->Control.LoopCount > ACPI_MAX_LOOP_ITERATIONS)
+            {
+                Status = AE_AML_INFINITE_LOOP;
+                break;
+            }
+
+            /*
+             * Go back and evaluate the predicate and maybe execute the loop
+             * another time
+             */
+            Status = AE_CTRL_PENDING;
+            WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart;
+            break;
+        }
+
+        /* Predicate was false, terminate this while loop */
+
+        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+            "[WHILE_OP] termination! Op=%p\n",Op));
+
+        /* Pop this control state and free it */
+
+        ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
+        AcpiUtDeleteGenericState (ControlState);
+        break;
+
+
+    case AML_RETURN_OP:
+
+        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+            "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg));
+
+        /*
+         * One optional operand -- the return value
+         * It can be either an immediate operand or a result that
+         * has been bubbled up the tree
+         */
+        if (Op->Common.Value.Arg)
+        {
+            /* Since we have a real Return(), delete any implicit return */
+
+            AcpiDsClearImplicitReturn (WalkState);
+
+            /* Return statement has an immediate operand */
+
+            Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
+            if (ACPI_FAILURE (Status))
+            {
+                return (Status);
+            }
+
+            /*
+             * If value being returned is a Reference (such as
+             * an arg or local), resolve it now because it may
+             * cease to exist at the end of the method.
+             */
+            Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
+            if (ACPI_FAILURE (Status))
+            {
+                return (Status);
+            }
+
+            /*
+             * Get the return value and save as the last result
+             * value.  This is the only place where WalkState->ReturnDesc
+             * is set to anything other than zero!
+             */
+            WalkState->ReturnDesc = WalkState->Operands[0];
+        }
+        else if (WalkState->ResultCount)
+        {
+            /* Since we have a real Return(), delete any implicit return */
+
+            AcpiDsClearImplicitReturn (WalkState);
+
+            /*
+             * The return value has come from a previous calculation.
+             *
+             * If value being returned is a Reference (such as
+             * an arg or local), resolve it now because it may
+             * cease to exist at the end of the method.
+             *
+             * Allow references created by the Index operator to return
+             * unchanged.
+             */
+            if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == ACPI_DESC_TYPE_OPERAND) &&
+                ((WalkState->Results->Results.ObjDesc [0])->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
+                ((WalkState->Results->Results.ObjDesc [0])->Reference.Class != ACPI_REFCLASS_INDEX))
+            {
+                Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState);
+                if (ACPI_FAILURE (Status))
+                {
+                    return (Status);
+                }
+            }
+
+            WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0];
+        }
+        else
+        {
+            /* No return operand */
+
+            if (WalkState->NumOperands)
+            {
+                AcpiUtRemoveReference (WalkState->Operands [0]);
+            }
+
+            WalkState->Operands [0]     = NULL;
+            WalkState->NumOperands      = 0;
+            WalkState->ReturnDesc       = NULL;
+        }
+
+
+        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+            "Completed RETURN_OP State=%p, RetVal=%p\n",
+            WalkState, WalkState->ReturnDesc));
+
+        /* End the control method execution right now */
+
+        Status = AE_CTRL_TERMINATE;
+        break;
+
+
+    case AML_NOOP_OP:
+
+        /* Just do nothing! */
+        break;
+
+
+    case AML_BREAK_POINT_OP:
+
+        /*
+         * Set the single-step flag. This will cause the debugger (if present)
+         * to break to the console within the AML debugger at the start of the
+         * next AML instruction.
+         */
+        ACPI_DEBUGGER_EXEC (
+            AcpiGbl_CmSingleStep = TRUE);
+        ACPI_DEBUGGER_EXEC (
+            AcpiOsPrintf ("**break** Executed AML BreakPoint opcode\n"));
+
+        /* Call to the OSL in case OS wants a piece of the action */
+
+        Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT,
+                    "Executed AML Breakpoint opcode");
+        break;
+
+
+    case AML_BREAK_OP:
+    case AML_CONTINUE_OP: /* ACPI 2.0 */
+
+
+        /* Pop and delete control states until we find a while */
+
+        while (WalkState->ControlState &&
+                (WalkState->ControlState->Control.Opcode != AML_WHILE_OP))
+        {
+            ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
+            AcpiUtDeleteGenericState (ControlState);
+        }
+
+        /* No while found? */
+
+        if (!WalkState->ControlState)
+        {
+            return (AE_AML_NO_WHILE);
+        }
+
+        /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */
+
+        WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd;
+
+        /* Return status depending on opcode */
+
+        if (Op->Common.AmlOpcode == AML_BREAK_OP)
+        {
+            Status = AE_CTRL_BREAK;
+        }
+        else
+        {
+            Status = AE_CTRL_CONTINUE;
+        }
+        break;
+
+
+    default:
+
+        ACPI_ERROR ((AE_INFO, "Unknown control opcode=0x%X Op=%p",
+            Op->Common.AmlOpcode, Op));
+
+        Status = AE_AML_BAD_OPCODE;
+        break;
+    }
+
+    return (Status);
+}
index 12d55f4..39d2e88 100644 (file)
@@ -8,7 +8,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
@@ -314,7 +314,7 @@ AcpiDsGetFieldNames (
     ACPI_PARSE_OBJECT       *Arg)
 {
     ACPI_STATUS             Status;
-    ACPI_INTEGER            Position;
+    UINT64                  Position;
 
 
     ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info);
@@ -338,8 +338,8 @@ AcpiDsGetFieldNames (
         {
         case AML_INT_RESERVEDFIELD_OP:
 
-            Position = (ACPI_INTEGER) Info->FieldBitPosition
-                        + (ACPI_INTEGER) Arg->Common.Value.Size;
+            Position = (UINT64) Info->FieldBitPosition
+                        + (UINT64) Arg->Common.Value.Size;
 
             if (Position > ACPI_UINT32_MAX)
             {
@@ -406,8 +406,8 @@ AcpiDsGetFieldNames (
 
             /* Keep track of bit position for the next field */
 
-            Position = (ACPI_INTEGER) Info->FieldBitPosition
-                        + (ACPI_INTEGER) Arg->Common.Value.Size;
+            Position = (UINT64) Info->FieldBitPosition
+                        + (UINT64) Arg->Common.Value.Size;
 
             if (Position > ACPI_UINT32_MAX)
             {
@@ -424,7 +424,7 @@ AcpiDsGetFieldNames (
         default:
 
             ACPI_ERROR ((AE_INFO,
-                "Invalid opcode in field list: %X", Arg->Common.AmlOpcode));
+                "Invalid opcode in field list: 0x%X", Arg->Common.AmlOpcode));
             return_ACPI_STATUS (AE_AML_BAD_OPCODE);
         }
 
index efea20e..f9d1e24 100644 (file)
@@ -8,7 +8,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
@@ -263,12 +263,12 @@ AcpiDsInitializeObjects (
         "**** Starting initialization of namespace objects ****\n"));
     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Parsing all Control Methods:"));
 
-    Info.MethodCount    = 0;
-    Info.OpRegionCount  = 0;
-    Info.ObjectCount    = 0;
-    Info.DeviceCount    = 0;
-    Info.TableIndex     = TableIndex;
-    Info.OwnerId        = OwnerId;
+    /* Set all init info to zero */
+
+    ACPI_MEMSET (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
+
+    Info.OwnerId = OwnerId;
+    Info.TableIndex = TableIndex;
 
     /* Walk entire namespace from the supplied root */
 
@@ -297,12 +297,12 @@ AcpiDsInitializeObjects (
     }
 
     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
-        "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
+        "\nTable [%4.4s](id %4.4X) - %u Objects with %u Devices %u Methods %u Regions\n",
         Table->Signature, OwnerId, Info.ObjectCount,
         Info.DeviceCount, Info.MethodCount, Info.OpRegionCount));
 
     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-        "%hd Methods, %hd Regions\n", Info.MethodCount, Info.OpRegionCount));
+        "%u Methods, %u Regions\n", Info.MethodCount, Info.OpRegionCount));
 
     return_ACPI_STATUS (AE_OK);
 }
index 48172e9..8f7d6bd 100644 (file)
@@ -8,7 +8,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
 
 #include "acpi.h"
 #include "accommon.h"
-#include "amlcode.h"
 #include "acdispat.h"
 #include "acinterp.h"
 #include "acnamesp.h"
@@ -291,7 +290,7 @@ AcpiDsBeginMethodExecution (
     /*
      * If this method is serialized, we need to acquire the method mutex.
      */
-    if (ObjDesc->Method.MethodFlags & AML_METHOD_SERIALIZED)
+    if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED)
     {
         /*
          * Create a mutex for the method if it is defined to be Serialized
@@ -318,7 +317,7 @@ AcpiDsBeginMethodExecution (
             (WalkState->Thread->CurrentSyncLevel > ObjDesc->Method.Mutex->Mutex.SyncLevel))
         {
             ACPI_ERROR ((AE_INFO,
-                "Cannot acquire Mutex for method [%4.4s], current SyncLevel is too large (%d)",
+                "Cannot acquire Mutex for method [%4.4s], current SyncLevel is too large (%u)",
                 AcpiUtGetNodeName (MethodNode),
                 WalkState->Thread->CurrentSyncLevel));
 
@@ -517,9 +516,9 @@ AcpiDsCallControlMethod (
 
     /* Invoke an internal method if necessary */
 
-    if (ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY)
+    if (ObjDesc->Method.InfoFlags & ACPI_METHOD_INTERNAL_ONLY)
     {
-        Status = ObjDesc->Method.Extra.Implementation (NextWalkState);
+        Status = ObjDesc->Method.Dispatch.Implementation (NextWalkState);
         if (Status == AE_OK)
         {
             Status = AE_CTRL_TERMINATE;
@@ -694,13 +693,31 @@ AcpiDsTerminateControlMethod (
 
         /*
          * Delete any namespace objects created anywhere within the
-         * namespace by the execution of this method. Unless this method
-         * is a module-level executable code method, in which case we
-         * want make the objects permanent.
+         * namespace by the execution of this method. Unless:
+         * 1) This method is a module-level executable code method, in which
+         *    case we want make the objects permanent.
+         * 2) There are other threads executing the method, in which case we
+         *    will wait until the last thread has completed.
          */
-        if (!(MethodDesc->Method.Flags & AOPOBJ_MODULE_LEVEL))
+        if (!(MethodDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL) &&
+             (MethodDesc->Method.ThreadCount == 1))
         {
-            AcpiNsDeleteNamespaceByOwner (MethodDesc->Method.OwnerId);
+            /* Delete any direct children of (created by) this method */
+
+            AcpiNsDeleteNamespaceSubtree (WalkState->MethodNode);
+
+            /*
+             * Delete any objects that were created by this method
+             * elsewhere in the namespace (if any were created).
+             * Use of the ACPI_METHOD_MODIFIED_NAMESPACE optimizes the
+             * deletion such that we don't have to perform an entire
+             * namespace walk for every control method execution.
+             */
+            if (MethodDesc->Method.InfoFlags & ACPI_METHOD_MODIFIED_NAMESPACE)
+            {
+                AcpiNsDeleteNamespaceByOwner (MethodDesc->Method.OwnerId);
+                MethodDesc->Method.InfoFlags &= ~ACPI_METHOD_MODIFIED_NAMESPACE;
+            }
         }
     }
 
@@ -725,7 +742,7 @@ AcpiDsTerminateControlMethod (
          * we immediately reuse it for the next thread executing this method
          */
         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-            "*** Completed execution of one thread, %d threads remaining\n",
+            "*** Completed execution of one thread, %u threads remaining\n",
             MethodDesc->Method.ThreadCount));
     }
     else
@@ -737,20 +754,39 @@ AcpiDsTerminateControlMethod (
          * Serialized if it appears that the method is incorrectly written and
          * does not support multiple thread execution. The best example of this
          * is if such a method creates namespace objects and blocks. A second
-         * thread will fail with an AE_ALREADY_EXISTS exception
+         * thread will fail with an AE_ALREADY_EXISTS exception.
          *
          * This code is here because we must wait until the last thread exits
-         * before creating the synchronization semaphore.
+         * before marking the method as serialized.
          */
-        if ((MethodDesc->Method.MethodFlags & AML_METHOD_SERIALIZED) &&
-            (!MethodDesc->Method.Mutex))
+        if (MethodDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED_PENDING)
         {
-            (void) AcpiDsCreateMethodMutex (MethodDesc);
+            if (WalkState)
+            {
+                ACPI_INFO ((AE_INFO,
+                    "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error",
+                    WalkState->MethodNode->Name.Ascii));
+            }
+
+            /*
+             * Method tried to create an object twice and was marked as
+             * "pending serialized". The probable cause is that the method
+             * cannot handle reentrancy.
+             *
+             * The method was created as NotSerialized, but it tried to create
+             * a named object and then blocked, causing the second thread
+             * entrance to begin and then fail. Workaround this problem by
+             * marking the method permanently as Serialized when the last
+             * thread exits here.
+             */
+            MethodDesc->Method.InfoFlags &= ~ACPI_METHOD_SERIALIZED_PENDING;
+            MethodDesc->Method.InfoFlags |= ACPI_METHOD_SERIALIZED;
+            MethodDesc->Method.SyncLevel = 0;
         }
 
         /* No more threads, we can free the OwnerId */
 
-        if (!(MethodDesc->Method.Flags & AOPOBJ_MODULE_LEVEL))
+        if (!(MethodDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL))
         {
             AcpiUtReleaseOwnerId (&MethodDesc->Method.OwnerId);
         }
index 551e848..a264b3a 100644 (file)
@@ -8,7 +8,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
@@ -188,8 +188,7 @@ AcpiDsMethodDataInit (
         WalkState->Arguments[i].Name.Integer |= (i << 24);
         WalkState->Arguments[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
         WalkState->Arguments[i].Type = ACPI_TYPE_ANY;
-        WalkState->Arguments[i].Flags =
-            ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG;
+        WalkState->Arguments[i].Flags = ANOBJ_METHOD_ARG;
     }
 
     /* Init the method locals */
@@ -201,8 +200,7 @@ AcpiDsMethodDataInit (
         WalkState->LocalVariables[i].Name.Integer |= (i << 24);
         WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
         WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY;
-        WalkState->LocalVariables[i].Flags =
-            ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL;
+        WalkState->LocalVariables[i].Flags = ANOBJ_METHOD_LOCAL;
     }
 
     return_VOID;
@@ -238,7 +236,7 @@ AcpiDsMethodDataDeleteAll (
     {
         if (WalkState->LocalVariables[Index].Object)
         {
-            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%p\n",
+            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%u=%p\n",
                     Index, WalkState->LocalVariables[Index].Object));
 
             /* Detach object (if present) and remove a reference */
@@ -253,7 +251,7 @@ AcpiDsMethodDataDeleteAll (
     {
         if (WalkState->Arguments[Index].Object)
         {
-            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%p\n",
+            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%u=%p\n",
                     Index, WalkState->Arguments[Index].Object));
 
             /* Detach object (if present) and remove a reference */
@@ -322,7 +320,7 @@ AcpiDsMethodDataInitArgs (
         Index++;
     }
 
-    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", Index));
+    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%u args passed to method\n", Index));
     return_ACPI_STATUS (AE_OK);
 }
 
@@ -363,7 +361,7 @@ AcpiDsMethodDataGetNode (
         if (Index > ACPI_METHOD_MAX_LOCAL)
         {
             ACPI_ERROR ((AE_INFO,
-                "Local index %d is invalid (max %d)",
+                "Local index %u is invalid (max %u)",
                 Index, ACPI_METHOD_MAX_LOCAL));
             return_ACPI_STATUS (AE_AML_INVALID_INDEX);
         }
@@ -378,7 +376,7 @@ AcpiDsMethodDataGetNode (
         if (Index > ACPI_METHOD_MAX_ARG)
         {
             ACPI_ERROR ((AE_INFO,
-                "Arg index %d is invalid (max %d)",
+                "Arg index %u is invalid (max %u)",
                 Index, ACPI_METHOD_MAX_ARG));
             return_ACPI_STATUS (AE_AML_INVALID_INDEX);
         }
@@ -389,7 +387,7 @@ AcpiDsMethodDataGetNode (
         break;
 
     default:
-        ACPI_ERROR ((AE_INFO, "Type %d is invalid", Type));
+        ACPI_ERROR ((AE_INFO, "Type %u is invalid", Type));
         return_ACPI_STATUS (AE_TYPE);
     }
 
@@ -429,7 +427,7 @@ AcpiDsMethodDataSetValue (
 
 
     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
-        "NewObj %p Type %2.2X, Refs=%d [%s]\n", Object,
+        "NewObj %p Type %2.2X, Refs=%u [%s]\n", Object,
         Type, Object->Common.ReferenceCount,
         AcpiUtGetTypeName (Object->Common.Type)));
 
@@ -540,7 +538,7 @@ AcpiDsMethodDataGetValue (
         case ACPI_REFCLASS_ARG:
 
             ACPI_ERROR ((AE_INFO,
-                "Uninitialized Arg[%d] at node %p",
+                "Uninitialized Arg[%u] at node %p",
                 Index, Node));
 
             return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
@@ -555,7 +553,7 @@ AcpiDsMethodDataGetValue (
 
         default:
 
-            ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: %X", Type));
+            ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: 0x%X", Type));
             return_ACPI_STATUS (AE_AML_INTERNAL);
         }
     }
@@ -667,7 +665,7 @@ AcpiDsStoreObjectToLocal (
 
 
     ACPI_FUNCTION_TRACE (DsStoreObjectToLocal);
-    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%d Obj=%p\n",
+    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n",
         Type, Index, ObjDesc));
 
     /* Parameter validation */
index cf444a1..abf8672 100644 (file)
@@ -8,7 +8,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
@@ -159,6 +159,7 @@ AcpiDsBuildInternalObject (
 {
     ACPI_OPERAND_OBJECT     *ObjDesc;
     ACPI_STATUS             Status;
+    ACPI_OBJECT_TYPE        Type;
 
 
     ACPI_FUNCTION_TRACE (DsBuildInternalObject);
@@ -241,7 +242,20 @@ AcpiDsBuildInternalObject (
                 return_ACPI_STATUS (Status);
             }
 
-            switch (Op->Common.Node->Type)
+            /*
+             * Special handling for Alias objects. We need to setup the type
+             * and the Op->Common.Node to point to the Alias target. Note,
+             * Alias has at most one level of indirection internally.
+             */
+            Type = Op->Common.Node->Type;
+            if (Type == ACPI_TYPE_LOCAL_ALIAS)
+            {
+                Type = ObjDesc->Common.Type;
+                Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
+                    Op->Common.Node->Object);
+            }
+
+            switch (Type)
             {
             /*
              * For these types, we need the actual node, not the subobject.
@@ -365,7 +379,7 @@ AcpiDsBuildInternalBufferObj (
         if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP)
         {
             ACPI_ERROR ((AE_INFO,
-                "Expecting bytelist, got AML opcode %X in op %p",
+                "Expecting bytelist, found AML opcode 0x%X in op %p",
                 ByteList->Common.AmlOpcode, ByteList));
 
             AcpiUtRemoveReference (ObjDesc);
@@ -599,7 +613,7 @@ AcpiDsBuildInternalPackageObj (
         }
 
         ACPI_INFO ((AE_INFO,
-            "Actual Package length (0x%X) is larger than NumElements field (0x%X), truncated\n",
+            "Actual Package length (%u) is larger than NumElements field (%u), truncated\n",
             i, ElementCount));
     }
     else if (i < ElementCount)
@@ -609,7 +623,7 @@ AcpiDsBuildInternalPackageObj (
          * Note: this is not an error, the package is padded out with NULLs.
          */
         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-            "Package List length (0x%X) smaller than NumElements count (0x%X), padded with null elements\n",
+            "Package List length (%u) smaller than NumElements count (%u), padded with null elements\n",
             i, ElementCount));
     }
 
@@ -787,7 +801,7 @@ AcpiDsInitObjectFromOp (
 
             case AML_ONES_OP:
 
-                ObjDesc->Integer.Value = ACPI_INTEGER_MAX;
+                ObjDesc->Integer.Value = ACPI_UINT64_MAX;
 
                 /* Truncate value if we are executing from a 32-bit ACPI table */
 
@@ -804,7 +818,7 @@ AcpiDsInitObjectFromOp (
             default:
 
                 ACPI_ERROR ((AE_INFO,
-                    "Unknown constant opcode %X", Opcode));
+                    "Unknown constant opcode 0x%X", Opcode));
                 Status = AE_AML_OPERAND_TYPE;
                 break;
             }
@@ -821,7 +835,7 @@ AcpiDsInitObjectFromOp (
 
 
         default:
-            ACPI_ERROR ((AE_INFO, "Unknown Integer type %X",
+            ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X",
                 OpInfo->Type));
             Status = AE_AML_OPERAND_TYPE;
             break;
@@ -902,7 +916,7 @@ AcpiDsInitObjectFromOp (
             default:
 
                 ACPI_ERROR ((AE_INFO,
-                    "Unimplemented reference type for AML opcode: %4.4X", Opcode));
+                    "Unimplemented reference type for AML opcode: 0x%4.4X", Opcode));
                 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
             }
             break;
@@ -912,7 +926,7 @@ AcpiDsInitObjectFromOp (
 
     default:
 
-        ACPI_ERROR ((AE_INFO, "Unimplemented data type: %X",
+        ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X",
             ObjDesc->Common.Type));
 
         Status = AE_AML_OPERAND_TYPE;
index 3edbacc..0f5164e 100644 (file)
@@ -1,7 +1,6 @@
 /******************************************************************************
  *
- * Module Name: dsopcode - Dispatcher Op Region support and handling of
- *                         "control" opcodes
+ * Module Name: dsopcode - Dispatcher suport for regions and fields
  *
  *****************************************************************************/
 
@@ -9,7 +8,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
 
 /* Local prototypes */
 
-static ACPI_STATUS
-AcpiDsExecuteArguments (
-    ACPI_NAMESPACE_NODE     *Node,
-    ACPI_NAMESPACE_NODE     *ScopeNode,
-    UINT32                  AmlLength,
-    UINT8                   *AmlStart);
-
 static ACPI_STATUS
 AcpiDsInitBufferField (
     UINT16                  AmlOpcode,
@@ -148,369 +140,6 @@ AcpiDsInitBufferField (
     ACPI_OPERAND_OBJECT     *ResultDesc);
 
 
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsExecuteArguments
- *
- * PARAMETERS:  Node                - Object NS node
- *              ScopeNode           - Parent NS node
- *              AmlLength           - Length of executable AML
- *              AmlStart            - Pointer to the AML
- *
- * RETURN:      Status.
- *
- * DESCRIPTION: Late (deferred) execution of region or field arguments
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-AcpiDsExecuteArguments (
-    ACPI_NAMESPACE_NODE     *Node,
-    ACPI_NAMESPACE_NODE     *ScopeNode,
-    UINT32                  AmlLength,
-    UINT8                   *AmlStart)
-{
-    ACPI_STATUS             Status;
-    ACPI_PARSE_OBJECT       *Op;
-    ACPI_WALK_STATE         *WalkState;
-
-
-    ACPI_FUNCTION_TRACE (DsExecuteArguments);
-
-
-    /*
-     * Allocate a new parser op to be the root of the parsed tree
-     */
-    Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
-    if (!Op)
-    {
-        return_ACPI_STATUS (AE_NO_MEMORY);
-    }
-
-    /* Save the Node for use in AcpiPsParseAml */
-
-    Op->Common.Node = ScopeNode;
-
-    /* Create and initialize a new parser state */
-
-    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
-    if (!WalkState)
-    {
-        Status = AE_NO_MEMORY;
-        goto Cleanup;
-    }
-
-    Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
-                    AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
-    if (ACPI_FAILURE (Status))
-    {
-        AcpiDsDeleteWalkState (WalkState);
-        goto Cleanup;
-    }
-
-    /* Mark this parse as a deferred opcode */
-
-    WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP;
-    WalkState->DeferredNode = Node;
-
-    /* Pass1: Parse the entire declaration */
-
-    Status = AcpiPsParseAml (WalkState);
-    if (ACPI_FAILURE (Status))
-    {
-        goto Cleanup;
-    }
-
-    /* Get and init the Op created above */
-
-    Op->Common.Node = Node;
-    AcpiPsDeleteParseTree (Op);
-
-    /* Evaluate the deferred arguments */
-
-    Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
-    if (!Op)
-    {
-        return_ACPI_STATUS (AE_NO_MEMORY);
-    }
-
-    Op->Common.Node = ScopeNode;
-
-    /* Create and initialize a new parser state */
-
-    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
-    if (!WalkState)
-    {
-        Status = AE_NO_MEMORY;
-        goto Cleanup;
-    }
-
-    /* Execute the opcode and arguments */
-
-    Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
-                    AmlLength, NULL, ACPI_IMODE_EXECUTE);
-    if (ACPI_FAILURE (Status))
-    {
-        AcpiDsDeleteWalkState (WalkState);
-        goto Cleanup;
-    }
-
-    /* Mark this execution as a deferred opcode */
-
-    WalkState->DeferredNode = Node;
-    Status = AcpiPsParseAml (WalkState);
-
-Cleanup:
-    AcpiPsDeleteParseTree (Op);
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsGetBufferFieldArguments
- *
- * PARAMETERS:  ObjDesc         - A valid BufferField object
- *
- * RETURN:      Status.
- *
- * DESCRIPTION: Get BufferField Buffer and Index.  This implements the late
- *              evaluation of these field attributes.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDsGetBufferFieldArguments (
-    ACPI_OPERAND_OBJECT     *ObjDesc)
-{
-    ACPI_OPERAND_OBJECT     *ExtraDesc;
-    ACPI_NAMESPACE_NODE     *Node;
-    ACPI_STATUS             Status;
-
-
-    ACPI_FUNCTION_TRACE_PTR (DsGetBufferFieldArguments, ObjDesc);
-
-
-    if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
-    {
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    /* Get the AML pointer (method object) and BufferField node */
-
-    ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
-    Node = ObjDesc->BufferField.Node;
-
-    ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_BUFFER_FIELD, Node, NULL));
-    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
-        AcpiUtGetNodeName (Node)));
-
-    /* Execute the AML code for the TermArg arguments */
-
-    Status = AcpiDsExecuteArguments (Node, AcpiNsGetParentNode (Node),
-                ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsGetBankFieldArguments
- *
- * PARAMETERS:  ObjDesc         - A valid BankField object
- *
- * RETURN:      Status.
- *
- * DESCRIPTION: Get BankField BankValue.  This implements the late
- *              evaluation of these field attributes.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDsGetBankFieldArguments (
-    ACPI_OPERAND_OBJECT     *ObjDesc)
-{
-    ACPI_OPERAND_OBJECT     *ExtraDesc;
-    ACPI_NAMESPACE_NODE     *Node;
-    ACPI_STATUS             Status;
-
-
-    ACPI_FUNCTION_TRACE_PTR (DsGetBankFieldArguments, ObjDesc);
-
-
-    if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
-    {
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    /* Get the AML pointer (method object) and BankField node */
-
-    ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
-    Node = ObjDesc->BankField.Node;
-
-    ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_LOCAL_BANK_FIELD, Node, NULL));
-    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
-        AcpiUtGetNodeName (Node)));
-
-    /* Execute the AML code for the TermArg arguments */
-
-    Status = AcpiDsExecuteArguments (Node, AcpiNsGetParentNode (Node),
-                ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsGetBufferArguments
- *
- * PARAMETERS:  ObjDesc         - A valid Buffer object
- *
- * RETURN:      Status.
- *
- * DESCRIPTION: Get Buffer length and initializer byte list.  This implements
- *              the late evaluation of these attributes.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDsGetBufferArguments (
-    ACPI_OPERAND_OBJECT     *ObjDesc)
-{
-    ACPI_NAMESPACE_NODE     *Node;
-    ACPI_STATUS             Status;
-
-
-    ACPI_FUNCTION_TRACE_PTR (DsGetBufferArguments, ObjDesc);
-
-
-    if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
-    {
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    /* Get the Buffer node */
-
-    Node = ObjDesc->Buffer.Node;
-    if (!Node)
-    {
-        ACPI_ERROR ((AE_INFO,
-            "No pointer back to NS node in buffer obj %p", ObjDesc));
-        return_ACPI_STATUS (AE_AML_INTERNAL);
-    }
-
-    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
-
-    /* Execute the AML code for the TermArg arguments */
-
-    Status = AcpiDsExecuteArguments (Node, Node,
-                ObjDesc->Buffer.AmlLength, ObjDesc->Buffer.AmlStart);
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsGetPackageArguments
- *
- * PARAMETERS:  ObjDesc         - A valid Package object
- *
- * RETURN:      Status.
- *
- * DESCRIPTION: Get Package length and initializer byte list.  This implements
- *              the late evaluation of these attributes.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDsGetPackageArguments (
-    ACPI_OPERAND_OBJECT     *ObjDesc)
-{
-    ACPI_NAMESPACE_NODE     *Node;
-    ACPI_STATUS             Status;
-
-
-    ACPI_FUNCTION_TRACE_PTR (DsGetPackageArguments, ObjDesc);
-
-
-    if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
-    {
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    /* Get the Package node */
-
-    Node = ObjDesc->Package.Node;
-    if (!Node)
-    {
-        ACPI_ERROR ((AE_INFO,
-            "No pointer back to NS node in package %p", ObjDesc));
-        return_ACPI_STATUS (AE_AML_INTERNAL);
-    }
-
-    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n"));
-
-    /* Execute the AML code for the TermArg arguments */
-
-    Status = AcpiDsExecuteArguments (Node, Node,
-                ObjDesc->Package.AmlLength, ObjDesc->Package.AmlStart);
-    return_ACPI_STATUS (Status);
-}
-
-
-/*****************************************************************************
- *
- * FUNCTION:    AcpiDsGetRegionArguments
- *
- * PARAMETERS:  ObjDesc         - A valid region object
- *
- * RETURN:      Status.
- *
- * DESCRIPTION: Get region address and length.  This implements the late
- *              evaluation of these region attributes.
- *
- ****************************************************************************/
-
-ACPI_STATUS
-AcpiDsGetRegionArguments (
-    ACPI_OPERAND_OBJECT     *ObjDesc)
-{
-    ACPI_NAMESPACE_NODE     *Node;
-    ACPI_STATUS             Status;
-    ACPI_OPERAND_OBJECT     *ExtraDesc;
-
-
-    ACPI_FUNCTION_TRACE_PTR (DsGetRegionArguments, ObjDesc);
-
-
-    if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
-    {
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
-    if (!ExtraDesc)
-    {
-        return_ACPI_STATUS (AE_NOT_EXIST);
-    }
-
-    /* Get the Region node */
-
-    Node = ObjDesc->Region.Node;
-
-    ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_REGION, Node, NULL));
-
-    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
-        AcpiUtGetNodeName (Node), ExtraDesc->Extra.AmlStart));
-
-    /* Execute the argument AML */
-
-    Status = AcpiDsExecuteArguments (Node, AcpiNsGetParentNode (Node),
-                ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
-    return_ACPI_STATUS (Status);
-}
-
-
 /*******************************************************************************
  *
  * FUNCTION:    AcpiDsInitializeRegion
@@ -678,7 +307,7 @@ AcpiDsInitBufferField (
     default:
 
         ACPI_ERROR ((AE_INFO,
-            "Unknown field creation opcode %02x",
+            "Unknown field creation opcode 0x%02X",
             AmlOpcode));
         Status = AE_AML_BAD_OPCODE;
         goto Cleanup;
@@ -690,7 +319,7 @@ AcpiDsInitBufferField (
         (8 * (UINT32) BufferDesc->Buffer.Length))
     {
         ACPI_ERROR ((AE_INFO,
-            "Field [%4.4s] at %d exceeds Buffer [%4.4s] size %d (bits)",
+            "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
             AcpiUtGetNodeName (ResultDesc),
             BitOffset + BitCount,
             AcpiUtGetNodeName (BufferDesc->Buffer.Node),
@@ -806,7 +435,7 @@ AcpiDsEvalBufferFieldOperands (
                     ACPI_WALK_OPERANDS, WalkState);
     if (ACPI_FAILURE (Status))
     {
-        ACPI_ERROR ((AE_INFO, "(%s) bad operand(s) (%X)",
+        ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
             AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
 
         return_ACPI_STATUS (Status);
@@ -942,8 +571,9 @@ AcpiDsEvalRegionOperands (
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Get region address and length
- *              Called from AcpiDsExecEndOp during DataTableRegion parse tree walk
+ * DESCRIPTION: Get region address and length.
+ *              Called from AcpiDsExecEndOp during DataTableRegion parse
+ *              tree walk.
  *
  ******************************************************************************/
 
@@ -1249,371 +879,3 @@ AcpiDsEvalBankFieldOperands (
     return_ACPI_STATUS (Status);
 }
 
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsExecBeginControlOp
- *
- * PARAMETERS:  WalkList        - The list that owns the walk stack
- *              Op              - The control Op
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Handles all control ops encountered during control method
- *              execution.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDsExecBeginControlOp (
-    ACPI_WALK_STATE         *WalkState,
-    ACPI_PARSE_OBJECT       *Op)
-{
-    ACPI_STATUS             Status = AE_OK;
-    ACPI_GENERIC_STATE      *ControlState;
-
-
-    ACPI_FUNCTION_NAME (DsExecBeginControlOp);
-
-
-    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", Op,
-        Op->Common.AmlOpcode, WalkState));
-
-    switch (Op->Common.AmlOpcode)
-    {
-    case AML_WHILE_OP:
-
-        /*
-         * If this is an additional iteration of a while loop, continue.
-         * There is no need to allocate a new control state.
-         */
-        if (WalkState->ControlState)
-        {
-            if (WalkState->ControlState->Control.AmlPredicateStart ==
-                (WalkState->ParserState.Aml - 1))
-            {
-                /* Reset the state to start-of-loop */
-
-                WalkState->ControlState->Common.State = ACPI_CONTROL_CONDITIONAL_EXECUTING;
-                break;
-            }
-        }
-
-        /*lint -fallthrough */
-
-    case AML_IF_OP:
-
-        /*
-         * IF/WHILE: Create a new control state to manage these
-         * constructs. We need to manage these as a stack, in order
-         * to handle nesting.
-         */
-        ControlState = AcpiUtCreateControlState ();
-        if (!ControlState)
-        {
-            Status = AE_NO_MEMORY;
-            break;
-        }
-        /*
-         * Save a pointer to the predicate for multiple executions
-         * of a loop
-         */
-        ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1;
-        ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd;
-        ControlState->Control.Opcode = Op->Common.AmlOpcode;
-
-
-        /* Push the control state on this walk's control stack */
-
-        AcpiUtPushGenericState (&WalkState->ControlState, ControlState);
-        break;
-
-    case AML_ELSE_OP:
-
-        /* Predicate is in the state object */
-        /* If predicate is true, the IF was executed, ignore ELSE part */
-
-        if (WalkState->LastPredicate)
-        {
-            Status = AE_CTRL_TRUE;
-        }
-
-        break;
-
-    case AML_RETURN_OP:
-
-        break;
-
-    default:
-        break;
-    }
-
-    return (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsExecEndControlOp
- *
- * PARAMETERS:  WalkList        - The list that owns the walk stack
- *              Op              - The control Op
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Handles all control ops encountered during control method
- *              execution.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDsExecEndControlOp (
-    ACPI_WALK_STATE         *WalkState,
-    ACPI_PARSE_OBJECT       *Op)
-{
-    ACPI_STATUS             Status = AE_OK;
-    ACPI_GENERIC_STATE      *ControlState;
-
-
-    ACPI_FUNCTION_NAME (DsExecEndControlOp);
-
-
-    switch (Op->Common.AmlOpcode)
-    {
-    case AML_IF_OP:
-
-        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op));
-
-        /*
-         * Save the result of the predicate in case there is an
-         * ELSE to come
-         */
-        WalkState->LastPredicate =
-            (BOOLEAN) WalkState->ControlState->Common.Value;
-
-        /*
-         * Pop the control state that was created at the start
-         * of the IF and free it
-         */
-        ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
-        AcpiUtDeleteGenericState (ControlState);
-        break;
-
-
-    case AML_ELSE_OP:
-
-        break;
-
-
-    case AML_WHILE_OP:
-
-        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op));
-
-        ControlState = WalkState->ControlState;
-        if (ControlState->Common.Value)
-        {
-            /* Predicate was true, the body of the loop was just executed */
-
-            /*
-             * This loop counter mechanism allows the interpreter to escape
-             * possibly infinite loops. This can occur in poorly written AML
-             * when the hardware does not respond within a while loop and the
-             * loop does not implement a timeout.
-             */
-            ControlState->Control.LoopCount++;
-            if (ControlState->Control.LoopCount > ACPI_MAX_LOOP_ITERATIONS)
-            {
-                Status = AE_AML_INFINITE_LOOP;
-                break;
-            }
-
-            /*
-             * Go back and evaluate the predicate and maybe execute the loop
-             * another time
-             */
-            Status = AE_CTRL_PENDING;
-            WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart;
-            break;
-        }
-
-        /* Predicate was false, terminate this while loop */
-
-        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-            "[WHILE_OP] termination! Op=%p\n",Op));
-
-        /* Pop this control state and free it */
-
-        ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
-        AcpiUtDeleteGenericState (ControlState);
-        break;
-
-
-    case AML_RETURN_OP:
-
-        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-            "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg));
-
-        /*
-         * One optional operand -- the return value
-         * It can be either an immediate operand or a result that
-         * has been bubbled up the tree
-         */
-        if (Op->Common.Value.Arg)
-        {
-            /* Since we have a real Return(), delete any implicit return */
-
-            AcpiDsClearImplicitReturn (WalkState);
-
-            /* Return statement has an immediate operand */
-
-            Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
-            if (ACPI_FAILURE (Status))
-            {
-                return (Status);
-            }
-
-            /*
-             * If value being returned is a Reference (such as
-             * an arg or local), resolve it now because it may
-             * cease to exist at the end of the method.
-             */
-            Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
-            if (ACPI_FAILURE (Status))
-            {
-                return (Status);
-            }
-
-            /*
-             * Get the return value and save as the last result
-             * value.  This is the only place where WalkState->ReturnDesc
-             * is set to anything other than zero!
-             */
-            WalkState->ReturnDesc = WalkState->Operands[0];
-        }
-        else if (WalkState->ResultCount)
-        {
-            /* Since we have a real Return(), delete any implicit return */
-
-            AcpiDsClearImplicitReturn (WalkState);
-
-            /*
-             * The return value has come from a previous calculation.
-             *
-             * If value being returned is a Reference (such as
-             * an arg or local), resolve it now because it may
-             * cease to exist at the end of the method.
-             *
-             * Allow references created by the Index operator to return unchanged.
-             */
-            if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == ACPI_DESC_TYPE_OPERAND) &&
-                ((WalkState->Results->Results.ObjDesc [0])->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
-                ((WalkState->Results->Results.ObjDesc [0])->Reference.Class != ACPI_REFCLASS_INDEX))
-            {
-                Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState);
-                if (ACPI_FAILURE (Status))
-                {
-                    return (Status);
-                }
-            }
-
-            WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0];
-        }
-        else
-        {
-            /* No return operand */
-
-            if (WalkState->NumOperands)
-            {
-                AcpiUtRemoveReference (WalkState->Operands [0]);
-            }
-
-            WalkState->Operands [0]     = NULL;
-            WalkState->NumOperands      = 0;
-            WalkState->ReturnDesc       = NULL;
-        }
-
-
-        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-            "Completed RETURN_OP State=%p, RetVal=%p\n",
-            WalkState, WalkState->ReturnDesc));
-
-        /* End the control method execution right now */
-
-        Status = AE_CTRL_TERMINATE;
-        break;
-
-
-    case AML_NOOP_OP:
-
-        /* Just do nothing! */
-        break;
-
-
-    case AML_BREAK_POINT_OP:
-
-        /*
-         * Set the single-step flag. This will cause the debugger (if present)
-         * to break to the console within the AML debugger at the start of the
-         * next AML instruction.
-         */
-        ACPI_DEBUGGER_EXEC (
-            AcpiGbl_CmSingleStep = TRUE);
-        ACPI_DEBUGGER_EXEC (
-            AcpiOsPrintf ("**break** Executed AML BreakPoint opcode\n"));
-
-        /* Call to the OSL in case OS wants a piece of the action */
-
-        Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT,
-                    "Executed AML Breakpoint opcode");
-        break;
-
-
-    case AML_BREAK_OP:
-    case AML_CONTINUE_OP: /* ACPI 2.0 */
-
-
-        /* Pop and delete control states until we find a while */
-
-        while (WalkState->ControlState &&
-                (WalkState->ControlState->Control.Opcode != AML_WHILE_OP))
-        {
-            ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
-            AcpiUtDeleteGenericState (ControlState);
-        }
-
-        /* No while found? */
-
-        if (!WalkState->ControlState)
-        {
-            return (AE_AML_NO_WHILE);
-        }
-
-        /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */
-
-        WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd;
-
-        /* Return status depending on opcode */
-
-        if (Op->Common.AmlOpcode == AML_BREAK_OP)
-        {
-            Status = AE_CTRL_BREAK;
-        }
-        else
-        {
-            Status = AE_CTRL_CONTINUE;
-        }
-        break;
-
-
-    default:
-
-        ACPI_ERROR ((AE_INFO, "Unknown control opcode=%X Op=%p",
-            Op->Common.AmlOpcode, Op));
-
-        Status = AE_AML_BAD_OPCODE;
-        break;
-    }
-
-    return (Status);
-}
-
index 6c211ac..22bd0bf 100644 (file)
@@ -8,7 +8,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
@@ -875,7 +875,7 @@ AcpiDsCreateOperands (
 
         Index--;
 
-        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Arg #%d (%p) done, Arg1=%p\n",
+        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Arg #%u (%p) done, Arg1=%p\n",
             Index, Arg, FirstArg));
     }
 
@@ -890,7 +890,7 @@ Cleanup:
      */
     AcpiDsObjStackPopAndDelete (ArgCount, WalkState);
 
-    ACPI_EXCEPTION ((AE_INFO, Status, "While creating Arg %d", Index));
+    ACPI_EXCEPTION ((AE_INFO, Status, "While creating Arg %u", Index));
     return_ACPI_STATUS (Status);
 }
 
index 9485c62..e243c7f 100644 (file)
@@ -9,7 +9,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
@@ -227,7 +227,7 @@ AcpiDsGetPredicateValue (
     if (LocalObjDesc->Common.Type != ACPI_TYPE_INTEGER)
     {
         ACPI_ERROR ((AE_INFO,
-            "Bad predicate (not an integer) ObjDesc=%p State=%p Type=%X",
+            "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X",
             ObjDesc, WalkState, ObjDesc->Common.Type));
 
         Status = AE_AML_OPERAND_TYPE;
@@ -400,10 +400,26 @@ AcpiDsExecBeginOp (
              * we must enter this object into the namespace.  The created
              * object is temporary and will be deleted upon completion of
              * the execution of this method.
+             *
+             * Note 10/2010: Except for the Scope() op. This opcode does
+             * not actually create a new object, it refers to an existing
+             * object. However, for Scope(), we want to indeed open a
+             * new scope.
              */
-            Status = AcpiDsLoad2BeginOp (WalkState, NULL);
+            if (Op->Common.AmlOpcode != AML_SCOPE_OP)
+            {
+                Status = AcpiDsLoad2BeginOp (WalkState, NULL);
+            }
+            else
+            {
+                Status = AcpiDsScopeStackPush (Op->Named.Node,
+                            Op->Named.Node->Type, WalkState);
+                if (ACPI_FAILURE (Status))
+                {
+                    return_ACPI_STATUS (Status);
+                }
+            }
         }
-
         break;
 
 
@@ -463,7 +479,7 @@ AcpiDsExecEndOp (
 
     if (OpClass == AML_CLASS_UNKNOWN)
     {
-        ACPI_ERROR ((AE_INFO, "Unknown opcode %X", Op->Common.AmlOpcode));
+        ACPI_ERROR ((AE_INFO, "Unknown opcode 0x%X", Op->Common.AmlOpcode));
         return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
     }
 
@@ -783,7 +799,7 @@ AcpiDsExecEndOp (
         default:
 
             ACPI_ERROR ((AE_INFO,
-                "Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p",
+                "Unimplemented opcode, class=0x%X type=0x%X Opcode=-0x%X Op=%p",
                 OpClass, OpType, Op->Common.AmlOpcode, Op));
 
             Status = AE_NOT_IMPLEMENTED;
index 48c4ae6..f30bbfc 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Module Name: dswload - Dispatcher namespace load callbacks
+ * Module Name: dswload - Dispatcher first pass namespace load callbacks
  *
  *****************************************************************************/
 
@@ -8,7 +8,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
 #include "acdispat.h"
 #include "acinterp.h"
 #include "acnamesp.h"
-#include "acevents.h"
 
 #ifdef ACPI_ASL_COMPILER
 #include "acdisasm.h"
@@ -539,7 +538,7 @@ AcpiDsLoad1EndOp (
         else if (Op->Common.AmlOpcode == AML_DATA_REGION_OP)
         {
             Status = AcpiExCreateRegion (Op->Named.Data, Op->Named.Length,
-                        REGION_DATA_TABLE, WalkState);
+                        ACPI_ADR_SPACE_DATA_TABLE, WalkState);
             if (ACPI_FAILURE (Status))
             {
                 return_ACPI_STATUS (Status);
@@ -622,695 +621,3 @@ AcpiDsLoad1EndOp (
 
     return_ACPI_STATUS (Status);
 }
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsLoad2BeginOp
- *
- * PARAMETERS:  WalkState       - Current state of the parse tree walk
- *              OutOp           - Wher to return op if a new one is created
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Descending callback used during the loading of ACPI tables.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDsLoad2BeginOp (
-    ACPI_WALK_STATE         *WalkState,
-    ACPI_PARSE_OBJECT       **OutOp)
-{
-    ACPI_PARSE_OBJECT       *Op;
-    ACPI_NAMESPACE_NODE     *Node;
-    ACPI_STATUS             Status;
-    ACPI_OBJECT_TYPE        ObjectType;
-    char                    *BufferPtr;
-    UINT32                  Flags;
-
-
-    ACPI_FUNCTION_TRACE (DsLoad2BeginOp);
-
-
-    Op = WalkState->Op;
-    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", Op, WalkState));
-
-    if (Op)
-    {
-        if ((WalkState->ControlState) &&
-            (WalkState->ControlState->Common.State ==
-                ACPI_CONTROL_CONDITIONAL_EXECUTING))
-        {
-            /* We are executing a while loop outside of a method */
-
-            Status = AcpiDsExecBeginOp (WalkState, OutOp);
-            return_ACPI_STATUS (Status);
-        }
-
-        /* We only care about Namespace opcodes here */
-
-        if ((!(WalkState->OpInfo->Flags & AML_NSOPCODE)   &&
-              (WalkState->Opcode != AML_INT_NAMEPATH_OP)) ||
-            (!(WalkState->OpInfo->Flags & AML_NAMED)))
-        {
-            return_ACPI_STATUS (AE_OK);
-        }
-
-        /* Get the name we are going to enter or lookup in the namespace */
-
-        if (WalkState->Opcode == AML_INT_NAMEPATH_OP)
-        {
-            /* For Namepath op, get the path string */
-
-            BufferPtr = Op->Common.Value.String;
-            if (!BufferPtr)
-            {
-                /* No name, just exit */
-
-                return_ACPI_STATUS (AE_OK);
-            }
-        }
-        else
-        {
-            /* Get name from the op */
-
-            BufferPtr = ACPI_CAST_PTR (char, &Op->Named.Name);
-        }
-    }
-    else
-    {
-        /* Get the namestring from the raw AML */
-
-        BufferPtr = AcpiPsGetNextNamestring (&WalkState->ParserState);
-    }
-
-    /* Map the opcode into an internal object type */
-
-    ObjectType = WalkState->OpInfo->ObjectType;
-
-    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-        "State=%p Op=%p Type=%X\n", WalkState, Op, ObjectType));
-
-    switch (WalkState->Opcode)
-    {
-    case AML_FIELD_OP:
-    case AML_BANK_FIELD_OP:
-    case AML_INDEX_FIELD_OP:
-
-        Node = NULL;
-        Status = AE_OK;
-        break;
-
-    case AML_INT_NAMEPATH_OP:
-        /*
-         * The NamePath is an object reference to an existing object.
-         * Don't enter the name into the namespace, but look it up
-         * for use later.
-         */
-        Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType,
-                        ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
-                        WalkState, &(Node));
-        break;
-
-    case AML_SCOPE_OP:
-
-        /* Special case for Scope(\) -> refers to the Root node */
-
-        if (Op && (Op->Named.Node == AcpiGbl_RootNode))
-        {
-            Node = Op->Named.Node;
-
-            Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
-            if (ACPI_FAILURE (Status))
-            {
-                return_ACPI_STATUS (Status);
-            }
-        }
-        else
-        {
-            /*
-             * The Path is an object reference to an existing object.
-             * Don't enter the name into the namespace, but look it up
-             * for use later.
-             */
-            Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType,
-                        ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
-                        WalkState, &(Node));
-            if (ACPI_FAILURE (Status))
-            {
-#ifdef ACPI_ASL_COMPILER
-                if (Status == AE_NOT_FOUND)
-                {
-                    Status = AE_OK;
-                }
-                else
-                {
-                    ACPI_ERROR_NAMESPACE (BufferPtr, Status);
-                }
-#else
-                ACPI_ERROR_NAMESPACE (BufferPtr, Status);
-#endif
-                return_ACPI_STATUS (Status);
-            }
-        }
-
-        /*
-         * We must check to make sure that the target is
-         * one of the opcodes that actually opens a scope
-         */
-        switch (Node->Type)
-        {
-        case ACPI_TYPE_ANY:
-        case ACPI_TYPE_LOCAL_SCOPE:         /* Scope */
-        case ACPI_TYPE_DEVICE:
-        case ACPI_TYPE_POWER:
-        case ACPI_TYPE_PROCESSOR:
-        case ACPI_TYPE_THERMAL:
-
-            /* These are acceptable types */
-            break;
-
-        case ACPI_TYPE_INTEGER:
-        case ACPI_TYPE_STRING:
-        case ACPI_TYPE_BUFFER:
-
-            /*
-             * These types we will allow, but we will change the type.
-             * This enables some existing code of the form:
-             *
-             *  Name (DEB, 0)
-             *  Scope (DEB) { ... }
-             */
-            ACPI_WARNING ((AE_INFO,
-                "Type override - [%4.4s] had invalid type (%s) "
-                "for Scope operator, changed to type ANY\n",
-                AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type)));
-
-            Node->Type = ACPI_TYPE_ANY;
-            WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY;
-            break;
-
-        default:
-
-            /* All other types are an error */
-
-            ACPI_ERROR ((AE_INFO,
-                "Invalid type (%s) for target of "
-                "Scope operator [%4.4s] (Cannot override)",
-                AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node)));
-
-            return (AE_AML_OPERAND_TYPE);
-        }
-        break;
-
-    default:
-
-        /* All other opcodes */
-
-        if (Op && Op->Common.Node)
-        {
-            /* This op/node was previously entered into the namespace */
-
-            Node = Op->Common.Node;
-
-            if (AcpiNsOpensScope (ObjectType))
-            {
-                Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
-                if (ACPI_FAILURE (Status))
-                {
-                    return_ACPI_STATUS (Status);
-                }
-            }
-
-            return_ACPI_STATUS (AE_OK);
-        }
-
-        /*
-         * Enter the named type into the internal namespace. We enter the name
-         * as we go downward in the parse tree. Any necessary subobjects that
-         * involve arguments to the opcode must be created as we go back up the
-         * parse tree later.
-         *
-         * Note: Name may already exist if we are executing a deferred opcode.
-         */
-        if (WalkState->DeferredNode)
-        {
-            /* This name is already in the namespace, get the node */
-
-            Node = WalkState->DeferredNode;
-            Status = AE_OK;
-            break;
-        }
-
-        Flags = ACPI_NS_NO_UPSEARCH;
-        if (WalkState->PassNumber == ACPI_IMODE_EXECUTE)
-        {
-            /* Execution mode, node cannot already exist, node is temporary */
-
-            Flags |= ACPI_NS_ERROR_IF_FOUND;
-
-            if (!(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
-            {
-                Flags |= ACPI_NS_TEMPORARY;
-            }
-        }
-
-        /* Add new entry or lookup existing entry */
-
-        Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType,
-                    ACPI_IMODE_LOAD_PASS2, Flags, WalkState, &Node);
-
-        if (ACPI_SUCCESS (Status) && (Flags & ACPI_NS_TEMPORARY))
-        {
-            ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-                "***New Node [%4.4s] %p is temporary\n",
-                AcpiUtGetNodeName (Node), Node));
-        }
-        break;
-    }
-
-    if (ACPI_FAILURE (Status))
-    {
-        ACPI_ERROR_NAMESPACE (BufferPtr, Status);
-        return_ACPI_STATUS (Status);
-    }
-
-    if (!Op)
-    {
-        /* Create a new op */
-
-        Op = AcpiPsAllocOp (WalkState->Opcode);
-        if (!Op)
-        {
-            return_ACPI_STATUS (AE_NO_MEMORY);
-        }
-
-        /* Initialize the new op */
-
-        if (Node)
-        {
-            Op->Named.Name = Node->Name.Integer;
-        }
-        *OutOp = Op;
-    }
-
-    /*
-     * Put the Node in the "op" object that the parser uses, so we
-     * can get it again quickly when this scope is closed
-     */
-    Op->Common.Node = Node;
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsLoad2EndOp
- *
- * PARAMETERS:  WalkState       - Current state of the parse tree walk
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Ascending callback used during the loading of the namespace,
- *              both control methods and everything else.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDsLoad2EndOp (
-    ACPI_WALK_STATE         *WalkState)
-{
-    ACPI_PARSE_OBJECT       *Op;
-    ACPI_STATUS             Status = AE_OK;
-    ACPI_OBJECT_TYPE        ObjectType;
-    ACPI_NAMESPACE_NODE     *Node;
-    ACPI_PARSE_OBJECT       *Arg;
-    ACPI_NAMESPACE_NODE     *NewNode;
-#ifndef ACPI_NO_METHOD_EXECUTION
-    UINT32                  i;
-    UINT8                   RegionSpace;
-#endif
-
-
-    ACPI_FUNCTION_TRACE (DsLoad2EndOp);
-
-    Op = WalkState->Op;
-    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
-            WalkState->OpInfo->Name, Op, WalkState));
-
-    /* Check if opcode had an associated namespace object */
-
-    if (!(WalkState->OpInfo->Flags & AML_NSOBJECT))
-    {
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    if (Op->Common.AmlOpcode == AML_SCOPE_OP)
-    {
-        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-            "Ending scope Op=%p State=%p\n", Op, WalkState));
-    }
-
-    ObjectType = WalkState->OpInfo->ObjectType;
-
-    /*
-     * Get the Node/name from the earlier lookup
-     * (It was saved in the *op structure)
-     */
-    Node = Op->Common.Node;
-
-    /*
-     * Put the Node on the object stack (Contains the ACPI Name of
-     * this object)
-     */
-    WalkState->Operands[0] = (void *) Node;
-    WalkState->NumOperands = 1;
-
-    /* Pop the scope stack */
-
-    if (AcpiNsOpensScope (ObjectType) &&
-       (Op->Common.AmlOpcode != AML_INT_METHODCALL_OP))
-    {
-        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
-            AcpiUtGetTypeName (ObjectType), Op));
-
-        Status = AcpiDsScopeStackPop (WalkState);
-        if (ACPI_FAILURE (Status))
-        {
-            goto Cleanup;
-        }
-    }
-
-    /*
-     * Named operations are as follows:
-     *
-     * AML_ALIAS
-     * AML_BANKFIELD
-     * AML_CREATEBITFIELD
-     * AML_CREATEBYTEFIELD
-     * AML_CREATEDWORDFIELD
-     * AML_CREATEFIELD
-     * AML_CREATEQWORDFIELD
-     * AML_CREATEWORDFIELD
-     * AML_DATA_REGION
-     * AML_DEVICE
-     * AML_EVENT
-     * AML_FIELD
-     * AML_INDEXFIELD
-     * AML_METHOD
-     * AML_METHODCALL
-     * AML_MUTEX
-     * AML_NAME
-     * AML_NAMEDFIELD
-     * AML_OPREGION
-     * AML_POWERRES
-     * AML_PROCESSOR
-     * AML_SCOPE
-     * AML_THERMALZONE
-     */
-
-    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-        "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
-        AcpiPsGetOpcodeName (Op->Common.AmlOpcode), WalkState, Op, Node));
-
-    /* Decode the opcode */
-
-    Arg = Op->Common.Value.Arg;
-
-    switch (WalkState->OpInfo->Type)
-    {
-#ifndef ACPI_NO_METHOD_EXECUTION
-
-    case AML_TYPE_CREATE_FIELD:
-        /*
-         * Create the field object, but the field buffer and index must
-         * be evaluated later during the execution phase
-         */
-        Status = AcpiDsCreateBufferField (Op, WalkState);
-        break;
-
-
-     case AML_TYPE_NAMED_FIELD:
-        /*
-         * If we are executing a method, initialize the field
-         */
-        if (WalkState->MethodNode)
-        {
-            Status = AcpiDsInitFieldObjects (Op, WalkState);
-        }
-
-        switch (Op->Common.AmlOpcode)
-        {
-        case AML_INDEX_FIELD_OP:
-
-            Status = AcpiDsCreateIndexField (Op, (ACPI_HANDLE) Arg->Common.Node,
-                        WalkState);
-            break;
-
-        case AML_BANK_FIELD_OP:
-
-            Status = AcpiDsCreateBankField (Op, Arg->Common.Node, WalkState);
-            break;
-
-        case AML_FIELD_OP:
-
-            Status = AcpiDsCreateField (Op, Arg->Common.Node, WalkState);
-            break;
-
-        default:
-            /* All NAMED_FIELD opcodes must be handled above */
-            break;
-        }
-        break;
-
-
-     case AML_TYPE_NAMED_SIMPLE:
-
-        Status = AcpiDsCreateOperands (WalkState, Arg);
-        if (ACPI_FAILURE (Status))
-        {
-            goto Cleanup;
-        }
-
-        switch (Op->Common.AmlOpcode)
-        {
-        case AML_PROCESSOR_OP:
-
-            Status = AcpiExCreateProcessor (WalkState);
-            break;
-
-        case AML_POWER_RES_OP:
-
-            Status = AcpiExCreatePowerResource (WalkState);
-            break;
-
-        case AML_MUTEX_OP:
-
-            Status = AcpiExCreateMutex (WalkState);
-            break;
-
-        case AML_EVENT_OP:
-
-            Status = AcpiExCreateEvent (WalkState);
-            break;
-
-
-        case AML_ALIAS_OP:
-
-            Status = AcpiExCreateAlias (WalkState);
-            break;
-
-        default:
-            /* Unknown opcode */
-
-            Status = AE_OK;
-            goto Cleanup;
-        }
-
-        /* Delete operands */
-
-        for (i = 1; i < WalkState->NumOperands; i++)
-        {
-            AcpiUtRemoveReference (WalkState->Operands[i]);
-            WalkState->Operands[i] = NULL;
-        }
-
-        break;
-#endif /* ACPI_NO_METHOD_EXECUTION */
-
-    case AML_TYPE_NAMED_COMPLEX:
-
-        switch (Op->Common.AmlOpcode)
-        {
-#ifndef ACPI_NO_METHOD_EXECUTION
-        case AML_REGION_OP:
-        case AML_DATA_REGION_OP:
-
-            if (Op->Common.AmlOpcode == AML_REGION_OP)
-            {
-                RegionSpace = (ACPI_ADR_SPACE_TYPE)
-                      ((Op->Common.Value.Arg)->Common.Value.Integer);
-            }
-            else
-            {
-                RegionSpace = REGION_DATA_TABLE;
-            }
-
-            /*
-             * The OpRegion is not fully parsed at this time. The only valid
-             * argument is the SpaceId. (We must save the address of the
-             * AML of the address and length operands)
-             *
-             * If we have a valid region, initialize it. The namespace is
-             * unlocked at this point.
-             *
-             * Need to unlock interpreter if it is locked (if we are running
-             * a control method), in order to allow _REG methods to be run
-             * during AcpiEvInitializeRegion.
-             */
-            if (WalkState->MethodNode)
-            {
-                /*
-                 * Executing a method: initialize the region and unlock
-                 * the interpreter
-                 */
-                Status = AcpiExCreateRegion (Op->Named.Data, Op->Named.Length,
-                            RegionSpace, WalkState);
-                if (ACPI_FAILURE (Status))
-                {
-                    return (Status);
-                }
-
-                AcpiExExitInterpreter ();
-            }
-
-            Status = AcpiEvInitializeRegion (AcpiNsGetAttachedObject (Node),
-                        FALSE);
-            if (WalkState->MethodNode)
-            {
-                AcpiExEnterInterpreter ();
-            }
-
-            if (ACPI_FAILURE (Status))
-            {
-                /*
-                 *  If AE_NOT_EXIST is returned, it is not fatal
-                 *  because many regions get created before a handler
-                 *  is installed for said region.
-                 */
-                if (AE_NOT_EXIST == Status)
-                {
-                    Status = AE_OK;
-                }
-            }
-            break;
-
-
-        case AML_NAME_OP:
-
-            Status = AcpiDsCreateNode (WalkState, Node, Op);
-            break;
-
-
-        case AML_METHOD_OP:
-            /*
-             * MethodOp PkgLength NameString MethodFlags TermList
-             *
-             * Note: We must create the method node/object pair as soon as we
-             * see the method declaration. This allows later pass1 parsing
-             * of invocations of the method (need to know the number of
-             * arguments.)
-             */
-            ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-                "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
-                WalkState, Op, Op->Named.Node));
-
-            if (!AcpiNsGetAttachedObject (Op->Named.Node))
-            {
-                WalkState->Operands[0] = ACPI_CAST_PTR (void, Op->Named.Node);
-                WalkState->NumOperands = 1;
-
-                Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
-                if (ACPI_SUCCESS (Status))
-                {
-                    Status = AcpiExCreateMethod (Op->Named.Data,
-                                        Op->Named.Length, WalkState);
-                }
-                WalkState->Operands[0] = NULL;
-                WalkState->NumOperands = 0;
-
-                if (ACPI_FAILURE (Status))
-                {
-                    return_ACPI_STATUS (Status);
-                }
-            }
-            break;
-
-#endif /* ACPI_NO_METHOD_EXECUTION */
-
-        default:
-            /* All NAMED_COMPLEX opcodes must be handled above */
-            break;
-        }
-        break;
-
-
-    case AML_CLASS_INTERNAL:
-
-        /* case AML_INT_NAMEPATH_OP: */
-        break;
-
-
-    case AML_CLASS_METHOD_CALL:
-
-        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-            "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
-            WalkState, Op, Node));
-
-        /*
-         * Lookup the method name and save the Node
-         */
-        Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
-                        ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS2,
-                        ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
-                        WalkState, &(NewNode));
-        if (ACPI_SUCCESS (Status))
-        {
-            /*
-             * Make sure that what we found is indeed a method
-             * We didn't search for a method on purpose, to see if the name
-             * would resolve
-             */
-            if (NewNode->Type != ACPI_TYPE_METHOD)
-            {
-                Status = AE_AML_OPERAND_TYPE;
-            }
-
-            /* We could put the returned object (Node) on the object stack for
-             * later, but for now, we will put it in the "op" object that the
-             * parser uses, so we can get it again at the end of this scope
-             */
-            Op->Common.Node = NewNode;
-        }
-        else
-        {
-            ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
-        }
-        break;
-
-
-    default:
-        break;
-    }
-
-Cleanup:
-
-    /* Remove the Node pushed at the very beginning */
-
-    WalkState->Operands[0] = NULL;
-    WalkState->NumOperands = 0;
-    return_ACPI_STATUS (Status);
-}
-
-
diff --git a/reactos/drivers/bus/acpi/acpica/dispatcher/dswload2.c b/reactos/drivers/bus/acpi/acpica/dispatcher/dswload2.c
new file mode 100644 (file)
index 0000000..8eba533
--- /dev/null
@@ -0,0 +1,819 @@
+/******************************************************************************
+ *
+ * Module Name: dswload2 - Dispatcher second pass namespace load callbacks
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * 1. Copyright Notice
+ *
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
+ * All rights reserved.
+ *
+ * 2. License
+ *
+ * 2.1. This is your license from Intel Corp. under its intellectual property
+ * rights.  You may have additional license terms from the party that provided
+ * you this software, covering your right to use that party's intellectual
+ * property rights.
+ *
+ * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
+ * copy of the source code appearing in this file ("Covered Code") an
+ * irrevocable, perpetual, worldwide license under Intel's copyrights in the
+ * base code distributed originally by Intel ("Original Intel Code") to copy,
+ * make derivatives, distribute, use and display any portion of the Covered
+ * Code in any form, with the right to sublicense such rights; and
+ *
+ * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
+ * license (with the right to sublicense), under only those claims of Intel
+ * patents that are infringed by the Original Intel Code, to make, use, sell,
+ * offer to sell, and import the Covered Code and derivative works thereof
+ * solely to the minimum extent necessary to exercise the above copyright
+ * license, and in no event shall the patent license extend to any additions
+ * to or modifications of the Original Intel Code.  No other license or right
+ * is granted directly or by implication, estoppel or otherwise;
+ *
+ * The above copyright and patent license is granted only if the following
+ * conditions are met:
+ *
+ * 3. Conditions
+ *
+ * 3.1. Redistribution of Source with Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification with rights to further distribute source must include
+ * the above Copyright Notice, the above License, this list of Conditions,
+ * and the following Disclaimer and Export Compliance provision.  In addition,
+ * Licensee must cause all Covered Code to which Licensee contributes to
+ * contain a file documenting the changes Licensee made to create that Covered
+ * Code and the date of any change.  Licensee must include in that file the
+ * documentation of any changes made by any predecessor Licensee.  Licensee
+ * must include a prominent statement that the modification is derived,
+ * directly or indirectly, from Original Intel Code.
+ *
+ * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification without rights to further distribute source must
+ * include the following Disclaimer and Export Compliance provision in the
+ * documentation and/or other materials provided with distribution.  In
+ * addition, Licensee may not authorize further sublicense of source of any
+ * portion of the Covered Code, and must include terms to the effect that the
+ * license from Licensee to its licensee is limited to the intellectual
+ * property embodied in the software Licensee provides to its licensee, and
+ * not to intellectual property embodied in modifications its licensee may
+ * make.
+ *
+ * 3.3. Redistribution of Executable. Redistribution in executable form of any
+ * substantial portion of the Covered Code or modification must reproduce the
+ * above Copyright Notice, and the following Disclaimer and Export Compliance
+ * provision in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3.4. Intel retains all right, title, and interest in and to the Original
+ * Intel Code.
+ *
+ * 3.5. Neither the name Intel nor any other trademark owned or controlled by
+ * Intel shall be used in advertising or otherwise to promote the sale, use or
+ * other dealings in products derived from or relating to the Covered Code
+ * without prior written authorization from Intel.
+ *
+ * 4. Disclaimer and Export Compliance
+ *
+ * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
+ * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
+ * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
+ * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
+ * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
+ * PARTICULAR PURPOSE.
+ *
+ * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
+ * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
+ * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
+ * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
+ * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
+ * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
+ * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
+ * LIMITED REMEDY.
+ *
+ * 4.3. Licensee shall not export, either directly or indirectly, any of this
+ * software or system incorporating such software without first obtaining any
+ * required license or other approval from the U. S. Department of Commerce or
+ * any other agency or department of the United States Government.  In the
+ * event Licensee exports any such software from the United States or
+ * re-exports any such software from a foreign destination, Licensee shall
+ * ensure that the distribution and export/re-export of the software is in
+ * compliance with all laws, regulations, orders, or other restrictions of the
+ * U.S. Export Administration Regulations. Licensee agrees that neither it nor
+ * any of its subsidiaries will export/re-export any technical data, process,
+ * software, or service, directly or indirectly, to any country for which the
+ * United States government or any agency thereof requires an export license,
+ * other governmental approval, or letter of assurance, without first obtaining
+ * such license, approval or letter.
+ *
+ *****************************************************************************/
+
+#define __DSWLOAD2_C__
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acparser.h"
+#include "amlcode.h"
+#include "acdispat.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "acevents.h"
+
+#define _COMPONENT          ACPI_DISPATCHER
+        ACPI_MODULE_NAME    ("dswload2")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsLoad2BeginOp
+ *
+ * PARAMETERS:  WalkState       - Current state of the parse tree walk
+ *              OutOp           - Wher to return op if a new one is created
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Descending callback used during the loading of ACPI tables.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsLoad2BeginOp (
+    ACPI_WALK_STATE         *WalkState,
+    ACPI_PARSE_OBJECT       **OutOp)
+{
+    ACPI_PARSE_OBJECT       *Op;
+    ACPI_NAMESPACE_NODE     *Node;
+    ACPI_STATUS             Status;
+    ACPI_OBJECT_TYPE        ObjectType;
+    char                    *BufferPtr;
+    UINT32                  Flags;
+
+
+    ACPI_FUNCTION_TRACE (DsLoad2BeginOp);
+
+
+    Op = WalkState->Op;
+    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", Op, WalkState));
+
+    if (Op)
+    {
+        if ((WalkState->ControlState) &&
+            (WalkState->ControlState->Common.State ==
+                ACPI_CONTROL_CONDITIONAL_EXECUTING))
+        {
+            /* We are executing a while loop outside of a method */
+
+            Status = AcpiDsExecBeginOp (WalkState, OutOp);
+            return_ACPI_STATUS (Status);
+        }
+
+        /* We only care about Namespace opcodes here */
+
+        if ((!(WalkState->OpInfo->Flags & AML_NSOPCODE)   &&
+              (WalkState->Opcode != AML_INT_NAMEPATH_OP)) ||
+            (!(WalkState->OpInfo->Flags & AML_NAMED)))
+        {
+            return_ACPI_STATUS (AE_OK);
+        }
+
+        /* Get the name we are going to enter or lookup in the namespace */
+
+        if (WalkState->Opcode == AML_INT_NAMEPATH_OP)
+        {
+            /* For Namepath op, get the path string */
+
+            BufferPtr = Op->Common.Value.String;
+            if (!BufferPtr)
+            {
+                /* No name, just exit */
+
+                return_ACPI_STATUS (AE_OK);
+            }
+        }
+        else
+        {
+            /* Get name from the op */
+
+            BufferPtr = ACPI_CAST_PTR (char, &Op->Named.Name);
+        }
+    }
+    else
+    {
+        /* Get the namestring from the raw AML */
+
+        BufferPtr = AcpiPsGetNextNamestring (&WalkState->ParserState);
+    }
+
+    /* Map the opcode into an internal object type */
+
+    ObjectType = WalkState->OpInfo->ObjectType;
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+        "State=%p Op=%p Type=%X\n", WalkState, Op, ObjectType));
+
+    switch (WalkState->Opcode)
+    {
+    case AML_FIELD_OP:
+    case AML_BANK_FIELD_OP:
+    case AML_INDEX_FIELD_OP:
+
+        Node = NULL;
+        Status = AE_OK;
+        break;
+
+    case AML_INT_NAMEPATH_OP:
+        /*
+         * The NamePath is an object reference to an existing object.
+         * Don't enter the name into the namespace, but look it up
+         * for use later.
+         */
+        Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType,
+                        ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+                        WalkState, &(Node));
+        break;
+
+    case AML_SCOPE_OP:
+
+        /* Special case for Scope(\) -> refers to the Root node */
+
+        if (Op && (Op->Named.Node == AcpiGbl_RootNode))
+        {
+            Node = Op->Named.Node;
+
+            Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
+            if (ACPI_FAILURE (Status))
+            {
+                return_ACPI_STATUS (Status);
+            }
+        }
+        else
+        {
+            /*
+             * The Path is an object reference to an existing object.
+             * Don't enter the name into the namespace, but look it up
+             * for use later.
+             */
+            Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType,
+                        ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+                        WalkState, &(Node));
+            if (ACPI_FAILURE (Status))
+            {
+#ifdef ACPI_ASL_COMPILER
+                if (Status == AE_NOT_FOUND)
+                {
+                    Status = AE_OK;
+                }
+                else
+                {
+                    ACPI_ERROR_NAMESPACE (BufferPtr, Status);
+                }
+#else
+                ACPI_ERROR_NAMESPACE (BufferPtr, Status);
+#endif
+                return_ACPI_STATUS (Status);
+            }
+        }
+
+        /*
+         * We must check to make sure that the target is
+         * one of the opcodes that actually opens a scope
+         */
+        switch (Node->Type)
+        {
+        case ACPI_TYPE_ANY:
+        case ACPI_TYPE_LOCAL_SCOPE:         /* Scope */
+        case ACPI_TYPE_DEVICE:
+        case ACPI_TYPE_POWER:
+        case ACPI_TYPE_PROCESSOR:
+        case ACPI_TYPE_THERMAL:
+
+            /* These are acceptable types */
+            break;
+
+        case ACPI_TYPE_INTEGER:
+        case ACPI_TYPE_STRING:
+        case ACPI_TYPE_BUFFER:
+
+            /*
+             * These types we will allow, but we will change the type.
+             * This enables some existing code of the form:
+             *
+             *  Name (DEB, 0)
+             *  Scope (DEB) { ... }
+             */
+            ACPI_WARNING ((AE_INFO,
+                "Type override - [%4.4s] had invalid type (%s) "
+                "for Scope operator, changed to type ANY\n",
+                AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type)));
+
+            Node->Type = ACPI_TYPE_ANY;
+            WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY;
+            break;
+
+        default:
+
+            /* All other types are an error */
+
+            ACPI_ERROR ((AE_INFO,
+                "Invalid type (%s) for target of "
+                "Scope operator [%4.4s] (Cannot override)",
+                AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node)));
+
+            return (AE_AML_OPERAND_TYPE);
+        }
+        break;
+
+    default:
+
+        /* All other opcodes */
+
+        if (Op && Op->Common.Node)
+        {
+            /* This op/node was previously entered into the namespace */
+
+            Node = Op->Common.Node;
+
+            if (AcpiNsOpensScope (ObjectType))
+            {
+                Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
+                if (ACPI_FAILURE (Status))
+                {
+                    return_ACPI_STATUS (Status);
+                }
+            }
+
+            return_ACPI_STATUS (AE_OK);
+        }
+
+        /*
+         * Enter the named type into the internal namespace. We enter the name
+         * as we go downward in the parse tree. Any necessary subobjects that
+         * involve arguments to the opcode must be created as we go back up the
+         * parse tree later.
+         *
+         * Note: Name may already exist if we are executing a deferred opcode.
+         */
+        if (WalkState->DeferredNode)
+        {
+            /* This name is already in the namespace, get the node */
+
+            Node = WalkState->DeferredNode;
+            Status = AE_OK;
+            break;
+        }
+
+        Flags = ACPI_NS_NO_UPSEARCH;
+        if (WalkState->PassNumber == ACPI_IMODE_EXECUTE)
+        {
+            /* Execution mode, node cannot already exist, node is temporary */
+
+            Flags |= ACPI_NS_ERROR_IF_FOUND;
+
+            if (!(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
+            {
+                Flags |= ACPI_NS_TEMPORARY;
+            }
+        }
+
+        /* Add new entry or lookup existing entry */
+
+        Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType,
+                    ACPI_IMODE_LOAD_PASS2, Flags, WalkState, &Node);
+
+        if (ACPI_SUCCESS (Status) && (Flags & ACPI_NS_TEMPORARY))
+        {
+            ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+                "***New Node [%4.4s] %p is temporary\n",
+                AcpiUtGetNodeName (Node), Node));
+        }
+        break;
+    }
+
+    if (ACPI_FAILURE (Status))
+    {
+        ACPI_ERROR_NAMESPACE (BufferPtr, Status);
+        return_ACPI_STATUS (Status);
+    }
+
+    if (!Op)
+    {
+        /* Create a new op */
+
+        Op = AcpiPsAllocOp (WalkState->Opcode);
+        if (!Op)
+        {
+            return_ACPI_STATUS (AE_NO_MEMORY);
+        }
+
+        /* Initialize the new op */
+
+        if (Node)
+        {
+            Op->Named.Name = Node->Name.Integer;
+        }
+        *OutOp = Op;
+    }
+
+    /*
+     * Put the Node in the "op" object that the parser uses, so we
+     * can get it again quickly when this scope is closed
+     */
+    Op->Common.Node = Node;
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsLoad2EndOp
+ *
+ * PARAMETERS:  WalkState       - Current state of the parse tree walk
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Ascending callback used during the loading of the namespace,
+ *              both control methods and everything else.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsLoad2EndOp (
+    ACPI_WALK_STATE         *WalkState)
+{
+    ACPI_PARSE_OBJECT       *Op;
+    ACPI_STATUS             Status = AE_OK;
+    ACPI_OBJECT_TYPE        ObjectType;
+    ACPI_NAMESPACE_NODE     *Node;
+    ACPI_PARSE_OBJECT       *Arg;
+    ACPI_NAMESPACE_NODE     *NewNode;
+#ifndef ACPI_NO_METHOD_EXECUTION
+    UINT32                  i;
+    UINT8                   RegionSpace;
+#endif
+
+
+    ACPI_FUNCTION_TRACE (DsLoad2EndOp);
+
+    Op = WalkState->Op;
+    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
+            WalkState->OpInfo->Name, Op, WalkState));
+
+    /* Check if opcode had an associated namespace object */
+
+    if (!(WalkState->OpInfo->Flags & AML_NSOBJECT))
+    {
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    if (Op->Common.AmlOpcode == AML_SCOPE_OP)
+    {
+        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+            "Ending scope Op=%p State=%p\n", Op, WalkState));
+    }
+
+    ObjectType = WalkState->OpInfo->ObjectType;
+
+    /*
+     * Get the Node/name from the earlier lookup
+     * (It was saved in the *op structure)
+     */
+    Node = Op->Common.Node;
+
+    /*
+     * Put the Node on the object stack (Contains the ACPI Name of
+     * this object)
+     */
+    WalkState->Operands[0] = (void *) Node;
+    WalkState->NumOperands = 1;
+
+    /* Pop the scope stack */
+
+    if (AcpiNsOpensScope (ObjectType) &&
+       (Op->Common.AmlOpcode != AML_INT_METHODCALL_OP))
+    {
+        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
+            AcpiUtGetTypeName (ObjectType), Op));
+
+        Status = AcpiDsScopeStackPop (WalkState);
+        if (ACPI_FAILURE (Status))
+        {
+            goto Cleanup;
+        }
+    }
+
+    /*
+     * Named operations are as follows:
+     *
+     * AML_ALIAS
+     * AML_BANKFIELD
+     * AML_CREATEBITFIELD
+     * AML_CREATEBYTEFIELD
+     * AML_CREATEDWORDFIELD
+     * AML_CREATEFIELD
+     * AML_CREATEQWORDFIELD
+     * AML_CREATEWORDFIELD
+     * AML_DATA_REGION
+     * AML_DEVICE
+     * AML_EVENT
+     * AML_FIELD
+     * AML_INDEXFIELD
+     * AML_METHOD
+     * AML_METHODCALL
+     * AML_MUTEX
+     * AML_NAME
+     * AML_NAMEDFIELD
+     * AML_OPREGION
+     * AML_POWERRES
+     * AML_PROCESSOR
+     * AML_SCOPE
+     * AML_THERMALZONE
+     */
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+        "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
+        AcpiPsGetOpcodeName (Op->Common.AmlOpcode), WalkState, Op, Node));
+
+    /* Decode the opcode */
+
+    Arg = Op->Common.Value.Arg;
+
+    switch (WalkState->OpInfo->Type)
+    {
+#ifndef ACPI_NO_METHOD_EXECUTION
+
+    case AML_TYPE_CREATE_FIELD:
+        /*
+         * Create the field object, but the field buffer and index must
+         * be evaluated later during the execution phase
+         */
+        Status = AcpiDsCreateBufferField (Op, WalkState);
+        break;
+
+
+     case AML_TYPE_NAMED_FIELD:
+        /*
+         * If we are executing a method, initialize the field
+         */
+        if (WalkState->MethodNode)
+        {
+            Status = AcpiDsInitFieldObjects (Op, WalkState);
+        }
+
+        switch (Op->Common.AmlOpcode)
+        {
+        case AML_INDEX_FIELD_OP:
+
+            Status = AcpiDsCreateIndexField (Op, (ACPI_HANDLE) Arg->Common.Node,
+                        WalkState);
+            break;
+
+        case AML_BANK_FIELD_OP:
+
+            Status = AcpiDsCreateBankField (Op, Arg->Common.Node, WalkState);
+            break;
+
+        case AML_FIELD_OP:
+
+            Status = AcpiDsCreateField (Op, Arg->Common.Node, WalkState);
+            break;
+
+        default:
+            /* All NAMED_FIELD opcodes must be handled above */
+            break;
+        }
+        break;
+
+
+     case AML_TYPE_NAMED_SIMPLE:
+
+        Status = AcpiDsCreateOperands (WalkState, Arg);
+        if (ACPI_FAILURE (Status))
+        {
+            goto Cleanup;
+        }
+
+        switch (Op->Common.AmlOpcode)
+        {
+        case AML_PROCESSOR_OP:
+
+            Status = AcpiExCreateProcessor (WalkState);
+            break;
+
+        case AML_POWER_RES_OP:
+
+            Status = AcpiExCreatePowerResource (WalkState);
+            break;
+
+        case AML_MUTEX_OP:
+
+            Status = AcpiExCreateMutex (WalkState);
+            break;
+
+        case AML_EVENT_OP:
+
+            Status = AcpiExCreateEvent (WalkState);
+            break;
+
+
+        case AML_ALIAS_OP:
+
+            Status = AcpiExCreateAlias (WalkState);
+            break;
+
+        default:
+            /* Unknown opcode */
+
+            Status = AE_OK;
+            goto Cleanup;
+        }
+
+        /* Delete operands */
+
+        for (i = 1; i < WalkState->NumOperands; i++)
+        {
+            AcpiUtRemoveReference (WalkState->Operands[i]);
+            WalkState->Operands[i] = NULL;
+        }
+
+        break;
+#endif /* ACPI_NO_METHOD_EXECUTION */
+
+    case AML_TYPE_NAMED_COMPLEX:
+
+        switch (Op->Common.AmlOpcode)
+        {
+#ifndef ACPI_NO_METHOD_EXECUTION
+        case AML_REGION_OP:
+        case AML_DATA_REGION_OP:
+
+            if (Op->Common.AmlOpcode == AML_REGION_OP)
+            {
+                RegionSpace = (ACPI_ADR_SPACE_TYPE)
+                      ((Op->Common.Value.Arg)->Common.Value.Integer);
+            }
+            else
+            {
+                RegionSpace = ACPI_ADR_SPACE_DATA_TABLE;
+            }
+
+            /*
+             * The OpRegion is not fully parsed at this time. The only valid
+             * argument is the SpaceId. (We must save the address of the
+             * AML of the address and length operands)
+             *
+             * If we have a valid region, initialize it. The namespace is
+             * unlocked at this point.
+             *
+             * Need to unlock interpreter if it is locked (if we are running
+             * a control method), in order to allow _REG methods to be run
+             * during AcpiEvInitializeRegion.
+             */
+            if (WalkState->MethodNode)
+            {
+                /*
+                 * Executing a method: initialize the region and unlock
+                 * the interpreter
+                 */
+                Status = AcpiExCreateRegion (Op->Named.Data, Op->Named.Length,
+                            RegionSpace, WalkState);
+                if (ACPI_FAILURE (Status))
+                {
+                    return (Status);
+                }
+
+                AcpiExExitInterpreter ();
+            }
+
+            Status = AcpiEvInitializeRegion (AcpiNsGetAttachedObject (Node),
+                        FALSE);
+            if (WalkState->MethodNode)
+            {
+                AcpiExEnterInterpreter ();
+            }
+
+            if (ACPI_FAILURE (Status))
+            {
+                /*
+                 *  If AE_NOT_EXIST is returned, it is not fatal
+                 *  because many regions get created before a handler
+                 *  is installed for said region.
+                 */
+                if (AE_NOT_EXIST == Status)
+                {
+                    Status = AE_OK;
+                }
+            }
+            break;
+
+
+        case AML_NAME_OP:
+
+            Status = AcpiDsCreateNode (WalkState, Node, Op);
+            break;
+
+
+        case AML_METHOD_OP:
+            /*
+             * MethodOp PkgLength NameString MethodFlags TermList
+             *
+             * Note: We must create the method node/object pair as soon as we
+             * see the method declaration. This allows later pass1 parsing
+             * of invocations of the method (need to know the number of
+             * arguments.)
+             */
+            ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+                "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
+                WalkState, Op, Op->Named.Node));
+
+            if (!AcpiNsGetAttachedObject (Op->Named.Node))
+            {
+                WalkState->Operands[0] = ACPI_CAST_PTR (void, Op->Named.Node);
+                WalkState->NumOperands = 1;
+
+                Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
+                if (ACPI_SUCCESS (Status))
+                {
+                    Status = AcpiExCreateMethod (Op->Named.Data,
+                                        Op->Named.Length, WalkState);
+                }
+                WalkState->Operands[0] = NULL;
+                WalkState->NumOperands = 0;
+
+                if (ACPI_FAILURE (Status))
+                {
+                    return_ACPI_STATUS (Status);
+                }
+            }
+            break;
+
+#endif /* ACPI_NO_METHOD_EXECUTION */
+
+        default:
+            /* All NAMED_COMPLEX opcodes must be handled above */
+            break;
+        }
+        break;
+
+
+    case AML_CLASS_INTERNAL:
+
+        /* case AML_INT_NAMEPATH_OP: */
+        break;
+
+
+    case AML_CLASS_METHOD_CALL:
+
+        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+            "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
+            WalkState, Op, Node));
+
+        /*
+         * Lookup the method name and save the Node
+         */
+        Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
+                        ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS2,
+                        ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+                        WalkState, &(NewNode));
+        if (ACPI_SUCCESS (Status))
+        {
+            /*
+             * Make sure that what we found is indeed a method
+             * We didn't search for a method on purpose, to see if the name
+             * would resolve
+             */
+            if (NewNode->Type != ACPI_TYPE_METHOD)
+            {
+                Status = AE_AML_OPERAND_TYPE;
+            }
+
+            /* We could put the returned object (Node) on the object stack for
+             * later, but for now, we will put it in the "op" object that the
+             * parser uses, so we can get it again at the end of this scope
+             */
+            Op->Common.Node = NewNode;
+        }
+        else
+        {
+            ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
+        }
+        break;
+
+
+    default:
+        break;
+    }
+
+Cleanup:
+
+    /* Remove the Node pushed at the very beginning */
+
+    WalkState->Operands[0] = NULL;
+    WalkState->NumOperands = 0;
+    return_ACPI_STATUS (Status);
+}
+
index 023f9ef..b95c427 100644 (file)
@@ -8,7 +8,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
index f0962bf..07ed6d4 100644 (file)
@@ -8,7 +8,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
@@ -277,7 +277,7 @@ AcpiDsResultPush (
     if (!Object)
     {
         ACPI_ERROR ((AE_INFO,
-            "Null Object! Obj=%p State=%p Num=%X",
+            "Null Object! Obj=%p State=%p Num=%u",
             Object, WalkState, WalkState->ResultCount));
         return (AE_BAD_PARAMETER);
     }
@@ -323,7 +323,7 @@ AcpiDsResultStackPush (
     if (((UINT32) WalkState->ResultSize + ACPI_RESULTS_FRAME_OBJ_NUM) >
         ACPI_RESULTS_OBJ_NUM_MAX)
     {
-        ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%X",
+        ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%u",
             WalkState, WalkState->ResultSize));
         return (AE_STACK_OVERFLOW);
     }
@@ -426,7 +426,7 @@ AcpiDsObjStackPush (
     if (WalkState->NumOperands >= ACPI_OBJ_NUM_OPERANDS)
     {
         ACPI_ERROR ((AE_INFO,
-            "Object stack overflow! Obj=%p State=%p #Ops=%X",
+            "Object stack overflow! Obj=%p State=%p #Ops=%u",
             Object, WalkState, WalkState->NumOperands));
         return (AE_STACK_OVERFLOW);
     }
@@ -480,7 +480,7 @@ AcpiDsObjStackPop (
         if (WalkState->NumOperands == 0)
         {
             ACPI_ERROR ((AE_INFO,
-                "Object stack underflow! Count=%X State=%p #Ops=%X",
+                "Object stack underflow! Count=%X State=%p #Ops=%u",
                 PopCount, WalkState, WalkState->NumOperands));
             return (AE_STACK_UNDERFLOW);
         }
@@ -491,7 +491,7 @@ AcpiDsObjStackPop (
         WalkState->Operands [WalkState->NumOperands] = NULL;
     }
 
-    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
+    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n",
         PopCount, WalkState, WalkState->NumOperands));
 
     return (AE_OK);
index 16f4027..a85588f 100644 (file)
@@ -8,7 +8,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
@@ -178,54 +178,6 @@ AcpiEvInitializeEvents (
 }
 
 
-/*******************************************************************************
- *
- * FUNCTION:    AcpiEvInstallFadtGpes
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks
- *              (0 and 1). This causes the _PRW methods to be run, so the HW
- *              must be fully initialized at this point, including global lock
- *              support.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiEvInstallFadtGpes (
-    void)
-{
-    ACPI_STATUS             Status;
-
-
-    ACPI_FUNCTION_TRACE (EvInstallFadtGpes);
-
-
-    /* Namespace must be locked */
-
-    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
-    if (ACPI_FAILURE (Status))
-    {
-        return (Status);
-    }
-
-    /* FADT GPE Block 0 */
-
-    (void) AcpiEvInitializeGpeBlock (
-                AcpiGbl_FadtGpeDevice, AcpiGbl_GpeFadtBlocks[0]);
-
-    /* FADT GPE Block 1 */
-
-    (void) AcpiEvInitializeGpeBlock (
-                AcpiGbl_FadtGpeDevice, AcpiGbl_GpeFadtBlocks[1]);
-
-    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
-    return_ACPI_STATUS (AE_OK);
-}
-
-
 /*******************************************************************************
  *
  * FUNCTION:    AcpiEvInstallXruptHandlers
@@ -366,9 +318,17 @@ AcpiEvFixedEventDetect (
         if ((FixedStatus & AcpiGbl_FixedEventInfo[i].StatusBitMask) &&
             (FixedEnable & AcpiGbl_FixedEventInfo[i].EnableBitMask))
         {
-            /* Found an active (signalled) event */
-
+            /*
+             * Found an active (signalled) event. Invoke global event
+             * handler if present.
+             */
             AcpiFixedEventCount[i]++;
+            if (AcpiGbl_GlobalEventHandler)
+            {
+                AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_FIXED, NULL,
+                     i, AcpiGbl_GlobalEventHandlerContext);
+            }
+
             IntStatus |= AcpiEvFixedEventDispatch (i);
         }
     }
@@ -415,7 +375,7 @@ AcpiEvFixedEventDispatch (
                 ACPI_DISABLE_EVENT);
 
         ACPI_ERROR ((AE_INFO,
-            "No installed handler for fixed event [%08X]",
+            "No installed handler for fixed event [0x%08X]",
             Event));
 
         return (ACPI_INTERRUPT_NOT_HANDLED);
diff --git a/reactos/drivers/bus/acpi/acpica/events/evglock.c b/reactos/drivers/bus/acpi/acpica/events/evglock.c
new file mode 100644 (file)
index 0000000..a7a585a
--- /dev/null
@@ -0,0 +1,439 @@
+/******************************************************************************
+ *
+ * Module Name: evglock - Global Lock support
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * 1. Copyright Notice
+ *
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
+ * All rights reserved.
+ *
+ * 2. License
+ *
+ * 2.1. This is your license from Intel Corp. under its intellectual property
+ * rights.  You may have additional license terms from the party that provided
+ * you this software, covering your right to use that party's intellectual
+ * property rights.
+ *
+ * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
+ * copy of the source code appearing in this file ("Covered Code") an
+ * irrevocable, perpetual, worldwide license under Intel's copyrights in the
+ * base code distributed originally by Intel ("Original Intel Code") to copy,
+ * make derivatives, distribute, use and display any portion of the Covered
+ * Code in any form, with the right to sublicense such rights; and
+ *
+ * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
+ * license (with the right to sublicense), under only those claims of Intel
+ * patents that are infringed by the Original Intel Code, to make, use, sell,
+ * offer to sell, and import the Covered Code and derivative works thereof
+ * solely to the minimum extent necessary to exercise the above copyright
+ * license, and in no event shall the patent license extend to any additions
+ * to or modifications of the Original Intel Code.  No other license or right
+ * is granted directly or by implication, estoppel or otherwise;
+ *
+ * The above copyright and patent license is granted only if the following
+ * conditions are met:
+ *
+ * 3. Conditions
+ *
+ * 3.1. Redistribution of Source with Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification with rights to further distribute source must include
+ * the above Copyright Notice, the above License, this list of Conditions,
+ * and the following Disclaimer and Export Compliance provision.  In addition,
+ * Licensee must cause all Covered Code to which Licensee contributes to
+ * contain a file documenting the changes Licensee made to create that Covered
+ * Code and the date of any change.  Licensee must include in that file the
+ * documentation of any changes made by any predecessor Licensee.  Licensee
+ * must include a prominent statement that the modification is derived,
+ * directly or indirectly, from Original Intel Code.
+ *
+ * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification without rights to further distribute source must
+ * include the following Disclaimer and Export Compliance provision in the
+ * documentation and/or other materials provided with distribution.  In
+ * addition, Licensee may not authorize further sublicense of source of any
+ * portion of the Covered Code, and must include terms to the effect that the
+ * license from Licensee to its licensee is limited to the intellectual
+ * property embodied in the software Licensee provides to its licensee, and
+ * not to intellectual property embodied in modifications its licensee may
+ * make.
+ *
+ * 3.3. Redistribution of Executable. Redistribution in executable form of any
+ * substantial portion of the Covered Code or modification must reproduce the
+ * above Copyright Notice, and the following Disclaimer and Export Compliance
+ * provision in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3.4. Intel retains all right, title, and interest in and to the Original
+ * Intel Code.
+ *
+ * 3.5. Neither the name Intel nor any other trademark owned or controlled by
+ * Intel shall be used in advertising or otherwise to promote the sale, use or
+ * other dealings in products derived from or relating to the Covered Code
+ * without prior written authorization from Intel.
+ *
+ * 4. Disclaimer and Export Compliance
+ *
+ * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
+ * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
+ * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
+ * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
+ * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
+ * PARTICULAR PURPOSE.
+ *
+ * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
+ * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
+ * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
+ * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
+ * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
+ * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
+ * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
+ * LIMITED REMEDY.
+ *
+ * 4.3. Licensee shall not export, either directly or indirectly, any of this
+ * software or system incorporating such software without first obtaining any
+ * required license or other approval from the U. S. Department of Commerce or
+ * any other agency or department of the United States Government.  In the
+ * event Licensee exports any such software from the United States or
+ * re-exports any such software from a foreign destination, Licensee shall
+ * ensure that the distribution and export/re-export of the software is in
+ * compliance with all laws, regulations, orders, or other restrictions of the
+ * U.S. Export Administration Regulations. Licensee agrees that neither it nor
+ * any of its subsidiaries will export/re-export any technical data, process,
+ * software, or service, directly or indirectly, to any country for which the
+ * United States government or any agency thereof requires an export license,
+ * other governmental approval, or letter of assurance, without first obtaining
+ * such license, approval or letter.
+ *
+ *****************************************************************************/
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acevents.h"
+#include "acinterp.h"
+
+#define _COMPONENT          ACPI_EVENTS
+        ACPI_MODULE_NAME    ("evglock")
+
+
+/* Local prototypes */
+
+static UINT32
+AcpiEvGlobalLockHandler (
+    void                    *Context);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiEvInitGlobalLockHandler
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install a handler for the global lock release event
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvInitGlobalLockHandler (
+    void)
+{
+    ACPI_STATUS             Status;
+
+
+    ACPI_FUNCTION_TRACE (EvInitGlobalLockHandler);
+
+
+    /* Attempt installation of the global lock handler */
+
+    Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL,
+                AcpiEvGlobalLockHandler, NULL);
+
+    /*
+     * If the global lock does not exist on this platform, the attempt to
+     * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick).
+     * Map to AE_OK, but mark global lock as not present. Any attempt to
+     * actually use the global lock will be flagged with an error.
+     */
+    AcpiGbl_GlobalLockPresent = FALSE;
+    if (Status == AE_NO_HARDWARE_RESPONSE)
+    {
+        ACPI_ERROR ((AE_INFO,
+            "No response from Global Lock hardware, disabling lock"));
+
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    Status = AcpiOsCreateLock (&AcpiGbl_GlobalLockPendingLock);
+    if (ACPI_FAILURE (Status))
+    {
+        return_ACPI_STATUS (Status);
+    }
+
+    AcpiGbl_GlobalLockPending = FALSE;
+    AcpiGbl_GlobalLockPresent = TRUE;
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiEvRemoveGlobalLockHandler
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove the handler for the Global Lock
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvRemoveGlobalLockHandler (
+    void)
+{
+    ACPI_STATUS             Status;
+
+
+    ACPI_FUNCTION_TRACE (EvRemoveGlobalLockHandler);
+
+    AcpiGbl_GlobalLockPresent = FALSE;
+    Status = AcpiRemoveFixedEventHandler (ACPI_EVENT_GLOBAL,
+                AcpiEvGlobalLockHandler);
+
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiEvGlobalLockHandler
+ *
+ * PARAMETERS:  Context         - From thread interface, not used
+ *
+ * RETURN:      ACPI_INTERRUPT_HANDLED
+ *
+ * DESCRIPTION: Invoked directly from the SCI handler when a global lock
+ *              release interrupt occurs. If there is actually a pending
+ *              request for the lock, signal the waiting thread.
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiEvGlobalLockHandler (
+    void                    *Context)
+{
+    ACPI_STATUS             Status;
+    ACPI_CPU_FLAGS          Flags;
+
+
+    Flags = AcpiOsAcquireLock (AcpiGbl_GlobalLockPendingLock);
+
+    /*
+     * If a request for the global lock is not actually pending,
+     * we are done. This handles "spurious" global lock interrupts
+     * which are possible (and have been seen) with bad BIOSs.
+     */
+    if (!AcpiGbl_GlobalLockPending)
+    {
+        goto CleanupAndExit;
+    }
+
+    /*
+     * Send a unit to the global lock semaphore. The actual acquisition
+     * of the global lock will be performed by the waiting thread.
+     */
+    Status = AcpiOsSignalSemaphore (AcpiGbl_GlobalLockSemaphore, 1);
+    if (ACPI_FAILURE (Status))
+    {
+        ACPI_ERROR ((AE_INFO, "Could not signal Global Lock semaphore"));
+    }
+
+    AcpiGbl_GlobalLockPending = FALSE;
+
+
+CleanupAndExit:
+
+    AcpiOsReleaseLock (AcpiGbl_GlobalLockPendingLock, Flags);
+    return (ACPI_INTERRUPT_HANDLED);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    AcpiEvAcquireGlobalLock
+ *
+ * PARAMETERS:  Timeout         - Max time to wait for the lock, in millisec.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Attempt to gain ownership of the Global Lock.
+ *
+ * MUTEX:       Interpreter must be locked
+ *
+ * Note: The original implementation allowed multiple threads to "acquire" the
+ * Global Lock, and the OS would hold the lock until the last thread had
+ * released it. However, this could potentially starve the BIOS out of the
+ * lock, especially in the case where there is a tight handshake between the
+ * Embedded Controller driver and the BIOS. Therefore, this implementation
+ * allows only one thread to acquire the HW Global Lock at a time, and makes
+ * the global lock appear as a standard mutex on the OS side.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiEvAcquireGlobalLock (
+    UINT16                  Timeout)
+{
+    ACPI_CPU_FLAGS          Flags;
+    ACPI_STATUS             Status;
+    BOOLEAN                 Acquired = FALSE;
+
+
+    ACPI_FUNCTION_TRACE (EvAcquireGlobalLock);
+
+
+    /*
+     * Only one thread can acquire the GL at a time, the GlobalLockMutex
+     * enforces this. This interface releases the interpreter if we must wait.
+     */
+    Status = AcpiExSystemWaitMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex,
+                Timeout);
+    if (ACPI_FAILURE (Status))
+    {
+        return_ACPI_STATUS (Status);
+    }
+
+    /*
+     * Update the global lock handle and check for wraparound. The handle is
+     * only used for the external global lock interfaces, but it is updated
+     * here to properly handle the case where a single thread may acquire the
+     * lock via both the AML and the AcpiAcquireGlobalLock interfaces. The
+     * handle is therefore updated on the first acquire from a given thread
+     * regardless of where the acquisition request originated.
+     */
+    AcpiGbl_GlobalLockHandle++;
+    if (AcpiGbl_GlobalLockHandle == 0)
+    {
+        AcpiGbl_GlobalLockHandle = 1;
+    }
+
+    /*
+     * Make sure that a global lock actually exists. If not, just
+     * treat the lock as a standard mutex.
+     */
+    if (!AcpiGbl_GlobalLockPresent)
+    {
+        AcpiGbl_GlobalLockAcquired = TRUE;
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    Flags = AcpiOsAcquireLock (AcpiGbl_GlobalLockPendingLock);
+
+    do
+    {
+        /* Attempt to acquire the actual hardware lock */
+
+        ACPI_ACQUIRE_GLOBAL_LOCK (AcpiGbl_FACS, Acquired);
+        if (Acquired)
+        {
+            AcpiGbl_GlobalLockAcquired = TRUE;
+            ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+                "Acquired hardware Global Lock\n"));
+            break;
+        }
+
+        /*
+         * Did not get the lock. The pending bit was set above, and
+         * we must now wait until we receive the global lock
+         * released interrupt.
+         */
+        AcpiGbl_GlobalLockPending = TRUE;
+        AcpiOsReleaseLock (AcpiGbl_GlobalLockPendingLock, Flags);
+
+        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+            "Waiting for hardware Global Lock\n"));
+
+        /*
+         * Wait for handshake with the global lock interrupt handler.
+         * This interface releases the interpreter if we must wait.
+         */
+        Status = AcpiExSystemWaitSemaphore (AcpiGbl_GlobalLockSemaphore,
+                    ACPI_WAIT_FOREVER);
+
+        Flags = AcpiOsAcquireLock (AcpiGbl_GlobalLockPendingLock);
+
+    } while (ACPI_SUCCESS (Status));
+
+    AcpiGbl_GlobalLockPending = FALSE;
+    AcpiOsReleaseLock (AcpiGbl_GlobalLockPendingLock, Flags);
+
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiEvReleaseGlobalLock
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Releases ownership of the Global Lock.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvReleaseGlobalLock (
+    void)
+{
+    BOOLEAN                 Pending = FALSE;
+    ACPI_STATUS             Status = AE_OK;
+
+
+    ACPI_FUNCTION_TRACE (EvReleaseGlobalLock);
+
+
+    /* Lock must be already acquired */
+
+    if (!AcpiGbl_GlobalLockAcquired)
+    {
+        ACPI_WARNING ((AE_INFO,
+            "Cannot release the ACPI Global Lock, it has not been acquired"));
+        return_ACPI_STATUS (AE_NOT_ACQUIRED);
+    }
+
+    if (AcpiGbl_GlobalLockPresent)
+    {
+        /* Allow any thread to release the lock */
+
+        ACPI_RELEASE_GLOBAL_LOCK (AcpiGbl_FACS, Pending);
+
+        /*
+         * If the pending bit was set, we must write GBL_RLS to the control
+         * register
+         */
+        if (Pending)
+        {
+            Status = AcpiWriteBitRegister (
+                        ACPI_BITREG_GLOBAL_LOCK_RELEASE, ACPI_ENABLE_EVENT);
+        }
+
+        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Released hardware Global Lock\n"));
+    }
+
+    AcpiGbl_GlobalLockAcquired = FALSE;
+
+    /* Release the local GL mutex */
+
+    AcpiOsReleaseMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex);
+    return_ACPI_STATUS (Status);
+}
index 00d72e5..59e5d55 100644 (file)
@@ -8,7 +8,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
@@ -134,272 +134,238 @@ AcpiEvAsynchEnableGpe (
 
 /*******************************************************************************
  *
- * FUNCTION:    AcpiEvSetGpeType
+ * FUNCTION:    AcpiEvUpdateGpeEnableMask
  *
- * PARAMETERS:  GpeEventInfo            - GPE to set
- *              Type                    - New type
+ * PARAMETERS:  GpeEventInfo            - GPE to update
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Sets the new type for the GPE (wake, run, or wake/run)
+ * DESCRIPTION: Updates GPE register enable mask based upon whether there are
+ *              runtime references to this GPE
  *
  ******************************************************************************/
 
 ACPI_STATUS
-AcpiEvSetGpeType (
-    ACPI_GPE_EVENT_INFO     *GpeEventInfo,
-    UINT8                   Type)
+AcpiEvUpdateGpeEnableMask (
+    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
 {
-    ACPI_STATUS             Status;
-
+    ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
+    UINT32                  RegisterBit;
 
-    ACPI_FUNCTION_TRACE (EvSetGpeType);
 
+    ACPI_FUNCTION_TRACE (EvUpdateGpeEnableMask);
 
-    /* Validate type and update register enable masks */
 
-    switch (Type)
+    GpeRegisterInfo = GpeEventInfo->RegisterInfo;
+    if (!GpeRegisterInfo)
     {
-    case ACPI_GPE_TYPE_WAKE:
-    case ACPI_GPE_TYPE_RUNTIME:
-    case ACPI_GPE_TYPE_WAKE_RUN:
-        break;
-
-    default:
-        return_ACPI_STATUS (AE_BAD_PARAMETER);
+        return_ACPI_STATUS (AE_NOT_EXIST);
     }
 
-    /* Disable the GPE if currently enabled */
+    RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo, GpeRegisterInfo);
 
-    Status = AcpiEvDisableGpe (GpeEventInfo);
+    /* Clear the run bit up front */
 
-    /* Clear the type bits and insert the new Type */
+    ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
 
-    GpeEventInfo->Flags &= ~ACPI_GPE_TYPE_MASK;
-    GpeEventInfo->Flags |= Type;
-    return_ACPI_STATUS (Status);
+    /* Set the mask bit only if there are references to this GPE */
+
+    if (GpeEventInfo->RuntimeCount)
+    {
+        ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, (UINT8) RegisterBit);
+    }
+
+    return_ACPI_STATUS (AE_OK);
 }
 
 
 /*******************************************************************************
  *
- * FUNCTION:    AcpiEvUpdateGpeEnableMasks
+ * FUNCTION:    AcpiEvEnableGpe
  *
- * PARAMETERS:  GpeEventInfo            - GPE to update
- *              Type                    - What to do: ACPI_GPE_DISABLE or
- *                                        ACPI_GPE_ENABLE
+ * PARAMETERS:  GpeEventInfo            - GPE to enable
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Updates GPE register enable masks based on the GPE type
+ * DESCRIPTION: Clear a GPE of stale events and enable it.
  *
  ******************************************************************************/
 
 ACPI_STATUS
-AcpiEvUpdateGpeEnableMasks (
-    ACPI_GPE_EVENT_INFO     *GpeEventInfo,
-    UINT8                   Type)
+AcpiEvEnableGpe (
+    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
 {
-    ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
-    UINT8                   RegisterBit;
+    ACPI_STATUS             Status;
 
 
-    ACPI_FUNCTION_TRACE (EvUpdateGpeEnableMasks);
+    ACPI_FUNCTION_TRACE (EvEnableGpe);
 
 
-    GpeRegisterInfo = GpeEventInfo->RegisterInfo;
-    if (!GpeRegisterInfo)
+    /*
+     * We will only allow a GPE to be enabled if it has either an associated
+     * method (_Lxx/_Exx) or a handler, or is using the implicit notify
+     * feature. Otherwise, the GPE will be immediately disabled by
+     * AcpiEvGpeDispatch the first time it fires.
+     */
+    if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
+        ACPI_GPE_DISPATCH_NONE)
     {
-        return_ACPI_STATUS (AE_NOT_EXIST);
+        return_ACPI_STATUS (AE_NO_HANDLER);
     }
 
-    RegisterBit = (UINT8)
-        (1 << (GpeEventInfo->GpeNumber - GpeRegisterInfo->BaseGpeNumber));
-
-    /* 1) Disable case. Simply clear all enable bits */
+    /* Clear the GPE (of stale events) */
 
-    if (Type == ACPI_GPE_DISABLE)
+    Status = AcpiHwClearGpe (GpeEventInfo);
+    if (ACPI_FAILURE (Status))
     {
-        ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
-        ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
-        return_ACPI_STATUS (AE_OK);
+        return_ACPI_STATUS (Status);
     }
 
-    /* 2) Enable case. Set/Clear the appropriate enable bits */
-
-    switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
-    {
-    case ACPI_GPE_TYPE_WAKE:
-        ACPI_SET_BIT   (GpeRegisterInfo->EnableForWake, RegisterBit);
-        ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
-        break;
-
-    case ACPI_GPE_TYPE_RUNTIME:
-        ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
-        ACPI_SET_BIT   (GpeRegisterInfo->EnableForRun, RegisterBit);
-        break;
-
-    case ACPI_GPE_TYPE_WAKE_RUN:
-        ACPI_SET_BIT   (GpeRegisterInfo->EnableForWake, RegisterBit);
-        ACPI_SET_BIT   (GpeRegisterInfo->EnableForRun, RegisterBit);
-        break;
+    /* Enable the requested GPE */
 
-    default:
-        return_ACPI_STATUS (AE_BAD_PARAMETER);
-    }
-
-    return_ACPI_STATUS (AE_OK);
+    Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
+    return_ACPI_STATUS (Status);
 }
 
 
 /*******************************************************************************
  *
- * FUNCTION:    AcpiEvEnableGpe
+ * FUNCTION:    AcpiEvAddGpeReference
  *
- * PARAMETERS:  GpeEventInfo            - GPE to enable
- *              WriteToHardware         - Enable now, or just mark data structs
- *                                        (WAKE GPEs should be deferred)
+ * PARAMETERS:  GpeEventInfo            - Add a reference to this GPE
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Enable a GPE based on the GPE type
+ * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
+ *              hardware-enabled.
  *
  ******************************************************************************/
 
 ACPI_STATUS
-AcpiEvEnableGpe (
-    ACPI_GPE_EVENT_INFO     *GpeEventInfo,
-    BOOLEAN                 WriteToHardware)
+AcpiEvAddGpeReference (
+    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
 {
-    ACPI_STATUS             Status;
-
+    ACPI_STATUS             Status = AE_OK;
 
-    ACPI_FUNCTION_TRACE (EvEnableGpe);
 
+    ACPI_FUNCTION_TRACE (EvAddGpeReference);
 
-    /* Make sure HW enable masks are updated */
 
-    Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_ENABLE);
-    if (ACPI_FAILURE (Status))
+    if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
     {
-        return_ACPI_STATUS (Status);
+        return_ACPI_STATUS (AE_LIMIT);
     }
 
-    /* Mark wake-enabled or HW enable, or both */
-
-    switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
+    GpeEventInfo->RuntimeCount++;
+    if (GpeEventInfo->RuntimeCount == 1)
     {
-    case ACPI_GPE_TYPE_WAKE:
-
-        ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
-        break;
-
-    case ACPI_GPE_TYPE_WAKE_RUN:
-
-        ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
-
-        /*lint -fallthrough */
-
-    case ACPI_GPE_TYPE_RUNTIME:
-
-        ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_RUN_ENABLED);
+        /* Enable on first reference */
 
-        if (WriteToHardware)
+        Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
+        if (ACPI_SUCCESS (Status))
         {
-            /* Clear the GPE (of stale events), then enable it */
-
-            Status = AcpiHwClearGpe (GpeEventInfo);
-            if (ACPI_FAILURE (Status))
-            {
-                return_ACPI_STATUS (Status);
-            }
-
-            /* Enable the requested runtime GPE */
-
-            Status = AcpiHwWriteGpeEnableReg (GpeEventInfo);
+            Status = AcpiEvEnableGpe (GpeEventInfo);
         }
-        break;
 
-    default:
-        return_ACPI_STATUS (AE_BAD_PARAMETER);
+        if (ACPI_FAILURE (Status))
+        {
+            GpeEventInfo->RuntimeCount--;
+        }
     }
 
-    return_ACPI_STATUS (AE_OK);
+    return_ACPI_STATUS (Status);
 }
 
 
 /*******************************************************************************
  *
- * FUNCTION:    AcpiEvDisableGpe
+ * FUNCTION:    AcpiEvRemoveGpeReference
  *
- * PARAMETERS:  GpeEventInfo            - GPE to disable
+ * PARAMETERS:  GpeEventInfo            - Remove a reference to this GPE
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Disable a GPE based on the GPE type
+ * DESCRIPTION: Remove a reference to a GPE. When the last reference is
+ *              removed, the GPE is hardware-disabled.
  *
  ******************************************************************************/
 
 ACPI_STATUS
-AcpiEvDisableGpe (
+AcpiEvRemoveGpeReference (
     ACPI_GPE_EVENT_INFO     *GpeEventInfo)
 {
-    ACPI_STATUS             Status;
-
+    ACPI_STATUS             Status = AE_OK;
 
-    ACPI_FUNCTION_TRACE (EvDisableGpe);
 
+    ACPI_FUNCTION_TRACE (EvRemoveGpeReference);
 
-    /*
-     * Note: Always disable the GPE, even if we think that that it is already
-     * disabled. It is possible that the AML or some other code has enabled
-     * the GPE behind our back.
-     */
 
-    /* Make sure HW enable masks are updated */
-
-    Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_DISABLE);
-    if (ACPI_FAILURE (Status))
+    if (!GpeEventInfo->RuntimeCount)
     {
-        return_ACPI_STATUS (Status);
+        return_ACPI_STATUS (AE_LIMIT);
     }
 
-    /* Clear the appropriate enabled flags for this GPE */
-
-    switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
+    GpeEventInfo->RuntimeCount--;
+    if (!GpeEventInfo->RuntimeCount)
     {
-    case ACPI_GPE_TYPE_WAKE:
-
-        ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
-        break;
+        /* Disable on last reference */
 
-    case ACPI_GPE_TYPE_WAKE_RUN:
+        Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
+        if (ACPI_SUCCESS (Status))
+        {
+            Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
+        }
 
-        ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
+        if (ACPI_FAILURE (Status))
+        {
+            GpeEventInfo->RuntimeCount++;
+        }
+    }
 
-        /*lint -fallthrough */
+    return_ACPI_STATUS (Status);
+}
 
-    case ACPI_GPE_TYPE_RUNTIME:
 
-        /* Disable the requested runtime GPE */
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiEvLowGetGpeInfo
+ *
+ * PARAMETERS:  GpeNumber           - Raw GPE number
+ *              GpeBlock            - A GPE info block
+ *
+ * RETURN:      A GPE EventInfo struct. NULL if not a valid GPE (The GpeNumber
+ *              is not within the specified GPE block)
+ *
+ * DESCRIPTION: Returns the EventInfo struct associated with this GPE. This is
+ *              the low-level implementation of EvGetGpeEventInfo.
+ *
+ ******************************************************************************/
 
-        ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_RUN_ENABLED);
-        break;
+ACPI_GPE_EVENT_INFO *
+AcpiEvLowGetGpeInfo (
+    UINT32                  GpeNumber,
+    ACPI_GPE_BLOCK_INFO     *GpeBlock)
+{
+    UINT32                  GpeIndex;
 
-    default:
-        break;
-    }
 
     /*
-     * Always H/W disable this GPE, even if we don't know the GPE type.
-     * Simply clear the enable bit for this particular GPE, but do not
-     * write out the current GPE enable mask since this may inadvertently
-     * enable GPEs too early. An example is a rogue GPE that has arrived
-     * during ACPICA initialization - possibly because AML or other code
-     * has enabled the GPE.
+     * Validate that the GpeNumber is within the specified GpeBlock.
+     * (Two steps)
      */
-    Status = AcpiHwLowDisableGpe (GpeEventInfo);
-    return_ACPI_STATUS (Status);
+    if (!GpeBlock ||
+        (GpeNumber < GpeBlock->BlockBaseNumber))
+    {
+        return (NULL);
+    }
+
+    GpeIndex = GpeNumber - GpeBlock->BlockBaseNumber;
+    if (GpeIndex >= GpeBlock->GpeCount)
+    {
+        return (NULL);
+    }
+
+    return (&GpeBlock->EventInfo[GpeIndex]);
 }
 
 
@@ -426,14 +392,14 @@ AcpiEvGetGpeEventInfo (
     UINT32                  GpeNumber)
 {
     ACPI_OPERAND_OBJECT     *ObjDesc;
-    ACPI_GPE_BLOCK_INFO     *GpeBlock;
+    ACPI_GPE_EVENT_INFO     *GpeInfo;
     UINT32                  i;
 
 
     ACPI_FUNCTION_ENTRY ();
 
 
-    /* A NULL GpeBlock means use the FADT-defined GPE block(s) */
+    /* A NULL GpeDevice means use the FADT-defined GPE block(s) */
 
     if (!GpeDevice)
     {
@@ -441,16 +407,11 @@ AcpiEvGetGpeEventInfo (
 
         for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++)
         {
-            GpeBlock = AcpiGbl_GpeFadtBlocks[i];
-            if (GpeBlock)
+            GpeInfo = AcpiEvLowGetGpeInfo (GpeNumber,
+                        AcpiGbl_GpeFadtBlocks[i]);
+            if (GpeInfo)
             {
-                if ((GpeNumber >= GpeBlock->BlockBaseNumber) &&
-                    (GpeNumber < GpeBlock->BlockBaseNumber +
-                        (GpeBlock->RegisterCount * 8)))
-                {
-                    return (&GpeBlock->EventInfo[GpeNumber -
-                        GpeBlock->BlockBaseNumber]);
-                }
+                return (GpeInfo);
             }
         }
 
@@ -468,15 +429,7 @@ AcpiEvGetGpeEventInfo (
         return (NULL);
     }
 
-    GpeBlock = ObjDesc->Device.GpeBlock;
-
-    if ((GpeNumber >= GpeBlock->BlockBaseNumber) &&
-        (GpeNumber < GpeBlock->BlockBaseNumber + (GpeBlock->RegisterCount * 8)))
-    {
-        return (&GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber]);
-    }
-
-    return (NULL);
+    return (AcpiEvLowGetGpeInfo (GpeNumber, ObjDesc->Device.GpeBlock));
 }
 
 
@@ -505,7 +458,7 @@ AcpiEvGpeDetect (
     UINT8                   EnabledStatusByte;
     UINT32                  StatusReg;
     UINT32                  EnableReg;
-    //ACPI_CPU_FLAGS          Flags;
+    ACPI_CPU_FLAGS          Flags;
     UINT32                  i;
     UINT32                  j;
 
@@ -524,7 +477,7 @@ AcpiEvGpeDetect (
      * Note: Not necessary to obtain the hardware lock, since the GPE
      * registers are owned by the GpeLock.
      */
-    //Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
 
     /* Examine all GPE blocks attached to this interrupt level */
 
@@ -541,6 +494,16 @@ AcpiEvGpeDetect (
 
             GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
 
+            /*
+             * Optimization: If there are no GPEs enabled within this
+             * register, we can safely ignore the entire register.
+             */
+            if (!(GpeRegisterInfo->EnableForRun |
+                  GpeRegisterInfo->EnableForWake))
+            {
+                continue;
+            }
+
             /* Read the Status Register */
 
             Status = AcpiHwRead (&StatusReg, &GpeRegisterInfo->StatusAddress);
@@ -558,7 +521,7 @@ AcpiEvGpeDetect (
             }
 
             ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
-                "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n",
+                "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n",
                 GpeRegisterInfo->BaseGpeNumber, StatusReg, EnableReg));
 
             /* Check if there is anything active at all in this register */
@@ -583,7 +546,7 @@ AcpiEvGpeDetect (
                      * Found an active GPE. Dispatch the event to a handler
                      * or method.
                      */
-                    IntStatus |= AcpiEvGpeDispatch (
+                    IntStatus |= AcpiEvGpeDispatch (GpeBlock->Node,
                         &GpeBlock->EventInfo[((ACPI_SIZE) i *
                             ACPI_GPE_REGISTER_WIDTH) + j],
                         j + GpeRegisterInfo->BaseGpeNumber);
@@ -596,7 +559,7 @@ AcpiEvGpeDetect (
 
 UnlockAndExit:
 
-    //AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
     return (IntStatus);
 }
 
@@ -654,10 +617,6 @@ AcpiEvAsynchExecuteGpeMethod (
         return_VOID;
     }
 
-    /* Set the GPE flags for return to enabled state */
-
-    (void) AcpiEvEnableGpe (GpeEventInfo, FALSE);
-
     /*
      * Take a snapshot of the GPE info for this level - we copy the info to
      * prevent a race condition with RemoveHandler/RemoveBlock.
@@ -671,13 +630,27 @@ AcpiEvAsynchExecuteGpeMethod (
         return_VOID;
     }
 
-    /*
-     * Must check for control method type dispatch one more time to avoid a
-     * race with EvGpeInstallHandler
-     */
-    if ((LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
-            ACPI_GPE_DISPATCH_METHOD)
+    /* Do the correct dispatch - normal method or implicit notify */
+
+    switch (LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
     {
+    case ACPI_GPE_DISPATCH_NOTIFY:
+
+        /*
+         * Implicit notify.
+         * Dispatch a DEVICE_WAKE notify to the appropriate handler.
+         * NOTE: the request is queued for execution after this method
+         * completes. The notify handlers are NOT invoked synchronously
+         * from this thread -- because handlers may in turn run other
+         * control methods.
+         */
+        Status = AcpiEvQueueNotifyRequest (
+                    LocalGpeEventInfo->Dispatch.DeviceNode,
+                    ACPI_NOTIFY_DEVICE_WAKE);
+        break;
+
+    case ACPI_GPE_DISPATCH_METHOD:
+
         /* Allocate the evaluation information block */
 
         Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
@@ -688,8 +661,8 @@ AcpiEvAsynchExecuteGpeMethod (
         else
         {
             /*
-             * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
-             * control method that corresponds to this GPE
+             * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the
+             * _Lxx/_Exx control method that corresponds to this GPE
              */
             Info->PrefixNode = LocalGpeEventInfo->Dispatch.MethodNode;
             Info->Flags = ACPI_IGNORE_RETURN_VALUE;
@@ -704,6 +677,11 @@ AcpiEvAsynchExecuteGpeMethod (
                 "while evaluating GPE method [%4.4s]",
                 AcpiUtGetNodeName (LocalGpeEventInfo->Dispatch.MethodNode)));
         }
+
+        break;
+
+    default:
+        return_VOID; /* Should never happen */
     }
 
     /* Defer enabling of GPE until all notify handlers are done */
@@ -723,6 +701,7 @@ AcpiEvAsynchExecuteGpeMethod (
  * FUNCTION:    AcpiEvAsynchEnableGpe
  *
  * PARAMETERS:  Context (GpeEventInfo) - Info for this GPE
+ *              Callback from AcpiOsExecute
  *
  * RETURN:      None
  *
@@ -736,6 +715,32 @@ AcpiEvAsynchEnableGpe (
     void                    *Context)
 {
     ACPI_GPE_EVENT_INFO     *GpeEventInfo = Context;
+
+
+    (void) AcpiEvFinishGpe (GpeEventInfo);
+
+    ACPI_FREE (GpeEventInfo);
+    return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiEvFinishGpe
+ *
+ * PARAMETERS:  GpeEventInfo        - Info for this GPE
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution
+ *              of a GPE method or a synchronous or asynchronous GPE handler.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvFinishGpe (
+    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
+{
     ACPI_STATUS             Status;
 
 
@@ -743,23 +748,23 @@ AcpiEvAsynchEnableGpe (
             ACPI_GPE_LEVEL_TRIGGERED)
     {
         /*
-         * GPE is level-triggered, we clear the GPE status bit after handling
-         * the event.
+         * GPE is level-triggered, we clear the GPE status bit after
+         * handling the event.
          */
         Status = AcpiHwClearGpe (GpeEventInfo);
         if (ACPI_FAILURE (Status))
         {
-            goto Exit;
+            return (Status);
         }
     }
 
-    /* Enable this GPE */
-
-    (void) AcpiHwWriteGpeEnableReg (GpeEventInfo);
-
-Exit:
-    ACPI_FREE (GpeEventInfo);
-    return;
+    /*
+     * Enable this GPE, conditionally. This means that the GPE will
+     * only be physically enabled if the EnableForRun bit is set
+     * in the EventInfo.
+     */
+    (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE);
+    return (AE_OK);
 }
 
 
@@ -767,8 +772,9 @@ Exit:
  *
  * FUNCTION:    AcpiEvGpeDispatch
  *
- * PARAMETERS:  GpeEventInfo    - Info for this GPE
- *              GpeNumber       - Number relative to the parent GPE block
+ * PARAMETERS:  GpeDevice           - Device node. NULL for GPE0/GPE1
+ *              GpeEventInfo        - Info for this GPE
+ *              GpeNumber           - Number relative to the parent GPE block
  *
  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
  *
@@ -781,16 +787,25 @@ Exit:
 
 UINT32
 AcpiEvGpeDispatch (
+    ACPI_NAMESPACE_NODE     *GpeDevice,
     ACPI_GPE_EVENT_INFO     *GpeEventInfo,
     UINT32                  GpeNumber)
 {
     ACPI_STATUS             Status;
+    UINT32                  ReturnValue;
 
 
     ACPI_FUNCTION_TRACE (EvGpeDispatch);
 
 
+    /* Invoke global event handler if present */
+
     AcpiGpeCount++;
+    if (AcpiGbl_GlobalEventHandler)
+    {
+        AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_GPE, GpeDevice,
+             GpeNumber, AcpiGbl_GlobalEventHandlerContext);
+    }
 
     /*
      * If edge-triggered, clear the GPE status bit now. Note that
@@ -803,58 +818,55 @@ AcpiEvGpeDispatch (
         if (ACPI_FAILURE (Status))
         {
             ACPI_EXCEPTION ((AE_INFO, Status,
-                "Unable to clear GPE[%2X]", GpeNumber));
+                "Unable to clear GPE%02X", GpeNumber));
             return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
         }
     }
 
     /*
-     * Dispatch the GPE to either an installed handler, or the control method
-     * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke
-     * it and do not attempt to run the method. If there is neither a handler
-     * nor a method, we disable this GPE to prevent further such pointless
-     * events from firing.
+     * Always disable the GPE so that it does not keep firing before
+     * any asynchronous activity completes (either from the execution
+     * of a GPE method or an asynchronous GPE handler.)
+     *
+     * If there is no handler or method to run, just disable the
+     * GPE and leave it disabled permanently to prevent further such
+     * pointless events from firing.
+     */
+    Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
+    if (ACPI_FAILURE (Status))
+    {
+        ACPI_EXCEPTION ((AE_INFO, Status,
+            "Unable to disable GPE%02X", GpeNumber));
+        return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
+    }
+
+    /*
+     * Dispatch the GPE to either an installed handler or the control
+     * method associated with this GPE (_Lxx or _Exx). If a handler
+     * exists, we invoke it and do not attempt to run the method.
+     * If there is neither a handler nor a method, leave the GPE
+     * disabled.
      */
     switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
     {
     case ACPI_GPE_DISPATCH_HANDLER:
 
-        /*
-         * Invoke the installed handler (at interrupt level)
-         * Ignore return status for now.
-         * TBD: leave GPE disabled on error?
-         */
-        (void) GpeEventInfo->Dispatch.Handler->Address (
-                        GpeEventInfo->Dispatch.Handler->Context);
+        /* Invoke the installed handler (at interrupt level) */
+
+        ReturnValue = GpeEventInfo->Dispatch.Handler->Address (
+            GpeDevice, GpeNumber,
+            GpeEventInfo->Dispatch.Handler->Context);
 
-        /* It is now safe to clear level-triggered events. */
+        /* If requested, clear (if level-triggered) and reenable the GPE */
 
-        if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
-                ACPI_GPE_LEVEL_TRIGGERED)
+        if (ReturnValue & ACPI_REENABLE_GPE)
         {
-            Status = AcpiHwClearGpe (GpeEventInfo);
-            if (ACPI_FAILURE (Status))
-            {
-                ACPI_EXCEPTION ((AE_INFO, Status,
-                    "Unable to clear GPE[%2X]", GpeNumber));
-                return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
-            }
+            (void) AcpiEvFinishGpe (GpeEventInfo);
         }
         break;
 
     case ACPI_GPE_DISPATCH_METHOD:
-
-        /*
-         * Disable the GPE, so it doesn't keep firing before the method has a
-         * chance to run (it runs asynchronously with interrupts enabled).
-         */
-        Status = AcpiEvDisableGpe (GpeEventInfo);
-        if (ACPI_FAILURE (Status))
-        {
-            ACPI_EXCEPTION ((AE_INFO, Status,
-                "Unable to disable GPE[%2X]", GpeNumber));
-            return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
-        }
+    case ACPI_GPE_DISPATCH_NOTIFY:
 
         /*
          * Execute the method associated with the GPE
@@ -865,30 +877,21 @@ AcpiEvGpeDispatch (
         if (ACPI_FAILURE (Status))
         {
             ACPI_EXCEPTION ((AE_INFO, Status,
-                "Unable to queue handler for GPE[%2X] - event disabled",
+                "Unable to queue handler for GPE%02X - event disabled",
                 GpeNumber));
         }
         break;
 
     default:
 
-        /* No handler or method to run! */
-
-        ACPI_ERROR ((AE_INFO,
-            "No handler or method for GPE[%2X], disabling event",
-            GpeNumber));
-
         /*
-         * Disable the GPE. The GPE will remain disabled until the ACPICA
-         * Core Subsystem is restarted, or a handler is installed.
+         * No handler or method to run!
+         * 03/2010: This case should no longer be possible. We will not allow
+         * a GPE to be enabled if it has no handler or method.
          */
-        Status = AcpiEvDisableGpe (GpeEventInfo);
-        if (ACPI_FAILURE (Status))
-        {
-            ACPI_EXCEPTION ((AE_INFO, Status,
-                "Unable to disable GPE[%2X]", GpeNumber));
-            return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
-        }
+        ACPI_ERROR ((AE_INFO,
+            "No handler or method for GPE%02X, disabling event",
+            GpeNumber));
         break;
     }
 
index c86f80a..c3ea571 100644 (file)
@@ -8,7 +8,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
 
 /* Local prototypes */
 
-static ACPI_STATUS
-AcpiEvSaveMethodInfo (
-    ACPI_HANDLE             ObjHandle,
-    UINT32                  Level,
-    void                    *ObjDesc,
-    void                    **ReturnValue);
-
-static ACPI_STATUS
-AcpiEvMatchPrwAndGpe (
-    ACPI_HANDLE             ObjHandle,
-    UINT32                  Level,
-    void                    *Info,
-    void                    **ReturnValue);
-
-static ACPI_GPE_XRUPT_INFO *
-AcpiEvGetGpeXruptBlock (
-    UINT32                  InterruptNumber);
-
-static ACPI_STATUS
-AcpiEvDeleteGpeXrupt (
-    ACPI_GPE_XRUPT_INFO     *GpeXrupt);
-
 static ACPI_STATUS
 AcpiEvInstallGpeBlock (
     ACPI_GPE_BLOCK_INFO     *GpeBlock,
@@ -155,597 +133,6 @@ AcpiEvCreateGpeInfoBlocks (
     ACPI_GPE_BLOCK_INFO     *GpeBlock);
 
 
-/*******************************************************************************
- *
- * FUNCTION:    AcpiEvValidGpeEvent
- *
- * PARAMETERS:  GpeEventInfo                - Info for this GPE
- *
- * RETURN:      TRUE if the GpeEvent is valid
- *
- * DESCRIPTION: Validate a GPE event. DO NOT CALL FROM INTERRUPT LEVEL.
- *              Should be called only when the GPE lists are semaphore locked
- *              and not subject to change.
- *
- ******************************************************************************/
-
-BOOLEAN
-AcpiEvValidGpeEvent (
-    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
-{
-    ACPI_GPE_XRUPT_INFO     *GpeXruptBlock;
-    ACPI_GPE_BLOCK_INFO     *GpeBlock;
-
-
-    ACPI_FUNCTION_ENTRY ();
-
-
-    /* No need for spin lock since we are not changing any list elements */
-
-    /* Walk the GPE interrupt levels */
-
-    GpeXruptBlock = AcpiGbl_GpeXruptListHead;
-    while (GpeXruptBlock)
-    {
-        GpeBlock = GpeXruptBlock->GpeBlockListHead;
-
-        /* Walk the GPE blocks on this interrupt level */
-
-        while (GpeBlock)
-        {
-            if ((&GpeBlock->EventInfo[0] <= GpeEventInfo) &&
-                (&GpeBlock->EventInfo[((ACPI_SIZE)
-                    GpeBlock->RegisterCount) * 8] > GpeEventInfo))
-            {
-                return (TRUE);
-            }
-
-            GpeBlock = GpeBlock->Next;
-        }
-
-        GpeXruptBlock = GpeXruptBlock->Next;
-    }
-
-    return (FALSE);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiEvWalkGpeList
- *
- * PARAMETERS:  GpeWalkCallback     - Routine called for each GPE block
- *              Context             - Value passed to callback
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Walk the GPE lists.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiEvWalkGpeList (
-    ACPI_GPE_CALLBACK       GpeWalkCallback,
-    void                    *Context)
-{
-    ACPI_GPE_BLOCK_INFO     *GpeBlock;
-    ACPI_GPE_XRUPT_INFO     *GpeXruptInfo;
-    ACPI_STATUS             Status = AE_OK;
-    ACPI_CPU_FLAGS          Flags;
-
-
-    ACPI_FUNCTION_TRACE (EvWalkGpeList);
-
-
-    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
-
-    /* Walk the interrupt level descriptor list */
-
-    GpeXruptInfo = AcpiGbl_GpeXruptListHead;
-    while (GpeXruptInfo)
-    {
-        /* Walk all Gpe Blocks attached to this interrupt level */
-
-        GpeBlock = GpeXruptInfo->GpeBlockListHead;
-        while (GpeBlock)
-        {
-            /* One callback per GPE block */
-
-            Status = GpeWalkCallback (GpeXruptInfo, GpeBlock, Context);
-            if (ACPI_FAILURE (Status))
-            {
-                if (Status == AE_CTRL_END) /* Callback abort */
-                {
-                    Status = AE_OK;
-                }
-                goto UnlockAndExit;
-            }
-
-            GpeBlock = GpeBlock->Next;
-        }
-
-        GpeXruptInfo = GpeXruptInfo->Next;
-    }
-
-UnlockAndExit:
-    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiEvDeleteGpeHandlers
- *
- * PARAMETERS:  GpeXruptInfo        - GPE Interrupt info
- *              GpeBlock            - Gpe Block info
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Delete all Handler objects found in the GPE data structs.
- *              Used only prior to termination.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiEvDeleteGpeHandlers (
-    ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
-    ACPI_GPE_BLOCK_INFO     *GpeBlock,
-    void                    *Context)
-{
-    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
-    UINT32                  i;
-    UINT32                  j;
-
-
-    ACPI_FUNCTION_TRACE (EvDeleteGpeHandlers);
-
-
-    /* Examine each GPE Register within the block */
-
-    for (i = 0; i < GpeBlock->RegisterCount; i++)
-    {
-        /* Now look at the individual GPEs in this byte register */
-
-        for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
-        {
-            GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
-                ACPI_GPE_REGISTER_WIDTH) + j];
-
-            if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
-                    ACPI_GPE_DISPATCH_HANDLER)
-            {
-                ACPI_FREE (GpeEventInfo->Dispatch.Handler);
-                GpeEventInfo->Dispatch.Handler = NULL;
-                GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;
-            }
-        }
-    }
-
-    return_ACPI_STATUS (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiEvSaveMethodInfo
- *
- * PARAMETERS:  Callback from WalkNamespace
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Called from AcpiWalkNamespace. Expects each object to be a
- *              control method under the _GPE portion of the namespace.
- *              Extract the name and GPE type from the object, saving this
- *              information for quick lookup during GPE dispatch
- *
- *              The name of each GPE control method is of the form:
- *              "_Lxx" or "_Exx"
- *              Where:
- *                  L      - means that the GPE is level triggered
- *                  E      - means that the GPE is edge triggered
- *                  xx     - is the GPE number [in HEX]
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-AcpiEvSaveMethodInfo (
-    ACPI_HANDLE             ObjHandle,
-    UINT32                  Level,
-    void                    *ObjDesc,
-    void                    **ReturnValue)
-{
-    ACPI_GPE_BLOCK_INFO     *GpeBlock = (void *) ObjDesc;
-    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
-    UINT32                  GpeNumber;
-    char                    Name[ACPI_NAME_SIZE + 1];
-    UINT8                   Type;
-    ACPI_STATUS             Status;
-
-
-    ACPI_FUNCTION_TRACE (EvSaveMethodInfo);
-
-
-    /*
-     * _Lxx and _Exx GPE method support
-     *
-     * 1) Extract the name from the object and convert to a string
-     */
-    ACPI_MOVE_32_TO_32 (
-        Name, &((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Integer);
-    Name[ACPI_NAME_SIZE] = 0;
-
-    /*
-     * 2) Edge/Level determination is based on the 2nd character
-     *    of the method name
-     *
-     * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE
-     * if a _PRW object is found that points to this GPE.
-     */
-    switch (Name[1])
-    {
-    case 'L':
-        Type = ACPI_GPE_LEVEL_TRIGGERED;
-        break;
-
-    case 'E':
-        Type = ACPI_GPE_EDGE_TRIGGERED;
-        break;
-
-    default:
-        /* Unknown method type, just ignore it! */
-
-        ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
-            "Ignoring unknown GPE method type: %s "
-            "(name not of form _Lxx or _Exx)",
-            Name));
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    /* Convert the last two characters of the name to the GPE Number */
-
-    GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16);
-    if (GpeNumber == ACPI_UINT32_MAX)
-    {
-        /* Conversion failed; invalid method, just ignore it */
-
-        ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
-            "Could not extract GPE number from name: %s "
-            "(name is not of form _Lxx or _Exx)",
-            Name));
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    /* Ensure that we have a valid GPE number for this GPE block */
-
-    if ((GpeNumber < GpeBlock->BlockBaseNumber) ||
-        (GpeNumber >= (GpeBlock->BlockBaseNumber +
-            (GpeBlock->RegisterCount * 8))))
-    {
-        /*
-         * Not valid for this GPE block, just ignore it. However, it may be
-         * valid for a different GPE block, since GPE0 and GPE1 methods both
-         * appear under \_GPE.
-         */
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    /*
-     * Now we can add this information to the GpeEventInfo block for use
-     * during dispatch of this GPE. Default type is RUNTIME, although this may
-     * change when the _PRW methods are executed later.
-     */
-    GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber];
-
-    GpeEventInfo->Flags = (UINT8)
-        (Type | ACPI_GPE_DISPATCH_METHOD | ACPI_GPE_TYPE_RUNTIME);
-
-    GpeEventInfo->Dispatch.MethodNode = (ACPI_NAMESPACE_NODE *) ObjHandle;
-
-    /* Update enable mask, but don't enable the HW GPE as of yet */
-
-    Status = AcpiEvEnableGpe (GpeEventInfo, FALSE);
-
-    ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
-        "Registered GPE method %s as GPE number 0x%.2X\n",
-        Name, GpeNumber));
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiEvMatchPrwAndGpe
- *
- * PARAMETERS:  Callback from WalkNamespace
- *
- * RETURN:      Status. NOTE: We ignore errors so that the _PRW walk is
- *              not aborted on a single _PRW failure.
- *
- * DESCRIPTION: Called from AcpiWalkNamespace. Expects each object to be a
- *              Device. Run the _PRW method. If present, extract the GPE
- *              number and mark the GPE as a WAKE GPE.
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-AcpiEvMatchPrwAndGpe (
-    ACPI_HANDLE             ObjHandle,
-    UINT32                  Level,
-    void                    *Info,
-    void                    **ReturnValue)
-{
-    ACPI_GPE_WALK_INFO      *GpeInfo = (void *) Info;
-    ACPI_NAMESPACE_NODE     *GpeDevice;
-    ACPI_GPE_BLOCK_INFO     *GpeBlock;
-    ACPI_NAMESPACE_NODE     *TargetGpeDevice;
-    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
-    ACPI_OPERAND_OBJECT     *PkgDesc;
-    ACPI_OPERAND_OBJECT     *ObjDesc;
-    UINT32                  GpeNumber;
-    ACPI_STATUS             Status;
-
-
-    ACPI_FUNCTION_TRACE (EvMatchPrwAndGpe);
-
-
-    /* Check for a _PRW method under this device */
-
-    Status = AcpiUtEvaluateObject (ObjHandle, METHOD_NAME__PRW,
-                ACPI_BTYPE_PACKAGE, &PkgDesc);
-    if (ACPI_FAILURE (Status))
-    {
-        /* Ignore all errors from _PRW, we don't want to abort the subsystem */
-
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    /* The returned _PRW package must have at least two elements */
-
-    if (PkgDesc->Package.Count < 2)
-    {
-        goto Cleanup;
-    }
-
-    /* Extract pointers from the input context */
-
-    GpeDevice = GpeInfo->GpeDevice;
-    GpeBlock = GpeInfo->GpeBlock;
-
-    /*
-     * The _PRW object must return a package, we are only interested in the
-     * first element
-     */
-    ObjDesc = PkgDesc->Package.Elements[0];
-
-    if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER)
-    {
-        /* Use FADT-defined GPE device (from definition of _PRW) */
-
-        TargetGpeDevice = AcpiGbl_FadtGpeDevice;
-
-        /* Integer is the GPE number in the FADT described GPE blocks */
-
-        GpeNumber = (UINT32) ObjDesc->Integer.Value;
-    }
-    else if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE)
-    {
-        /* Package contains a GPE reference and GPE number within a GPE block */
-
-        if ((ObjDesc->Package.Count < 2) ||
-            ((ObjDesc->Package.Elements[0])->Common.Type !=
-                ACPI_TYPE_LOCAL_REFERENCE) ||
-            ((ObjDesc->Package.Elements[1])->Common.Type !=
-                ACPI_TYPE_INTEGER))
-        {
-            goto Cleanup;
-        }
-
-        /* Get GPE block reference and decode */
-
-        TargetGpeDevice = ObjDesc->Package.Elements[0]->Reference.Node;
-        GpeNumber = (UINT32) ObjDesc->Package.Elements[1]->Integer.Value;
-    }
-    else
-    {
-        /* Unknown type, just ignore it */
-
-        goto Cleanup;
-    }
-
-    /*
-     * Is this GPE within this block?
-     *
-     * TRUE if and only if these conditions are true:
-     *     1) The GPE devices match.
-     *     2) The GPE index(number) is within the range of the Gpe Block
-     *          associated with the GPE device.
-     */
-    if ((GpeDevice == TargetGpeDevice) &&
-        (GpeNumber >= GpeBlock->BlockBaseNumber) &&
-        (GpeNumber < GpeBlock->BlockBaseNumber +
-            (GpeBlock->RegisterCount * 8)))
-    {
-        GpeEventInfo = &GpeBlock->EventInfo[GpeNumber -
-            GpeBlock->BlockBaseNumber];
-
-        /* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
-
-        GpeEventInfo->Flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);
-
-        Status = AcpiEvSetGpeType (GpeEventInfo, ACPI_GPE_TYPE_WAKE);
-        if (ACPI_FAILURE (Status))
-        {
-            goto Cleanup;
-        }
-
-        Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_DISABLE);
-    }
-
-Cleanup:
-    AcpiUtRemoveReference (PkgDesc);
-    return_ACPI_STATUS (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiEvGetGpeXruptBlock
- *
- * PARAMETERS:  InterruptNumber      - Interrupt for a GPE block
- *
- * RETURN:      A GPE interrupt block
- *
- * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt
- *              block per unique interrupt level used for GPEs. Should be
- *              called only when the GPE lists are semaphore locked and not
- *              subject to change.
- *
- ******************************************************************************/
-
-static ACPI_GPE_XRUPT_INFO *
-AcpiEvGetGpeXruptBlock (
-    UINT32                  InterruptNumber)
-{
-    ACPI_GPE_XRUPT_INFO     *NextGpeXrupt;
-    ACPI_GPE_XRUPT_INFO     *GpeXrupt;
-    ACPI_STATUS             Status;
-    ACPI_CPU_FLAGS          Flags;
-
-
-    ACPI_FUNCTION_TRACE (EvGetGpeXruptBlock);
-
-
-    /* No need for lock since we are not changing any list elements here */
-
-    NextGpeXrupt = AcpiGbl_GpeXruptListHead;
-    while (NextGpeXrupt)
-    {
-        if (NextGpeXrupt->InterruptNumber == InterruptNumber)
-        {
-            return_PTR (NextGpeXrupt);
-        }
-
-        NextGpeXrupt = NextGpeXrupt->Next;
-    }
-
-    /* Not found, must allocate a new xrupt descriptor */
-
-    GpeXrupt = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_XRUPT_INFO));
-    if (!GpeXrupt)
-    {
-        return_PTR (NULL);
-    }
-
-    GpeXrupt->InterruptNumber = InterruptNumber;
-
-    /* Install new interrupt descriptor with spin lock */
-
-    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
-    if (AcpiGbl_GpeXruptListHead)
-    {
-        NextGpeXrupt = AcpiGbl_GpeXruptListHead;
-        while (NextGpeXrupt->Next)
-        {
-            NextGpeXrupt = NextGpeXrupt->Next;
-        }
-
-        NextGpeXrupt->Next = GpeXrupt;
-        GpeXrupt->Previous = NextGpeXrupt;
-    }
-    else
-    {
-        AcpiGbl_GpeXruptListHead = GpeXrupt;
-    }
-    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
-
-    /* Install new interrupt handler if not SCI_INT */
-
-    if (InterruptNumber != AcpiGbl_FADT.SciInterrupt)
-    {
-        Status = AcpiOsInstallInterruptHandler (InterruptNumber,
-                    AcpiEvGpeXruptHandler, GpeXrupt);
-        if (ACPI_FAILURE (Status))
-        {
-            ACPI_ERROR ((AE_INFO,
-                "Could not install GPE interrupt handler at level 0x%X",
-                InterruptNumber));
-            return_PTR (NULL);
-        }
-    }
-
-    return_PTR (GpeXrupt);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiEvDeleteGpeXrupt
- *
- * PARAMETERS:  GpeXrupt        - A GPE interrupt info block
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Remove and free a GpeXrupt block. Remove an associated
- *              interrupt handler if not the SCI interrupt.
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-AcpiEvDeleteGpeXrupt (
-    ACPI_GPE_XRUPT_INFO     *GpeXrupt)
-{
-    ACPI_STATUS             Status;
-    ACPI_CPU_FLAGS          Flags;
-
-
-    ACPI_FUNCTION_TRACE (EvDeleteGpeXrupt);
-
-
-    /* We never want to remove the SCI interrupt handler */
-
-    if (GpeXrupt->InterruptNumber == AcpiGbl_FADT.SciInterrupt)
-    {
-        GpeXrupt->GpeBlockListHead = NULL;
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    /* Disable this interrupt */
-
-    Status = AcpiOsRemoveInterruptHandler (
-                GpeXrupt->InterruptNumber, AcpiEvGpeXruptHandler);
-    if (ACPI_FAILURE (Status))
-    {
-        return_ACPI_STATUS (Status);
-    }
-
-    /* Unlink the interrupt block with lock */
-
-    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
-    if (GpeXrupt->Previous)
-    {
-        GpeXrupt->Previous->Next = GpeXrupt->Next;
-    }
-    else
-    {
-        /* No previous, update list head */
-
-        AcpiGbl_GpeXruptListHead = GpeXrupt->Next;
-    }
-
-    if (GpeXrupt->Next)
-    {
-        GpeXrupt->Next->Previous = GpeXrupt->Previous;
-    }
-    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
-
-    /* Free the block */
-
-    ACPI_FREE (GpeXrupt);
-    return_ACPI_STATUS (AE_OK);
-}
-
-
 /*******************************************************************************
  *
  * FUNCTION:    AcpiEvInstallGpeBlock
@@ -880,7 +267,7 @@ AcpiEvDeleteGpeBlock (
         AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
     }
 
-    AcpiCurrentGpeCount -= GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH;
+    AcpiCurrentGpeCount -= GpeBlock->GpeCount;
 
     /* Free the GpeBlock */
 
@@ -925,8 +312,8 @@ AcpiEvCreateGpeInfoBlocks (
     /* Allocate the GPE register information block */
 
     GpeRegisterInfo = ACPI_ALLOCATE_ZEROED (
-                            (ACPI_SIZE) GpeBlock->RegisterCount *
-                            sizeof (ACPI_GPE_REGISTER_INFO));
+                        (ACPI_SIZE) GpeBlock->RegisterCount *
+                        sizeof (ACPI_GPE_REGISTER_INFO));
     if (!GpeRegisterInfo)
     {
         ACPI_ERROR ((AE_INFO,
@@ -938,10 +325,8 @@ AcpiEvCreateGpeInfoBlocks (
      * Allocate the GPE EventInfo block. There are eight distinct GPEs
      * per register. Initialization to zeros is sufficient.
      */
-    GpeEventInfo = ACPI_ALLOCATE_ZEROED (
-                        ((ACPI_SIZE) GpeBlock->RegisterCount *
-                        ACPI_GPE_REGISTER_WIDTH) *
-                        sizeof (ACPI_GPE_EVENT_INFO));
+    GpeEventInfo = ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) GpeBlock->GpeCount *
+                    sizeof (ACPI_GPE_EVENT_INFO));
     if (!GpeEventInfo)
     {
         ACPI_ERROR ((AE_INFO,
@@ -1059,6 +444,7 @@ AcpiEvCreateGpeBlock (
 {
     ACPI_STATUS             Status;
     ACPI_GPE_BLOCK_INFO     *GpeBlock;
+    ACPI_GPE_WALK_INFO      WalkInfo;
 
 
     ACPI_FUNCTION_TRACE (EvCreateGpeBlock);
@@ -1080,6 +466,8 @@ AcpiEvCreateGpeBlock (
     /* Initialize the new GPE block */
 
     GpeBlock->Node = GpeDevice;
+    GpeBlock->GpeCount = (UINT16) (RegisterCount * ACPI_GPE_REGISTER_WIDTH);
+    GpeBlock->Initialized = FALSE;
     GpeBlock->RegisterCount = RegisterCount;
     GpeBlock->BlockBaseNumber = GpeBlockBaseNumber;
 
@@ -1106,11 +494,17 @@ AcpiEvCreateGpeBlock (
         return_ACPI_STATUS (Status);
     }
 
-    /* Find all GPE methods (_Lxx, _Exx) for this block */
+    AcpiGbl_AllGpesInitialized = FALSE;
+
+    /* Find all GPE methods (_Lxx or_Exx) for this block */
+
+    WalkInfo.GpeBlock = GpeBlock;
+    WalkInfo.GpeDevice = GpeDevice;
+    WalkInfo.ExecuteByOwnerId = FALSE;
 
     Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,
                 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
-                AcpiEvSaveMethodInfo, NULL, GpeBlock, NULL);
+                AcpiEvMatchGpeMethod, NULL, &WalkInfo, NULL);
 
     /* Return the new block */
 
@@ -1122,15 +516,13 @@ AcpiEvCreateGpeBlock (
     ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
         "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
         (UINT32) GpeBlock->BlockBaseNumber,
-        (UINT32) (GpeBlock->BlockBaseNumber +
-                ((GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH) -1)),
-        GpeDevice->Name.Ascii,
-        GpeBlock->RegisterCount,
+        (UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1)),
+        GpeDevice->Name.Ascii, GpeBlock->RegisterCount,
         InterruptNumber));
 
     /* Update global count of currently available GPEs */
 
-    AcpiCurrentGpeCount += RegisterCount * ACPI_GPE_REGISTER_WIDTH;
+    AcpiCurrentGpeCount += GpeBlock->GpeCount;
     return_ACPI_STATUS (AE_OK);
 }
 
@@ -1139,28 +531,26 @@ AcpiEvCreateGpeBlock (
  *
  * FUNCTION:    AcpiEvInitializeGpeBlock
  *
- * PARAMETERS:  GpeDevice           - Handle to the parent GPE block
- *              GpeBlock            - Gpe Block info
+ * PARAMETERS:  ACPI_GPE_CALLBACK
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Initialize and enable a GPE block. First find and run any
- *              _PRT methods associated with the block, then enable the
- *              appropriate GPEs.
+ * DESCRIPTION: Initialize and enable a GPE block. Enable GPEs that have
+ *              associated methods.
  *              Note: Assumes namespace is locked.
  *
  ******************************************************************************/
 
 ACPI_STATUS
 AcpiEvInitializeGpeBlock (
-    ACPI_NAMESPACE_NODE     *GpeDevice,
-    ACPI_GPE_BLOCK_INFO     *GpeBlock)
+    ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
+    ACPI_GPE_BLOCK_INFO     *GpeBlock,
+    void                    *Ignored)
 {
     ACPI_STATUS             Status;
     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
-    ACPI_GPE_WALK_INFO      GpeInfo;
-    UINT32                  WakeGpeCount;
     UINT32                  GpeEnabledCount;
+    UINT32                  GpeIndex;
     UINT32                  i;
     UINT32                  j;
 
@@ -1168,235 +558,62 @@ AcpiEvInitializeGpeBlock (
     ACPI_FUNCTION_TRACE (EvInitializeGpeBlock);
 
 
-    /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */
-
-    if (!GpeBlock)
-    {
-        return_ACPI_STATUS (AE_OK);
-    }
-
     /*
-     * Runtime option: Should wake GPEs be enabled at runtime?  The default
-     * is no, they should only be enabled just as the machine goes to sleep.
+     * Ignore a null GPE block (e.g., if no GPE block 1 exists), and
+     * any GPE blocks that have been initialized already.
      */
-    if (AcpiGbl_LeaveWakeGpesDisabled)
+    if (!GpeBlock || GpeBlock->Initialized)
     {
-        /*
-         * Differentiate runtime vs wake GPEs, via the _PRW control methods.
-         * Each GPE that has one or more _PRWs that reference it is by
-         * definition a wake GPE and will not be enabled while the machine
-         * is running.
-         */
-        GpeInfo.GpeBlock = GpeBlock;
-        GpeInfo.GpeDevice = GpeDevice;
-
-        Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-                    ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
-                    AcpiEvMatchPrwAndGpe, NULL, &GpeInfo, NULL);
+        return_ACPI_STATUS (AE_OK);
     }
 
     /*
-     * Enable all GPEs in this block that have these attributes:
-     * 1) are "runtime" or "run/wake" GPEs, and
-     * 2) have a corresponding _Lxx or _Exx method
-     *
-     * Any other GPEs within this block must be enabled via the
-     * AcpiEnableGpe() external interface.
+     * Enable all GPEs that have a corresponding method and have the
+     * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block
+     * must be enabled via the acpi_enable_gpe() interface.
      */
-    WakeGpeCount = 0;
     GpeEnabledCount = 0;
 
     for (i = 0; i < GpeBlock->RegisterCount; i++)
     {
-        for (j = 0; j < 8; j++)
+        for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
         {
             /* Get the info block for this particular GPE */
 
-            GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
-                ACPI_GPE_REGISTER_WIDTH) + j];
-
-            if (((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
-                    ACPI_GPE_DISPATCH_METHOD) &&
-                 (GpeEventInfo->Flags & ACPI_GPE_TYPE_RUNTIME))
-            {
-                GpeEnabledCount++;
-            }
+            GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j;
+            GpeEventInfo = &GpeBlock->EventInfo[GpeIndex];
 
-            if (GpeEventInfo->Flags & ACPI_GPE_TYPE_WAKE)
+            /*
+             * Ignore GPEs that have no corresponding _Lxx/_Exx method
+             * and GPEs that are used to wake the system
+             */
+            if (((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_NONE) ||
+                ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) ||
+                (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
             {
-                WakeGpeCount++;
+                continue;
             }
-        }
-    }
-
-    ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
-        "Found %u Wake, Enabled %u Runtime GPEs in this block\n",
-        WakeGpeCount, GpeEnabledCount));
-
-    /* Enable all valid runtime GPEs found above */
-
-    Status = AcpiHwEnableRuntimeGpeBlock (NULL, GpeBlock, NULL);
-    if (ACPI_FAILURE (Status))
-    {
-        ACPI_ERROR ((AE_INFO, "Could not enable GPEs in GpeBlock %p",
-            GpeBlock));
-    }
-
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiEvGpeInitialize
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Initialize the GPE data structures
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiEvGpeInitialize (
-    void)
-{
-    UINT32                  RegisterCount0 = 0;
-    UINT32                  RegisterCount1 = 0;
-    UINT32                  GpeNumberMax = 0;
-    ACPI_STATUS             Status;
-
-
-    ACPI_FUNCTION_TRACE (EvGpeInitialize);
-
-
-    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
-    if (ACPI_FAILURE (Status))
-    {
-        return_ACPI_STATUS (Status);
-    }
-
-    /*
-     * Initialize the GPE Block(s) defined in the FADT
-     *
-     * Why the GPE register block lengths are divided by 2:  From the ACPI
-     * Spec, section "General-Purpose Event Registers", we have:
-     *
-     * "Each register block contains two registers of equal length
-     *  GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
-     *  GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
-     *  The length of the GPE1_STS and GPE1_EN registers is equal to
-     *  half the GPE1_LEN. If a generic register block is not supported
-     *  then its respective block pointer and block length values in the
-     *  FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
-     *  to be the same size."
-     */
-
-    /*
-     * Determine the maximum GPE number for this machine.
-     *
-     * Note: both GPE0 and GPE1 are optional, and either can exist without
-     * the other.
-     *
-     * If EITHER the register length OR the block address are zero, then that
-     * particular block is not supported.
-     */
-    if (AcpiGbl_FADT.Gpe0BlockLength &&
-        AcpiGbl_FADT.XGpe0Block.Address)
-    {
-        /* GPE block 0 exists (has both length and address > 0) */
-
-        RegisterCount0 = (UINT16) (AcpiGbl_FADT.Gpe0BlockLength / 2);
-
-        GpeNumberMax = (RegisterCount0 * ACPI_GPE_REGISTER_WIDTH) - 1;
-
-        /* Install GPE Block 0 */
-
-        Status = AcpiEvCreateGpeBlock (AcpiGbl_FadtGpeDevice,
-                    &AcpiGbl_FADT.XGpe0Block, RegisterCount0, 0,
-                    AcpiGbl_FADT.SciInterrupt, &AcpiGbl_GpeFadtBlocks[0]);
-
-        if (ACPI_FAILURE (Status))
-        {
-            ACPI_EXCEPTION ((AE_INFO, Status,
-                "Could not create GPE Block 0"));
-        }
-    }
-
-    if (AcpiGbl_FADT.Gpe1BlockLength &&
-        AcpiGbl_FADT.XGpe1Block.Address)
-    {
-        /* GPE block 1 exists (has both length and address > 0) */
-
-        RegisterCount1 = (UINT16) (AcpiGbl_FADT.Gpe1BlockLength / 2);
-
-        /* Check for GPE0/GPE1 overlap (if both banks exist) */
-
-        if ((RegisterCount0) &&
-            (GpeNumberMax >= AcpiGbl_FADT.Gpe1Base))
-        {
-            ACPI_ERROR ((AE_INFO,
-                "GPE0 block (GPE 0 to %d) overlaps the GPE1 block "
-                "(GPE %d to %d) - Ignoring GPE1",
-                GpeNumberMax, AcpiGbl_FADT.Gpe1Base,
-                AcpiGbl_FADT.Gpe1Base +
-                ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1)));
-
-            /* Ignore GPE1 block by setting the register count to zero */
-
-            RegisterCount1 = 0;
-        }
-        else
-        {
-            /* Install GPE Block 1 */
-
-            Status = AcpiEvCreateGpeBlock (AcpiGbl_FadtGpeDevice,
-                        &AcpiGbl_FADT.XGpe1Block, RegisterCount1,
-                        AcpiGbl_FADT.Gpe1Base,
-                        AcpiGbl_FADT.SciInterrupt, &AcpiGbl_GpeFadtBlocks[1]);
 
+            Status = AcpiEvAddGpeReference (GpeEventInfo);
             if (ACPI_FAILURE (Status))
             {
                 ACPI_EXCEPTION ((AE_INFO, Status,
-                    "Could not create GPE Block 1"));
+                    "Could not enable GPE 0x%02X",
+                    GpeIndex + GpeBlock->BlockBaseNumber));
+                continue;
             }
 
-            /*
-             * GPE0 and GPE1 do not have to be contiguous in the GPE number
-             * space. However, GPE0 always starts at GPE number zero.
-             */
-            GpeNumberMax = AcpiGbl_FADT.Gpe1Base +
-                            ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1);
+            GpeEnabledCount++;
         }
     }
 
-    /* Exit if there are no GPE registers */
-
-    if ((RegisterCount0 + RegisterCount1) == 0)
+    if (GpeEnabledCount)
     {
-        /* GPEs are not required by ACPI, this is OK */
-
         ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
-            "There are no GPE blocks defined in the FADT\n"));
-        Status = AE_OK;
-        goto Cleanup;
+            "Enabled %u GPEs in this block\n", GpeEnabledCount));
     }
 
-    /* Check for Max GPE number out-of-range */
-
-    if (GpeNumberMax > ACPI_GPE_MAX)
-    {
-        ACPI_ERROR ((AE_INFO,
-            "Maximum GPE number from FADT is too large: 0x%X",
-            GpeNumberMax));
-        Status = AE_BAD_VALUE;
-        goto Cleanup;
-    }
-
-Cleanup:
-    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+    GpeBlock->Initialized = TRUE;
     return_ACPI_STATUS (AE_OK);
 }
 
-
diff --git a/reactos/drivers/bus/acpi/acpica/events/evgpeinit.c b/reactos/drivers/bus/acpi/acpica/events/evgpeinit.c
new file mode 100644 (file)
index 0000000..8bba111
--- /dev/null
@@ -0,0 +1,531 @@
+/******************************************************************************
+ *
+ * Module Name: evgpeinit - System GPE initialization and update
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * 1. Copyright Notice
+ *
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
+ * All rights reserved.
+ *
+ * 2. License
+ *
+ * 2.1. This is your license from Intel Corp. under its intellectual property
+ * rights.  You may have additional license terms from the party that provided
+ * you this software, covering your right to use that party's intellectual
+ * property rights.
+ *
+ * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
+ * copy of the source code appearing in this file ("Covered Code") an
+ * irrevocable, perpetual, worldwide license under Intel's copyrights in the
+ * base code distributed originally by Intel ("Original Intel Code") to copy,
+ * make derivatives, distribute, use and display any portion of the Covered
+ * Code in any form, with the right to sublicense such rights; and
+ *
+ * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
+ * license (with the right to sublicense), under only those claims of Intel
+ * patents that are infringed by the Original Intel Code, to make, use, sell,
+ * offer to sell, and import the Covered Code and derivative works thereof
+ * solely to the minimum extent necessary to exercise the above copyright
+ * license, and in no event shall the patent license extend to any additions
+ * to or modifications of the Original Intel Code.  No other license or right
+ * is granted directly or by implication, estoppel or otherwise;
+ *
+ * The above copyright and patent license is granted only if the following
+ * conditions are met:
+ *
+ * 3. Conditions
+ *
+ * 3.1. Redistribution of Source with Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification with rights to further distribute source must include
+ * the above Copyright Notice, the above License, this list of Conditions,
+ * and the following Disclaimer and Export Compliance provision.  In addition,
+ * Licensee must cause all Covered Code to which Licensee contributes to
+ * contain a file documenting the changes Licensee made to create that Covered
+ * Code and the date of any change.  Licensee must include in that file the
+ * documentation of any changes made by any predecessor Licensee.  Licensee
+ * must include a prominent statement that the modification is derived,
+ * directly or indirectly, from Original Intel Code.
+ *
+ * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification without rights to further distribute source must
+ * include the following Disclaimer and Export Compliance provision in the
+ * documentation and/or other materials provided with distribution.  In
+ * addition, Licensee may not authorize further sublicense of source of any
+ * portion of the Covered Code, and must include terms to the effect that the
+ * license from Licensee to its licensee is limited to the intellectual
+ * property embodied in the software Licensee provides to its licensee, and
+ * not to intellectual property embodied in modifications its licensee may
+ * make.
+ *
+ * 3.3. Redistribution of Executable. Redistribution in executable form of any
+ * substantial portion of the Covered Code or modification must reproduce the
+ * above Copyright Notice, and the following Disclaimer and Export Compliance
+ * provision in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3.4. Intel retains all right, title, and interest in and to the Original
+ * Intel Code.
+ *
+ * 3.5. Neither the name Intel nor any other trademark owned or controlled by
+ * Intel shall be used in advertising or otherwise to promote the sale, use or
+ * other dealings in products derived from or relating to the Covered Code
+ * without prior written authorization from Intel.
+ *
+ * 4. Disclaimer and Export Compliance
+ *
+ * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
+ * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
+ * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
+ * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
+ * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
+ * PARTICULAR PURPOSE.
+ *
+ * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
+ * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
+ * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
+ * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
+ * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
+ * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
+ * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
+ * LIMITED REMEDY.
+ *
+ * 4.3. Licensee shall not export, either directly or indirectly, any of this
+ * software or system incorporating such software without first obtaining any
+ * required license or other approval from the U. S. Department of Commerce or
+ * any other agency or department of the United States Government.  In the
+ * event Licensee exports any such software from the United States or
+ * re-exports any such software from a foreign destination, Licensee shall
+ * ensure that the distribution and export/re-export of the software is in
+ * compliance with all laws, regulations, orders, or other restrictions of the
+ * U.S. Export Administration Regulations. Licensee agrees that neither it nor
+ * any of its subsidiaries will export/re-export any technical data, process,
+ * software, or service, directly or indirectly, to any country for which the
+ * United States government or any agency thereof requires an export license,
+ * other governmental approval, or letter of assurance, without first obtaining
+ * such license, approval or letter.
+ *
+ *****************************************************************************/
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acevents.h"
+#include "acnamesp.h"
+
+#define _COMPONENT          ACPI_EVENTS
+        ACPI_MODULE_NAME    ("evgpeinit")
+
+
+/*
+ * Note: History of _PRW support in ACPICA
+ *
+ * Originally (2000 - 2010), the GPE initialization code performed a walk of
+ * the entire namespace to execute the _PRW methods and detect all GPEs
+ * capable of waking the system.
+ *
+ * As of 10/2010, the _PRW method execution has been removed since it is
+ * actually unnecessary. The host OS must in fact execute all _PRW methods
+ * in order to identify the device/power-resource dependencies. We now put
+ * the onus on the host OS to identify the wake GPEs as part of this process
+ * and to inform ACPICA of these GPEs via the AcpiSetupGpeForWake interface. This
+ * not only reduces the complexity of the ACPICA initialization code, but in
+ * some cases (on systems with very large namespaces) it should reduce the
+ * kernel boot time as well.
+ */
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiEvGpeInitialize
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize the GPE data structures and the FADT GPE 0/1 blocks
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvGpeInitialize (
+    void)
+{
+    UINT32                  RegisterCount0 = 0;
+    UINT32                  RegisterCount1 = 0;
+    UINT32                  GpeNumberMax = 0;
+    ACPI_STATUS             Status;
+
+
+    ACPI_FUNCTION_TRACE (EvGpeInitialize);
+
+
+    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+    if (ACPI_FAILURE (Status))
+    {
+        return_ACPI_STATUS (Status);
+    }
+
+    /*
+     * Initialize the GPE Block(s) defined in the FADT
+     *
+     * Why the GPE register block lengths are divided by 2:  From the ACPI
+     * Spec, section "General-Purpose Event Registers", we have:
+     *
+     * "Each register block contains two registers of equal length
+     *  GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
+     *  GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
+     *  The length of the GPE1_STS and GPE1_EN registers is equal to
+     *  half the GPE1_LEN. If a generic register block is not supported
+     *  then its respective block pointer and block length values in the
+     *  FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
+     *  to be the same size."
+     */
+
+    /*
+     * Determine the maximum GPE number for this machine.
+     *
+     * Note: both GPE0 and GPE1 are optional, and either can exist without
+     * the other.
+     *
+     * If EITHER the register length OR the block address are zero, then that
+     * particular block is not supported.
+     */
+    if (AcpiGbl_FADT.Gpe0BlockLength &&
+        AcpiGbl_FADT.XGpe0Block.Address)
+    {
+        /* GPE block 0 exists (has both length and address > 0) */
+
+        RegisterCount0 = (UINT16) (AcpiGbl_FADT.Gpe0BlockLength / 2);
+
+        GpeNumberMax = (RegisterCount0 * ACPI_GPE_REGISTER_WIDTH) - 1;
+
+        /* Install GPE Block 0 */
+
+        Status = AcpiEvCreateGpeBlock (AcpiGbl_FadtGpeDevice,
+                    &AcpiGbl_FADT.XGpe0Block, RegisterCount0, 0,
+                    AcpiGbl_FADT.SciInterrupt, &AcpiGbl_GpeFadtBlocks[0]);
+
+        if (ACPI_FAILURE (Status))
+        {
+            ACPI_EXCEPTION ((AE_INFO, Status,
+                "Could not create GPE Block 0"));
+        }
+    }
+
+    if (AcpiGbl_FADT.Gpe1BlockLength &&
+        AcpiGbl_FADT.XGpe1Block.Address)
+    {
+        /* GPE block 1 exists (has both length and address > 0) */
+
+        RegisterCount1 = (UINT16) (AcpiGbl_FADT.Gpe1BlockLength / 2);
+
+        /* Check for GPE0/GPE1 overlap (if both banks exist) */
+
+        if ((RegisterCount0) &&
+            (GpeNumberMax >= AcpiGbl_FADT.Gpe1Base))
+        {
+            ACPI_ERROR ((AE_INFO,
+                "GPE0 block (GPE 0 to %u) overlaps the GPE1 block "
+                "(GPE %u to %u) - Ignoring GPE1",
+                GpeNumberMax, AcpiGbl_FADT.Gpe1Base,
+                AcpiGbl_FADT.Gpe1Base +
+                ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1)));
+
+            /* Ignore GPE1 block by setting the register count to zero */
+
+            RegisterCount1 = 0;
+        }
+        else
+        {
+            /* Install GPE Block 1 */
+
+            Status = AcpiEvCreateGpeBlock (AcpiGbl_FadtGpeDevice,
+                        &AcpiGbl_FADT.XGpe1Block, RegisterCount1,
+                        AcpiGbl_FADT.Gpe1Base,
+                        AcpiGbl_FADT.SciInterrupt, &AcpiGbl_GpeFadtBlocks[1]);
+
+            if (ACPI_FAILURE (Status))
+            {
+                ACPI_EXCEPTION ((AE_INFO, Status,
+                    "Could not create GPE Block 1"));
+            }
+
+            /*
+             * GPE0 and GPE1 do not have to be contiguous in the GPE number
+             * space. However, GPE0 always starts at GPE number zero.
+             */
+            GpeNumberMax = AcpiGbl_FADT.Gpe1Base +
+                            ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1);
+        }
+    }
+
+    /* Exit if there are no GPE registers */
+
+    if ((RegisterCount0 + RegisterCount1) == 0)
+    {
+        /* GPEs are not required by ACPI, this is OK */
+
+        ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+            "There are no GPE blocks defined in the FADT\n"));
+        Status = AE_OK;
+        goto Cleanup;
+    }
+
+    /* Check for Max GPE number out-of-range */
+
+    if (GpeNumberMax > ACPI_GPE_MAX)
+    {
+        ACPI_ERROR ((AE_INFO,
+            "Maximum GPE number from FADT is too large: 0x%X",
+            GpeNumberMax));
+        Status = AE_BAD_VALUE;
+        goto Cleanup;
+    }
+
+Cleanup:
+    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+    return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiEvUpdateGpes
+ *
+ * PARAMETERS:  TableOwnerId        - ID of the newly-loaded ACPI table
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a
+ *              result of a Load() or LoadTable() operation. If new GPE
+ *              methods have been installed, register the new methods.
+ *
+ ******************************************************************************/
+
+void
+AcpiEvUpdateGpes (
+    ACPI_OWNER_ID           TableOwnerId)
+{
+    ACPI_GPE_XRUPT_INFO     *GpeXruptInfo;
+    ACPI_GPE_BLOCK_INFO     *GpeBlock;
+    ACPI_GPE_WALK_INFO      WalkInfo;
+    ACPI_STATUS             Status = AE_OK;
+
+
+    /*
+     * Find any _Lxx/_Exx GPE methods that have just been loaded.
+     *
+     * Any GPEs that correspond to new _Lxx/_Exx methods are immediately
+     * enabled.
+     *
+     * Examine the namespace underneath each GpeDevice within the
+     * GpeBlock lists.
+     */
+    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+    if (ACPI_FAILURE (Status))
+    {
+        return;
+    }
+
+    WalkInfo.Count = 0;
+    WalkInfo.OwnerId = TableOwnerId;
+    WalkInfo.ExecuteByOwnerId = TRUE;
+
+    /* Walk the interrupt level descriptor list */
+
+    GpeXruptInfo = AcpiGbl_GpeXruptListHead;
+    while (GpeXruptInfo)
+    {
+        /* Walk all Gpe Blocks attached to this interrupt level */
+
+        GpeBlock = GpeXruptInfo->GpeBlockListHead;
+        while (GpeBlock)
+        {
+            WalkInfo.GpeBlock = GpeBlock;
+            WalkInfo.GpeDevice = GpeBlock->Node;
+
+            Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD,
+                        WalkInfo.GpeDevice, ACPI_UINT32_MAX,
+                        ACPI_NS_WALK_NO_UNLOCK, AcpiEvMatchGpeMethod,
+                        NULL, &WalkInfo, NULL);
+            if (ACPI_FAILURE (Status))
+            {
+                ACPI_EXCEPTION ((AE_INFO, Status,
+                    "While decoding _Lxx/_Exx methods"));
+            }
+
+            GpeBlock = GpeBlock->Next;
+        }
+
+        GpeXruptInfo = GpeXruptInfo->Next;
+    }
+
+    if (WalkInfo.Count)
+    {
+        ACPI_INFO ((AE_INFO, "Enabled %u new GPEs", WalkInfo.Count));
+    }
+
+    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+    return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiEvMatchGpeMethod
+ *
+ * PARAMETERS:  Callback from WalkNamespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Called from AcpiWalkNamespace. Expects each object to be a
+ *              control method under the _GPE portion of the namespace.
+ *              Extract the name and GPE type from the object, saving this
+ *              information for quick lookup during GPE dispatch. Allows a
+ *              per-OwnerId evaluation if ExecuteByOwnerId is TRUE in the
+ *              WalkInfo parameter block.
+ *
+ *              The name of each GPE control method is of the form:
+ *              "_Lxx" or "_Exx", where:
+ *                  L      - means that the GPE is level triggered
+ *                  E      - means that the GPE is edge triggered
+ *                  xx     - is the GPE number [in HEX]
+ *
+ * If WalkInfo->ExecuteByOwnerId is TRUE, we only execute examine GPE methods
+ * with that owner.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvMatchGpeMethod (
+    ACPI_HANDLE             ObjHandle,
+    UINT32                  Level,
+    void                    *Context,
+    void                    **ReturnValue)
+{
+    ACPI_NAMESPACE_NODE     *MethodNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
+    ACPI_GPE_WALK_INFO      *WalkInfo = ACPI_CAST_PTR (ACPI_GPE_WALK_INFO, Context);
+    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
+    UINT32                  GpeNumber;
+    char                    Name[ACPI_NAME_SIZE + 1];
+    UINT8                   Type;
+
+
+    ACPI_FUNCTION_TRACE (EvMatchGpeMethod);
+
+
+    /* Check if requested OwnerId matches this OwnerId */
+
+    if ((WalkInfo->ExecuteByOwnerId) &&
+        (MethodNode->OwnerId != WalkInfo->OwnerId))
+    {
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    /*
+     * Match and decode the _Lxx and _Exx GPE method names
+     *
+     * 1) Extract the method name and null terminate it
+     */
+    ACPI_MOVE_32_TO_32 (Name, &MethodNode->Name.Integer);
+    Name[ACPI_NAME_SIZE] = 0;
+
+    /* 2) Name must begin with an underscore */
+
+    if (Name[0] != '_')
+    {
+        return_ACPI_STATUS (AE_OK); /* Ignore this method */
+    }
+
+    /*
+     * 3) Edge/Level determination is based on the 2nd character
+     *    of the method name
+     */
+    switch (Name[1])
+    {
+    case 'L':
+        Type = ACPI_GPE_LEVEL_TRIGGERED;
+        break;
+
+    case 'E':
+        Type = ACPI_GPE_EDGE_TRIGGERED;
+        break;
+
+    default:
+        /* Unknown method type, just ignore it */
+
+        ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
+            "Ignoring unknown GPE method type: %s "
+            "(name not of form _Lxx or _Exx)", Name));
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    /* 4) The last two characters of the name are the hex GPE Number */
+
+    GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16);
+    if (GpeNumber == ACPI_UINT32_MAX)
+    {
+        /* Conversion failed; invalid method, just ignore it */
+
+        ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
+            "Could not extract GPE number from name: %s "
+            "(name is not of form _Lxx or _Exx)", Name));
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    /* Ensure that we have a valid GPE number for this GPE block */
+
+    GpeEventInfo = AcpiEvLowGetGpeInfo (GpeNumber, WalkInfo->GpeBlock);
+    if (!GpeEventInfo)
+    {
+        /*
+         * This GpeNumber is not valid for this GPE block, just ignore it.
+         * However, it may be valid for a different GPE block, since GPE0
+         * and GPE1 methods both appear under \_GPE.
+         */
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
+            ACPI_GPE_DISPATCH_HANDLER)
+    {
+        /* If there is already a handler, ignore this GPE method */
+
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
+            ACPI_GPE_DISPATCH_METHOD)
+    {
+        /*
+         * If there is already a method, ignore this method. But check
+         * for a type mismatch (if both the _Lxx AND _Exx exist)
+         */
+        if (Type != (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK))
+        {
+            ACPI_ERROR ((AE_INFO,
+                "For GPE 0x%.2X, found both _L%2.2X and _E%2.2X methods",
+                GpeNumber, GpeNumber, GpeNumber));
+        }
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    /*
+     * Add the GPE information from above to the GpeEventInfo block for
+     * use during dispatch of this GPE.
+     */
+    GpeEventInfo->Flags &= ~(ACPI_GPE_DISPATCH_MASK);
+    GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_METHOD);
+    GpeEventInfo->Dispatch.MethodNode = MethodNode;
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
+        "Registered GPE method %s as GPE number 0x%.2X\n",
+        Name, GpeNumber));
+    return_ACPI_STATUS (AE_OK);
+}
diff --git a/reactos/drivers/bus/acpi/acpica/events/evgpeutil.c b/reactos/drivers/bus/acpi/acpica/events/evgpeutil.c
new file mode 100644 (file)
index 0000000..eb422a1
--- /dev/null
@@ -0,0 +1,496 @@
+/******************************************************************************
+ *
+ * Module Name: evgpeutil - GPE utilities
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * 1. Copyright Notice
+ *
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
+ * All rights reserved.
+ *
+ * 2. License
+ *
+ * 2.1. This is your license from Intel Corp. under its intellectual property
+ * rights.  You may have additional license terms from the party that provided
+ * you this software, covering your right to use that party's intellectual
+ * property rights.
+ *
+ * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
+ * copy of the source code appearing in this file ("Covered Code") an
+ * irrevocable, perpetual, worldwide license under Intel's copyrights in the
+ * base code distributed originally by Intel ("Original Intel Code") to copy,
+ * make derivatives, distribute, use and display any portion of the Covered
+ * Code in any form, with the right to sublicense such rights; and
+ *
+ * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
+ * license (with the right to sublicense), under only those claims of Intel
+ * patents that are infringed by the Original Intel Code, to make, use, sell,
+ * offer to sell, and import the Covered Code and derivative works thereof
+ * solely to the minimum extent necessary to exercise the above copyright
+ * license, and in no event shall the patent license extend to any additions
+ * to or modifications of the Original Intel Code.  No other license or right
+ * is granted directly or by implication, estoppel or otherwise;
+ *
+ * The above copyright and patent license is granted only if the following
+ * conditions are met:
+ *
+ * 3. Conditions
+ *
+ * 3.1. Redistribution of Source with Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification with rights to further distribute source must include
+ * the above Copyright Notice, the above License, this list of Conditions,
+ * and the following Disclaimer and Export Compliance provision.  In addition,
+ * Licensee must cause all Covered Code to which Licensee contributes to
+ * contain a file documenting the changes Licensee made to create that Covered
+ * Code and the date of any change.  Licensee must include in that file the
+ * documentation of any changes made by any predecessor Licensee.  Licensee
+ * must include a prominent statement that the modification is derived,
+ * directly or indirectly, from Original Intel Code.
+ *
+ * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification without rights to further distribute source must
+ * include the following Disclaimer and Export Compliance provision in the
+ * documentation and/or other materials provided with distribution.  In
+ * addition, Licensee may not authorize further sublicense of source of any
+ * portion of the Covered Code, and must include terms to the effect that the
+ * license from Licensee to its licensee is limited to the intellectual
+ * property embodied in the software Licensee provides to its licensee, and
+ * not to intellectual property embodied in modifications its licensee may
+ * make.
+ *
+ * 3.3. Redistribution of Executable. Redistribution in executable form of any
+ * substantial portion of the Covered Code or modification must reproduce the
+ * above Copyright Notice, and the following Disclaimer and Export Compliance
+ * provision in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3.4. Intel retains all right, title, and interest in and to the Original
+ * Intel Code.
+ *
+ * 3.5. Neither the name Intel nor any other trademark owned or controlled by
+ * Intel shall be used in advertising or otherwise to promote the sale, use or
+ * other dealings in products derived from or relating to the Covered Code
+ * without prior written authorization from Intel.
+ *
+ * 4. Disclaimer and Export Compliance
+ *
+ * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
+ * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
+ * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
+ * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
+ * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
+ * PARTICULAR PURPOSE.
+ *
+ * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
+ * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
+ * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
+ * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
+ * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
+ * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
+ * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
+ * LIMITED REMEDY.
+ *
+ * 4.3. Licensee shall not export, either directly or indirectly, any of this
+ * software or system incorporating such software without first obtaining any
+ * required license or other approval from the U. S. Department of Commerce or
+ * any other agency or department of the United States Government.  In the
+ * event Licensee exports any such software from the United States or
+ * re-exports any such software from a foreign destination, Licensee shall
+ * ensure that the distribution and export/re-export of the software is in
+ * compliance with all laws, regulations, orders, or other restrictions of the
+ * U.S. Export Administration Regulations. Licensee agrees that neither it nor
+ * any of its subsidiaries will export/re-export any technical data, process,
+ * software, or service, directly or indirectly, to any country for which the
+ * United States government or any agency thereof requires an export license,
+ * other governmental approval, or letter of assurance, without first obtaining
+ * such license, approval or letter.
+ *
+ *****************************************************************************/
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acevents.h"
+
+#define _COMPONENT          ACPI_EVENTS
+        ACPI_MODULE_NAME    ("evgpeutil")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiEvWalkGpeList
+ *
+ * PARAMETERS:  GpeWalkCallback     - Routine called for each GPE block
+ *              Context             - Value passed to callback
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Walk the GPE lists.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvWalkGpeList (
+    ACPI_GPE_CALLBACK       GpeWalkCallback,
+    void                    *Context)
+{
+    ACPI_GPE_BLOCK_INFO     *GpeBlock;
+    ACPI_GPE_XRUPT_INFO     *GpeXruptInfo;
+    ACPI_STATUS             Status = AE_OK;
+    ACPI_CPU_FLAGS          Flags;
+
+
+    ACPI_FUNCTION_TRACE (EvWalkGpeList);
+
+
+    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+    /* Walk the interrupt level descriptor list */
+
+    GpeXruptInfo = AcpiGbl_GpeXruptListHead;
+    while (GpeXruptInfo)
+    {
+        /* Walk all Gpe Blocks attached to this interrupt level */
+
+        GpeBlock = GpeXruptInfo->GpeBlockListHead;
+        while (GpeBlock)
+        {
+            /* One callback per GPE block */
+
+            Status = GpeWalkCallback (GpeXruptInfo, GpeBlock, Context);
+            if (ACPI_FAILURE (Status))
+            {
+                if (Status == AE_CTRL_END) /* Callback abort */
+                {
+                    Status = AE_OK;
+                }
+                goto UnlockAndExit;
+            }
+
+            GpeBlock = GpeBlock->Next;
+        }
+
+        GpeXruptInfo = GpeXruptInfo->Next;
+    }
+
+UnlockAndExit:
+    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiEvValidGpeEvent
+ *
+ * PARAMETERS:  GpeEventInfo                - Info for this GPE
+ *
+ * RETURN:      TRUE if the GpeEvent is valid
+ *
+ * DESCRIPTION: Validate a GPE event. DO NOT CALL FROM INTERRUPT LEVEL.
+ *              Should be called only when the GPE lists are semaphore locked
+ *              and not subject to change.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiEvValidGpeEvent (
+    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
+{
+    ACPI_GPE_XRUPT_INFO     *GpeXruptBlock;
+    ACPI_GPE_BLOCK_INFO     *GpeBlock;
+
+
+    ACPI_FUNCTION_ENTRY ();
+
+
+    /* No need for spin lock since we are not changing any list elements */
+
+    /* Walk the GPE interrupt levels */
+
+    GpeXruptBlock = AcpiGbl_GpeXruptListHead;
+    while (GpeXruptBlock)
+    {
+        GpeBlock = GpeXruptBlock->GpeBlockListHead;
+
+        /* Walk the GPE blocks on this interrupt level */
+
+        while (GpeBlock)
+        {
+            if ((&GpeBlock->EventInfo[0] <= GpeEventInfo) &&
+                (&GpeBlock->EventInfo[GpeBlock->GpeCount] > GpeEventInfo))
+            {
+                return (TRUE);
+            }
+
+            GpeBlock = GpeBlock->Next;
+        }
+
+        GpeXruptBlock = GpeXruptBlock->Next;
+    }
+
+    return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiEvGetGpeDevice
+ *
+ * PARAMETERS:  GPE_WALK_CALLBACK
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Matches the input GPE index (0-CurrentGpeCount) with a GPE
+ *              block device. NULL if the GPE is one of the FADT-defined GPEs.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvGetGpeDevice (
+    ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
+    ACPI_GPE_BLOCK_INFO     *GpeBlock,
+    void                    *Context)
+{
+    ACPI_GPE_DEVICE_INFO    *Info = Context;
+
+
+    /* Increment Index by the number of GPEs in this block */
+
+    Info->NextBlockBaseIndex += GpeBlock->GpeCount;
+
+    if (Info->Index < Info->NextBlockBaseIndex)
+    {
+        /*
+         * The GPE index is within this block, get the node. Leave the node
+         * NULL for the FADT-defined GPEs
+         */
+        if ((GpeBlock->Node)->Type == ACPI_TYPE_DEVICE)
+        {
+            Info->GpeDevice = GpeBlock->Node;
+        }
+
+        Info->Status = AE_OK;
+        return (AE_CTRL_END);
+    }
+
+    return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiEvGetGpeXruptBlock
+ *
+ * PARAMETERS:  InterruptNumber      - Interrupt for a GPE block
+ *
+ * RETURN:      A GPE interrupt block
+ *
+ * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt
+ *              block per unique interrupt level used for GPEs. Should be
+ *              called only when the GPE lists are semaphore locked and not
+ *              subject to change.
+ *
+ ******************************************************************************/
+
+ACPI_GPE_XRUPT_INFO *
+AcpiEvGetGpeXruptBlock (
+    UINT32                  InterruptNumber)
+{
+    ACPI_GPE_XRUPT_INFO     *NextGpeXrupt;
+    ACPI_GPE_XRUPT_INFO     *GpeXrupt;
+    ACPI_STATUS             Status;
+    ACPI_CPU_FLAGS          Flags;
+
+
+    ACPI_FUNCTION_TRACE (EvGetGpeXruptBlock);
+
+
+    /* No need for lock since we are not changing any list elements here */
+
+    NextGpeXrupt = AcpiGbl_GpeXruptListHead;
+    while (NextGpeXrupt)
+    {
+        if (NextGpeXrupt->InterruptNumber == InterruptNumber)
+        {
+            return_PTR (NextGpeXrupt);
+        }
+
+        NextGpeXrupt = NextGpeXrupt->Next;
+    }
+
+    /* Not found, must allocate a new xrupt descriptor */
+
+    GpeXrupt = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_XRUPT_INFO));
+    if (!GpeXrupt)
+    {
+        return_PTR (NULL);
+    }
+
+    GpeXrupt->InterruptNumber = InterruptNumber;
+
+    /* Install new interrupt descriptor with spin lock */
+
+    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+    if (AcpiGbl_GpeXruptListHead)
+    {
+        NextGpeXrupt = AcpiGbl_GpeXruptListHead;
+        while (NextGpeXrupt->Next)
+        {
+            NextGpeXrupt = NextGpeXrupt->Next;
+        }
+
+        NextGpeXrupt->Next = GpeXrupt;
+        GpeXrupt->Previous = NextGpeXrupt;
+    }
+    else
+    {
+        AcpiGbl_GpeXruptListHead = GpeXrupt;
+    }
+    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+
+    /* Install new interrupt handler if not SCI_INT */
+
+    if (InterruptNumber != AcpiGbl_FADT.SciInterrupt)
+    {
+        Status = AcpiOsInstallInterruptHandler (InterruptNumber,
+                    AcpiEvGpeXruptHandler, GpeXrupt);
+        if (ACPI_FAILURE (Status))
+        {
+            ACPI_ERROR ((AE_INFO,
+                "Could not install GPE interrupt handler at level 0x%X",
+                InterruptNumber));
+            return_PTR (NULL);
+        }
+    }
+
+    return_PTR (GpeXrupt);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiEvDeleteGpeXrupt
+ *
+ * PARAMETERS:  GpeXrupt        - A GPE interrupt info block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove and free a GpeXrupt block. Remove an associated
+ *              interrupt handler if not the SCI interrupt.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvDeleteGpeXrupt (
+    ACPI_GPE_XRUPT_INFO     *GpeXrupt)
+{
+    ACPI_STATUS             Status;
+    ACPI_CPU_FLAGS          Flags;
+
+
+    ACPI_FUNCTION_TRACE (EvDeleteGpeXrupt);
+
+
+    /* We never want to remove the SCI interrupt handler */
+
+    if (GpeXrupt->InterruptNumber == AcpiGbl_FADT.SciInterrupt)
+    {
+        GpeXrupt->GpeBlockListHead = NULL;
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    /* Disable this interrupt */
+
+    Status = AcpiOsRemoveInterruptHandler (
+                GpeXrupt->InterruptNumber, AcpiEvGpeXruptHandler);
+    if (ACPI_FAILURE (Status))
+    {
+        return_ACPI_STATUS (Status);
+    }
+
+    /* Unlink the interrupt block with lock */
+
+    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+    if (GpeXrupt->Previous)
+    {
+        GpeXrupt->Previous->Next = GpeXrupt->Next;
+    }
+    else
+    {
+        /* No previous, update list head */
+
+        AcpiGbl_GpeXruptListHead = GpeXrupt->Next;
+    }
+
+    if (GpeXrupt->Next)
+    {
+        GpeXrupt->Next->Previous = GpeXrupt->Previous;
+    }
+    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+
+    /* Free the block */
+
+    ACPI_FREE (GpeXrupt);
+    return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiEvDeleteGpeHandlers
+ *
+ * PARAMETERS:  GpeXruptInfo        - GPE Interrupt info
+ *              GpeBlock            - Gpe Block info
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Delete all Handler objects found in the GPE data structs.
+ *              Used only prior to termination.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvDeleteGpeHandlers (
+    ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
+    ACPI_GPE_BLOCK_INFO     *GpeBlock,
+    void                    *Context)
+{
+    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
+    UINT32                  i;
+    UINT32                  j;
+
+
+    ACPI_FUNCTION_TRACE (EvDeleteGpeHandlers);
+
+
+    /* Examine each GPE Register within the block */
+
+    for (i = 0; i < GpeBlock->RegisterCount; i++)
+    {
+        /* Now look at the individual GPEs in this byte register */
+
+        for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
+        {
+            GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
+                ACPI_GPE_REGISTER_WIDTH) + j];
+
+            if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
+                    ACPI_GPE_DISPATCH_HANDLER)
+            {
+                ACPI_FREE (GpeEventInfo->Dispatch.Handler);
+                GpeEventInfo->Dispatch.Handler = NULL;
+                GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;
+            }
+        }
+    }
+
+    return_ACPI_STATUS (AE_OK);
+}
+
index 1e7f9e1..69d6c79 100644 (file)
@@ -8,7 +8,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
 #include "accommon.h"
 #include "acevents.h"
 #include "acnamesp.h"
-#include "acinterp.h"
 
 #define _COMPONENT          ACPI_EVENTS
         ACPI_MODULE_NAME    ("evmisc")
@@ -129,14 +128,6 @@ static void ACPI_SYSTEM_XFACE
 AcpiEvNotifyDispatch (
     void                    *Context);
 
-static UINT32
-AcpiEvGlobalLockHandler (
-    void                    *Context);
-
-static ACPI_STATUS
-AcpiEvRemoveGlobalLockHandler (
-    void);
-
 
 /*******************************************************************************
  *
@@ -372,292 +363,6 @@ AcpiEvNotifyDispatch (
 }
 
 
-/*******************************************************************************
- *
- * FUNCTION:    AcpiEvGlobalLockHandler
- *
- * PARAMETERS:  Context         - From thread interface, not used
- *
- * RETURN:      ACPI_INTERRUPT_HANDLED
- *
- * DESCRIPTION: Invoked directly from the SCI handler when a global lock
- *              release interrupt occurs. Attempt to acquire the global lock,
- *              if successful, signal the thread waiting for the lock.
- *
- * NOTE: Assumes that the semaphore can be signaled from interrupt level. If
- * this is not possible for some reason, a separate thread will have to be
- * scheduled to do this.
- *
- ******************************************************************************/
-
-static UINT32
-AcpiEvGlobalLockHandler (
-    void                    *Context)
-{
-    BOOLEAN                 Acquired = FALSE;
-    ACPI_STATUS             Status;
-
-
-    /*
-     * Attempt to get the lock.
-     *
-     * If we don't get it now, it will be marked pending and we will
-     * take another interrupt when it becomes free.
-     */
-    ACPI_ACQUIRE_GLOBAL_LOCK (AcpiGbl_FACS, Acquired);
-    if (Acquired)
-    {
-        /* Got the lock, now wake the thread waiting for it */
-
-        AcpiGbl_GlobalLockAcquired = TRUE;
-
-        /* Send a unit to the semaphore */
-
-        Status = AcpiOsSignalSemaphore (AcpiGbl_GlobalLockSemaphore, 1);
-        if (ACPI_FAILURE (Status))
-        {
-            ACPI_ERROR ((AE_INFO, "Could not signal Global Lock semaphore"));
-        }
-    }
-
-    return (ACPI_INTERRUPT_HANDLED);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiEvInitGlobalLockHandler
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Install a handler for the global lock release event
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiEvInitGlobalLockHandler (
-    void)
-{
-    ACPI_STATUS             Status;
-
-
-    ACPI_FUNCTION_TRACE (EvInitGlobalLockHandler);
-
-
-    /* Attempt installation of the global lock handler */
-
-    Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL,
-                AcpiEvGlobalLockHandler, NULL);
-
-    /*
-     * If the global lock does not exist on this platform, the attempt to
-     * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick).
-     * Map to AE_OK, but mark global lock as not present. Any attempt to
-     * actually use the global lock will be flagged with an error.
-     */
-    if (Status == AE_NO_HARDWARE_RESPONSE)
-    {
-        ACPI_ERROR ((AE_INFO,
-            "No response from Global Lock hardware, disabling lock"));
-
-        AcpiGbl_GlobalLockPresent = FALSE;
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    AcpiGbl_GlobalLockPresent = TRUE;
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiEvRemoveGlobalLockHandler
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Remove the handler for the Global Lock
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-AcpiEvRemoveGlobalLockHandler (
-    void)
-{
-    ACPI_STATUS             Status;
-
-
-    ACPI_FUNCTION_TRACE (EvRemoveGlobalLockHandler);
-
-    AcpiGbl_GlobalLockPresent = FALSE;
-    Status = AcpiRemoveFixedEventHandler (ACPI_EVENT_GLOBAL,
-                AcpiEvGlobalLockHandler);
-
-    return_ACPI_STATUS (Status);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION:    AcpiEvAcquireGlobalLock
- *
- * PARAMETERS:  Timeout         - Max time to wait for the lock, in millisec.
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Attempt to gain ownership of the Global Lock.
- *
- * MUTEX:       Interpreter must be locked
- *
- * Note: The original implementation allowed multiple threads to "acquire" the
- * Global Lock, and the OS would hold the lock until the last thread had
- * released it. However, this could potentially starve the BIOS out of the
- * lock, especially in the case where there is a tight handshake between the
- * Embedded Controller driver and the BIOS. Therefore, this implementation
- * allows only one thread to acquire the HW Global Lock at a time, and makes
- * the global lock appear as a standard mutex on the OS side.
- *
- *****************************************************************************/
-
-ACPI_STATUS
-AcpiEvAcquireGlobalLock (
-    UINT16                  Timeout)
-{
-    ACPI_STATUS             Status = AE_OK;
-    BOOLEAN                 Acquired = FALSE;
-
-
-    ACPI_FUNCTION_TRACE (EvAcquireGlobalLock);
-
-
-    /*
-     * Only one thread can acquire the GL at a time, the GlobalLockMutex
-     * enforces this. This interface releases the interpreter if we must wait.
-     */
-    Status = AcpiExSystemWaitMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex,
-                Timeout);
-    if (ACPI_FAILURE (Status))
-    {
-        return_ACPI_STATUS (Status);
-    }
-
-    /*
-     * Update the global lock handle and check for wraparound. The handle is
-     * only used for the external global lock interfaces, but it is updated
-     * here to properly handle the case where a single thread may acquire the
-     * lock via both the AML and the AcpiAcquireGlobalLock interfaces. The
-     * handle is therefore updated on the first acquire from a given thread
-     * regardless of where the acquisition request originated.
-     */
-    AcpiGbl_GlobalLockHandle++;
-    if (AcpiGbl_GlobalLockHandle == 0)
-    {
-        AcpiGbl_GlobalLockHandle = 1;
-    }
-
-    /*
-     * Make sure that a global lock actually exists. If not, just treat the
-     * lock as a standard mutex.
-     */
-    if (!AcpiGbl_GlobalLockPresent)
-    {
-        AcpiGbl_GlobalLockAcquired = TRUE;
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    /* Attempt to acquire the actual hardware lock */
-
-    ACPI_ACQUIRE_GLOBAL_LOCK (AcpiGbl_FACS, Acquired);
-    if (Acquired)
-    {
-       /* We got the lock */
-
-        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Acquired hardware Global Lock\n"));
-
-        AcpiGbl_GlobalLockAcquired = TRUE;
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    /*
-     * Did not get the lock. The pending bit was set above, and we must now
-     * wait until we get the global lock released interrupt.
-     */
-    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n"));
-
-    /*
-     * Wait for handshake with the global lock interrupt handler.
-     * This interface releases the interpreter if we must wait.
-     */
-    Status = AcpiExSystemWaitSemaphore (AcpiGbl_GlobalLockSemaphore,
-                ACPI_WAIT_FOREVER);
-
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiEvReleaseGlobalLock
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Releases ownership of the Global Lock.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiEvReleaseGlobalLock (
-    void)
-{
-    BOOLEAN                 Pending = FALSE;
-    ACPI_STATUS             Status = AE_OK;
-
-
-    ACPI_FUNCTION_TRACE (EvReleaseGlobalLock);
-
-
-    /* Lock must be already acquired */
-
-    if (!AcpiGbl_GlobalLockAcquired)
-    {
-        ACPI_WARNING ((AE_INFO,
-            "Cannot release the ACPI Global Lock, it has not been acquired"));
-        return_ACPI_STATUS (AE_NOT_ACQUIRED);
-    }
-
-    if (AcpiGbl_GlobalLockPresent)
-    {
-        /* Allow any thread to release the lock */
-
-        ACPI_RELEASE_GLOBAL_LOCK (AcpiGbl_FACS, Pending);
-
-        /*
-         * If the pending bit was set, we must write GBL_RLS to the control
-         * register
-         */
-        if (Pending)
-        {
-            Status = AcpiWriteBitRegister (
-                        ACPI_BITREG_GLOBAL_LOCK_RELEASE, ACPI_ENABLE_EVENT);
-        }
-
-        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Released hardware Global Lock\n"));
-    }
-
-    AcpiGbl_GlobalLockAcquired = FALSE;
-
-    /* Release the local GL mutex */
-
-    AcpiOsReleaseMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex);
-    return_ACPI_STATUS (Status);
-}
-
-
 /******************************************************************************
  *
  * FUNCTION:    AcpiEvTerminate
@@ -696,7 +401,7 @@ AcpiEvTerminate (
             if (ACPI_FAILURE (Status))
             {
                 ACPI_ERROR ((AE_INFO,
-                    "Could not disable fixed event %d", (UINT32) i));
+                    "Could not disable fixed event %u", (UINT32) i));
             }
         }
 
@@ -737,4 +442,3 @@ AcpiEvTerminate (
     }
     return_VOID;
 }
-
index 2bdfb87..bd50228 100644 (file)
@@ -8,7 +8,7 @@
  *
  * 1. Copyright Notice
  *
- * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  * All rights reserved.
  *
  * 2. License
@@ -133,6 +133,10 @@ AcpiEvHasDefaultHandler (
     ACPI_NAMESPACE_NODE     *Node,
     ACPI_ADR_SPACE_TYPE     SpaceId);
 
+static void
+AcpiEvOrphanEcRegMethod (
+    void);
+
 static ACPI_STATUS
 AcpiEvRegRun (
     ACPI_HANDLE             ObjHandle,
@@ -334,6 +338,8 @@ AcpiEvInitializeOpRegions (
         }
     }
 
+    AcpiGbl_RegMethodsExecuted = TRUE;
+
     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
     return_ACPI_STATUS (Status);
 }
@@ -442,7 +448,7 @@ Cleanup1:
  *              RegionOffset        - Where in the region to read or write
  *              BitWidth            - Field width in bits (8, 16, 32, or 64)
  *              Value               - Pointer to in or out value, must be
- *                                    full 64-bit ACPI_INTEGER
+ *                                    a full 64-bit integer
  *
  * RETURN:      Status
  *
@@ -457,7 +463,7 @@ AcpiEvAddressSpaceDispatch (
     UINT32                  Function,
     UINT32                  RegionOffset,
     UINT32                  BitWidth,
-    ACPI_INTEGER            *Value)
+    UINT64                  *Value)
 {
     ACPI_STATUS             Status;
     ACPI_ADR_SPACE_HANDLER  Handler;
@@ -681,7 +687,7 @@ AcpiEvDetachRegion(
 
             /* Now stop region accesses by executing the _REG method */
 
-            Status = AcpiEvExecuteRegMethod (RegionObj, 0);
+            Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_DISCONNECT);