--- old/usr/src/uts/intel/io/acpica/dispatcher/dsmethod.c	ven. janv. 17 07:29:57 2014
+++ /dev/null	ven. janv. 17 07:29:53 2014
@@ -1,726 +0,0 @@
-/******************************************************************************
- *
- * Module Name: dsmethod - Parser/Interpreter interface - control method parsing
- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2011, Intel Corp.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    substantially similar to the "NO WARRANTY" disclaimer below
- *    ("Disclaimer") and any redistribution must be conditioned upon
- *    including a substantially similar Disclaimer requirement for further
- *    binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGES.
- */
-
-#define __DSMETHOD_C__
-
-#include "acpi.h"
-#include "accommon.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "acnamesp.h"
-#include "acdisasm.h"
-
-
-#define _COMPONENT          ACPI_DISPATCHER
-        ACPI_MODULE_NAME    ("dsmethod")
-
-/* Local prototypes */
-
-static ACPI_STATUS
-AcpiDsCreateMethodMutex (
-    ACPI_OPERAND_OBJECT     *MethodDesc);
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsMethodError
- *
- * PARAMETERS:  Status          - Execution status
- *              WalkState       - Current state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Called on method error. Invoke the global exception handler if
- *              present, dump the method data if the disassembler is configured
- *
- *              Note: Allows the exception handler to change the status code
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDsMethodError (
-    ACPI_STATUS             Status,
-    ACPI_WALK_STATE         *WalkState)
-{
-    ACPI_FUNCTION_ENTRY ();
-
-
-    /* Ignore AE_OK and control exception codes */
-
-    if (ACPI_SUCCESS (Status) ||
-        (Status & AE_CODE_CONTROL))
-    {
-        return (Status);
-    }
-
-    /* Invoke the global exception handler */
-
-    if (AcpiGbl_ExceptionHandler)
-    {
-        /* Exit the interpreter, allow handler to execute methods */
-
-        AcpiExExitInterpreter ();
-
-        /*
-         * Handler can map the exception code to anything it wants, including
-         * AE_OK, in which case the executing method will not be aborted.
-         */
-        Status = AcpiGbl_ExceptionHandler (Status,
-                    WalkState->MethodNode ?
-                        WalkState->MethodNode->Name.Integer : 0,
-                    WalkState->Opcode, WalkState->AmlOffset, NULL);
-        AcpiExEnterInterpreter ();
-    }
-
-    AcpiDsClearImplicitReturn (WalkState);
-
-#ifdef ACPI_DISASSEMBLER
-    if (ACPI_FAILURE (Status))
-    {
-        /* Display method locals/args if disassembler is present */
-
-        AcpiDmDumpMethodInfo (Status, WalkState, WalkState->Op);
-    }
-#endif
-
-    return (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsCreateMethodMutex
- *
- * PARAMETERS:  ObjDesc             - The method object
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Create a mutex object for a serialized control method
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-AcpiDsCreateMethodMutex (
-    ACPI_OPERAND_OBJECT     *MethodDesc)
-{
-    ACPI_OPERAND_OBJECT     *MutexDesc;
-    ACPI_STATUS             Status;
-
-
-    ACPI_FUNCTION_TRACE (DsCreateMethodMutex);
-
-
-    /* Create the new mutex object */
-
-    MutexDesc = AcpiUtCreateInternalObject (ACPI_TYPE_MUTEX);
-    if (!MutexDesc)
-    {
-        return_ACPI_STATUS (AE_NO_MEMORY);
-    }
-
-    /* Create the actual OS Mutex */
-
-    Status = AcpiOsCreateMutex (&MutexDesc->Mutex.OsMutex);
-    if (ACPI_FAILURE (Status))
-    {
-        return_ACPI_STATUS (Status);
-    }
-
-    MutexDesc->Mutex.SyncLevel = MethodDesc->Method.SyncLevel;
-    MethodDesc->Method.Mutex = MutexDesc;
-    return_ACPI_STATUS (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsBeginMethodExecution
- *
- * PARAMETERS:  MethodNode          - Node of the method
- *              ObjDesc             - The method object
- *              WalkState           - current state, NULL if not yet executing
- *                                    a method.
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Prepare a method for execution.  Parses the method if necessary,
- *              increments the thread count, and waits at the method semaphore
- *              for clearance to execute.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDsBeginMethodExecution (
-    ACPI_NAMESPACE_NODE     *MethodNode,
-    ACPI_OPERAND_OBJECT     *ObjDesc,
-    ACPI_WALK_STATE         *WalkState)
-{
-    ACPI_STATUS             Status = AE_OK;
-
-
-    ACPI_FUNCTION_TRACE_PTR (DsBeginMethodExecution, MethodNode);
-
-
-    if (!MethodNode)
-    {
-        return_ACPI_STATUS (AE_NULL_ENTRY);
-    }
-
-    /* Prevent wraparound of thread count */
-
-    if (ObjDesc->Method.ThreadCount == ACPI_UINT8_MAX)
-    {
-        ACPI_ERROR ((AE_INFO,
-            "Method reached maximum reentrancy limit (255)"));
-        return_ACPI_STATUS (AE_AML_METHOD_LIMIT);
-    }
-
-    /*
-     * If this method is serialized, we need to acquire the method mutex.
-     */
-    if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED)
-    {
-        /*
-         * Create a mutex for the method if it is defined to be Serialized
-         * and a mutex has not already been created. We defer the mutex creation
-         * until a method is actually executed, to minimize the object count
-         */
-        if (!ObjDesc->Method.Mutex)
-        {
-            Status = AcpiDsCreateMethodMutex (ObjDesc);
-            if (ACPI_FAILURE (Status))
-            {
-                return_ACPI_STATUS (Status);
-            }
-        }
-
-        /*
-         * The CurrentSyncLevel (per-thread) must be less than or equal to
-         * the sync level of the method. This mechanism provides some
-         * deadlock prevention
-         *
-         * Top-level method invocation has no walk state at this point
-         */
-        if (WalkState &&
-            (WalkState->Thread->CurrentSyncLevel > ObjDesc->Method.Mutex->Mutex.SyncLevel))
-        {
-            ACPI_ERROR ((AE_INFO,
-                "Cannot acquire Mutex for method [%4.4s], current SyncLevel is too large (%u)",
-                AcpiUtGetNodeName (MethodNode),
-                WalkState->Thread->CurrentSyncLevel));
-
-            return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
-        }
-
-        /*
-         * Obtain the method mutex if necessary. Do not acquire mutex for a
-         * recursive call.
-         */
-        if (!WalkState ||
-            !ObjDesc->Method.Mutex->Mutex.ThreadId ||
-            (WalkState->Thread->ThreadId != ObjDesc->Method.Mutex->Mutex.ThreadId))
-        {
-            /*
-             * Acquire the method mutex. This releases the interpreter if we
-             * block (and reacquires it before it returns)
-             */
-            Status = AcpiExSystemWaitMutex (ObjDesc->Method.Mutex->Mutex.OsMutex,
-                        ACPI_WAIT_FOREVER);
-            if (ACPI_FAILURE (Status))
-            {
-                return_ACPI_STATUS (Status);
-            }
-
-            /* Update the mutex and walk info and save the original SyncLevel */
-
-            if (WalkState)
-            {
-                ObjDesc->Method.Mutex->Mutex.OriginalSyncLevel =
-                    WalkState->Thread->CurrentSyncLevel;
-
-                ObjDesc->Method.Mutex->Mutex.ThreadId = WalkState->Thread->ThreadId;
-                WalkState->Thread->CurrentSyncLevel = ObjDesc->Method.SyncLevel;
-            }
-            else
-            {
-                ObjDesc->Method.Mutex->Mutex.OriginalSyncLevel =
-                    ObjDesc->Method.Mutex->Mutex.SyncLevel;
-            }
-        }
-
-        /* Always increase acquisition depth */
-
-        ObjDesc->Method.Mutex->Mutex.AcquisitionDepth++;
-    }
-
-    /*
-     * Allocate an Owner ID for this method, only if this is the first thread
-     * to begin concurrent execution. We only need one OwnerId, even if the
-     * method is invoked recursively.
-     */
-    if (!ObjDesc->Method.OwnerId)
-    {
-        Status = AcpiUtAllocateOwnerId (&ObjDesc->Method.OwnerId);
-        if (ACPI_FAILURE (Status))
-        {
-            goto Cleanup;
-        }
-    }
-
-    /*
-     * Increment the method parse tree thread count since it has been
-     * reentered one more time (even if it is the same thread)
-     */
-    ObjDesc->Method.ThreadCount++;
-    AcpiMethodCount++;
-    return_ACPI_STATUS (Status);
-
-
-Cleanup:
-    /* On error, must release the method mutex (if present) */
-
-    if (ObjDesc->Method.Mutex)
-    {
-        AcpiOsReleaseMutex (ObjDesc->Method.Mutex->Mutex.OsMutex);
-    }
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsCallControlMethod
- *
- * PARAMETERS:  Thread              - Info for this thread
- *              ThisWalkState       - Current walk state
- *              Op                  - Current Op to be walked
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Transfer execution to a called control method
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDsCallControlMethod (
-    ACPI_THREAD_STATE       *Thread,
-    ACPI_WALK_STATE         *ThisWalkState,
-    ACPI_PARSE_OBJECT       *Op)
-{
-    ACPI_STATUS             Status;
-    ACPI_NAMESPACE_NODE     *MethodNode;
-    ACPI_WALK_STATE         *NextWalkState = NULL;
-    ACPI_OPERAND_OBJECT     *ObjDesc;
-    ACPI_EVALUATE_INFO      *Info;
-    UINT32                  i;
-
-
-    ACPI_FUNCTION_TRACE_PTR (DsCallControlMethod, ThisWalkState);
-
-    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Calling method %p, currentstate=%p\n",
-        ThisWalkState->PrevOp, ThisWalkState));
-
-    /*
-     * Get the namespace entry for the control method we are about to call
-     */
-    MethodNode = ThisWalkState->MethodCallNode;
-    if (!MethodNode)
-    {
-        return_ACPI_STATUS (AE_NULL_ENTRY);
-    }
-
-    ObjDesc = AcpiNsGetAttachedObject (MethodNode);
-    if (!ObjDesc)
-    {
-        return_ACPI_STATUS (AE_NULL_OBJECT);
-    }
-
-    /* Init for new method, possibly wait on method mutex */
-
-    Status = AcpiDsBeginMethodExecution (MethodNode, ObjDesc,
-                ThisWalkState);
-    if (ACPI_FAILURE (Status))
-    {
-        return_ACPI_STATUS (Status);
-    }
-
-    /* Begin method parse/execution. Create a new walk state */
-
-    NextWalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwnerId,
-                        NULL, ObjDesc, Thread);
-    if (!NextWalkState)
-    {
-        Status = AE_NO_MEMORY;
-        goto Cleanup;
-    }
-
-    /*
-     * The resolved arguments were put on the previous walk state's operand
-     * stack. Operands on the previous walk state stack always
-     * start at index 0. Also, null terminate the list of arguments
-     */
-    ThisWalkState->Operands [ThisWalkState->NumOperands] = NULL;
-
-    /*
-     * Allocate and initialize the evaluation information block
-     * TBD: this is somewhat inefficient, should change interface to
-     * DsInitAmlWalk. For now, keeps this struct off the CPU stack
-     */
-    Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
-    if (!Info)
-    {
-        return_ACPI_STATUS (AE_NO_MEMORY);
-    }
-
-    Info->Parameters = &ThisWalkState->Operands[0];
-
-    Status = AcpiDsInitAmlWalk (NextWalkState, NULL, MethodNode,
-                ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength,
-                Info, ACPI_IMODE_EXECUTE);
-
-    ACPI_FREE (Info);
-    if (ACPI_FAILURE (Status))
-    {
-        goto Cleanup;
-    }
-
-    /*
-     * Delete the operands on the previous walkstate operand stack
-     * (they were copied to new objects)
-     */
-    for (i = 0; i < ObjDesc->Method.ParamCount; i++)
-    {
-        AcpiUtRemoveReference (ThisWalkState->Operands [i]);
-        ThisWalkState->Operands [i] = NULL;
-    }
-
-    /* Clear the operand stack */
-
-    ThisWalkState->NumOperands = 0;
-
-    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-        "**** Begin nested execution of [%4.4s] **** WalkState=%p\n",
-        MethodNode->Name.Ascii, NextWalkState));
-
-    /* Invoke an internal method if necessary */
-
-    if (ObjDesc->Method.InfoFlags & ACPI_METHOD_INTERNAL_ONLY)
-    {
-        Status = ObjDesc->Method.Dispatch.Implementation (NextWalkState);
-        if (Status == AE_OK)
-        {
-            Status = AE_CTRL_TERMINATE;
-        }
-    }
-
-    return_ACPI_STATUS (Status);
-
-
-Cleanup:
-
-    /* On error, we must terminate the method properly */
-
-    AcpiDsTerminateControlMethod (ObjDesc, NextWalkState);
-    if (NextWalkState)
-    {
-        AcpiDsDeleteWalkState (NextWalkState);
-    }
-
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsRestartControlMethod
- *
- * PARAMETERS:  WalkState           - State for preempted method (caller)
- *              ReturnDesc          - Return value from the called method
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Restart a method that was preempted by another (nested) method
- *              invocation.  Handle the return value (if any) from the callee.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDsRestartControlMethod (
-    ACPI_WALK_STATE         *WalkState,
-    ACPI_OPERAND_OBJECT     *ReturnDesc)
-{
-    ACPI_STATUS             Status;
-    int                     SameAsImplicitReturn;
-
-
-    ACPI_FUNCTION_TRACE_PTR (DsRestartControlMethod, WalkState);
-
-
-    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-        "****Restart [%4.4s] Op %p ReturnValueFromCallee %p\n",
-        AcpiUtGetNodeName (WalkState->MethodNode),
-        WalkState->MethodCallOp, ReturnDesc));
-
-    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-        "    ReturnFromThisMethodUsed?=%X ResStack %p Walk %p\n",
-        WalkState->ReturnUsed,
-        WalkState->Results, WalkState));
-
-    /* Did the called method return a value? */
-
-    if (ReturnDesc)
-    {
-        /* Is the implicit return object the same as the return desc? */
-
-        SameAsImplicitReturn = (WalkState->ImplicitReturnObj == ReturnDesc);
-
-        /* Are we actually going to use the return value? */
-
-        if (WalkState->ReturnUsed)
-        {
-            /* Save the return value from the previous method */
-
-            Status = AcpiDsResultPush (ReturnDesc, WalkState);
-            if (ACPI_FAILURE (Status))
-            {
-                AcpiUtRemoveReference (ReturnDesc);
-                return_ACPI_STATUS (Status);
-            }
-
-            /*
-             * Save as THIS method's return value in case it is returned
-             * immediately to yet another method
-             */
-            WalkState->ReturnDesc = ReturnDesc;
-        }
-
-        /*
-         * The following code is the optional support for the so-called
-         * "implicit return". Some AML code assumes that the last value of the
-         * method is "implicitly" returned to the caller, in the absence of an
-         * explicit return value.
-         *
-         * Just save the last result of the method as the return value.
-         *
-         * NOTE: this is optional because the ASL language does not actually
-         * support this behavior.
-         */
-        else if (!AcpiDsDoImplicitReturn (ReturnDesc, WalkState, FALSE) ||
-                 SameAsImplicitReturn)
-        {
-            /*
-             * Delete the return value if it will not be used by the
-             * calling method or remove one reference if the explicit return
-             * is the same as the implicit return value.
-             */
-            AcpiUtRemoveReference (ReturnDesc);
-        }
-    }
-
-    return_ACPI_STATUS (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiDsTerminateControlMethod
- *
- * PARAMETERS:  MethodDesc          - Method object
- *              WalkState           - State associated with the method
- *
- * RETURN:      None
- *
- * DESCRIPTION: Terminate a control method.  Delete everything that the method
- *              created, delete all locals and arguments, and delete the parse
- *              tree if requested.
- *
- * MUTEX:       Interpreter is locked
- *
- ******************************************************************************/
-
-void
-AcpiDsTerminateControlMethod (
-    ACPI_OPERAND_OBJECT     *MethodDesc,
-    ACPI_WALK_STATE         *WalkState)
-{
-
-    ACPI_FUNCTION_TRACE_PTR (DsTerminateControlMethod, WalkState);
-
-
-    /* MethodDesc is required, WalkState is optional */
-
-    if (!MethodDesc)
-    {
-        return_VOID;
-    }
-
-    if (WalkState)
-    {
-        /* Delete all arguments and locals */
-
-        AcpiDsMethodDataDeleteAll (WalkState);
-
-        /*
-         * If method is serialized, release the mutex and restore the
-         * current sync level for this thread
-         */
-        if (MethodDesc->Method.Mutex)
-        {
-            /* Acquisition Depth handles recursive calls */
-
-            MethodDesc->Method.Mutex->Mutex.AcquisitionDepth--;
-            if (!MethodDesc->Method.Mutex->Mutex.AcquisitionDepth)
-            {
-                WalkState->Thread->CurrentSyncLevel =
-                    MethodDesc->Method.Mutex->Mutex.OriginalSyncLevel;
-
-                AcpiOsReleaseMutex (MethodDesc->Method.Mutex->Mutex.OsMutex);
-                MethodDesc->Method.Mutex->Mutex.ThreadId = 0;
-            }
-        }
-
-        /*
-         * Delete any namespace objects created anywhere within the
-         * 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.InfoFlags & ACPI_METHOD_MODULE_LEVEL) &&
-             (MethodDesc->Method.ThreadCount == 1))
-        {
-            /* 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;
-            }
-        }
-    }
-
-    /* Decrement the thread count on the method */
-
-    if (MethodDesc->Method.ThreadCount)
-    {
-        MethodDesc->Method.ThreadCount--;
-    }
-    else
-    {
-        ACPI_ERROR ((AE_INFO,
-            "Invalid zero thread count in method"));
-    }
-
-    /* Are there any other threads currently executing this method? */
-
-    if (MethodDesc->Method.ThreadCount)
-    {
-        /*
-         * Additional threads. Do not release the OwnerId in this case,
-         * we immediately reuse it for the next thread executing this method
-         */
-        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-            "*** Completed execution of one thread, %u threads remaining\n",
-            MethodDesc->Method.ThreadCount));
-    }
-    else
-    {
-        /* This is the only executing thread for this method */
-
-        /*
-         * Support to dynamically change a method from NotSerialized to
-         * 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.
-         *
-         * This code is here because we must wait until the last thread exits
-         * before marking the method as serialized.
-         */
-        if (MethodDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED_PENDING)
-        {
-            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.InfoFlags & ACPI_METHOD_MODULE_LEVEL))
-        {
-            AcpiUtReleaseOwnerId (&MethodDesc->Method.OwnerId);
-        }
-    }
-
-    return_VOID;
-}
-
-
--- /dev/null	ven. janv. 17 07:29:53 2014
+++ new/usr/src/common/acpica/components/dispatcher/dsmethod.c	ven. janv. 17 07:29:57 2014
@@ -0,0 +1,726 @@
+/******************************************************************************
+ *
+ * Module Name: dsmethod - Parser/Interpreter interface - control method parsing
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#define __DSMETHOD_C__
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acdispat.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "acdisasm.h"
+
+
+#define _COMPONENT          ACPI_DISPATCHER
+        ACPI_MODULE_NAME    ("dsmethod")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDsCreateMethodMutex (
+    ACPI_OPERAND_OBJECT     *MethodDesc);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsMethodError
+ *
+ * PARAMETERS:  Status          - Execution status
+ *              WalkState       - Current state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Called on method error. Invoke the global exception handler if
+ *              present, dump the method data if the disassembler is configured
+ *
+ *              Note: Allows the exception handler to change the status code
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsMethodError (
+    ACPI_STATUS             Status,
+    ACPI_WALK_STATE         *WalkState)
+{
+    ACPI_FUNCTION_ENTRY ();
+
+
+    /* Ignore AE_OK and control exception codes */
+
+    if (ACPI_SUCCESS (Status) ||
+        (Status & AE_CODE_CONTROL))
+    {
+        return (Status);
+    }
+
+    /* Invoke the global exception handler */
+
+    if (AcpiGbl_ExceptionHandler)
+    {
+        /* Exit the interpreter, allow handler to execute methods */
+
+        AcpiExExitInterpreter ();
+
+        /*
+         * Handler can map the exception code to anything it wants, including
+         * AE_OK, in which case the executing method will not be aborted.
+         */
+        Status = AcpiGbl_ExceptionHandler (Status,
+                    WalkState->MethodNode ?
+                        WalkState->MethodNode->Name.Integer : 0,
+                    WalkState->Opcode, WalkState->AmlOffset, NULL);
+        AcpiExEnterInterpreter ();
+    }
+
+    AcpiDsClearImplicitReturn (WalkState);
+
+#ifdef ACPI_DISASSEMBLER
+    if (ACPI_FAILURE (Status))
+    {
+        /* Display method locals/args if disassembler is present */
+
+        AcpiDmDumpMethodInfo (Status, WalkState, WalkState->Op);
+    }
+#endif
+
+    return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsCreateMethodMutex
+ *
+ * PARAMETERS:  ObjDesc             - The method object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Create a mutex object for a serialized control method
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsCreateMethodMutex (
+    ACPI_OPERAND_OBJECT     *MethodDesc)
+{
+    ACPI_OPERAND_OBJECT     *MutexDesc;
+    ACPI_STATUS             Status;
+
+
+    ACPI_FUNCTION_TRACE (DsCreateMethodMutex);
+
+
+    /* Create the new mutex object */
+
+    MutexDesc = AcpiUtCreateInternalObject (ACPI_TYPE_MUTEX);
+    if (!MutexDesc)
+    {
+        return_ACPI_STATUS (AE_NO_MEMORY);
+    }
+
+    /* Create the actual OS Mutex */
+
+    Status = AcpiOsCreateMutex (&MutexDesc->Mutex.OsMutex);
+    if (ACPI_FAILURE (Status))
+    {
+        AcpiUtDeleteObjectDesc (MutexDesc);
+        return_ACPI_STATUS (Status);
+    }
+
+    MutexDesc->Mutex.SyncLevel = MethodDesc->Method.SyncLevel;
+    MethodDesc->Method.Mutex = MutexDesc;
+    return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsBeginMethodExecution
+ *
+ * PARAMETERS:  MethodNode          - Node of the method
+ *              ObjDesc             - The method object
+ *              WalkState           - current state, NULL if not yet executing
+ *                                    a method.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Prepare a method for execution. Parses the method if necessary,
+ *              increments the thread count, and waits at the method semaphore
+ *              for clearance to execute.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsBeginMethodExecution (
+    ACPI_NAMESPACE_NODE     *MethodNode,
+    ACPI_OPERAND_OBJECT     *ObjDesc,
+    ACPI_WALK_STATE         *WalkState)
+{
+    ACPI_STATUS             Status = AE_OK;
+
+
+    ACPI_FUNCTION_TRACE_PTR (DsBeginMethodExecution, MethodNode);
+
+
+    if (!MethodNode)
+    {
+        return_ACPI_STATUS (AE_NULL_ENTRY);
+    }
+
+    /* Prevent wraparound of thread count */
+
+    if (ObjDesc->Method.ThreadCount == ACPI_UINT8_MAX)
+    {
+        ACPI_ERROR ((AE_INFO,
+            "Method reached maximum reentrancy limit (255)"));
+        return_ACPI_STATUS (AE_AML_METHOD_LIMIT);
+    }
+
+    /*
+     * If this method is serialized, we need to acquire the method mutex.
+     */
+    if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED)
+    {
+        /*
+         * Create a mutex for the method if it is defined to be Serialized
+         * and a mutex has not already been created. We defer the mutex creation
+         * until a method is actually executed, to minimize the object count
+         */
+        if (!ObjDesc->Method.Mutex)
+        {
+            Status = AcpiDsCreateMethodMutex (ObjDesc);
+            if (ACPI_FAILURE (Status))
+            {
+                return_ACPI_STATUS (Status);
+            }
+        }
+
+        /*
+         * The CurrentSyncLevel (per-thread) must be less than or equal to
+         * the sync level of the method. This mechanism provides some
+         * deadlock prevention
+         *
+         * Top-level method invocation has no walk state at this point
+         */
+        if (WalkState &&
+            (WalkState->Thread->CurrentSyncLevel > ObjDesc->Method.Mutex->Mutex.SyncLevel))
+        {
+            ACPI_ERROR ((AE_INFO,
+                "Cannot acquire Mutex for method [%4.4s], current SyncLevel is too large (%u)",
+                AcpiUtGetNodeName (MethodNode),
+                WalkState->Thread->CurrentSyncLevel));
+
+            return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
+        }
+
+        /*
+         * Obtain the method mutex if necessary. Do not acquire mutex for a
+         * recursive call.
+         */
+        if (!WalkState ||
+            !ObjDesc->Method.Mutex->Mutex.ThreadId ||
+            (WalkState->Thread->ThreadId != ObjDesc->Method.Mutex->Mutex.ThreadId))
+        {
+            /*
+             * Acquire the method mutex. This releases the interpreter if we
+             * block (and reacquires it before it returns)
+             */
+            Status = AcpiExSystemWaitMutex (ObjDesc->Method.Mutex->Mutex.OsMutex,
+                        ACPI_WAIT_FOREVER);
+            if (ACPI_FAILURE (Status))
+            {
+                return_ACPI_STATUS (Status);
+            }
+
+            /* Update the mutex and walk info and save the original SyncLevel */
+
+            if (WalkState)
+            {
+                ObjDesc->Method.Mutex->Mutex.OriginalSyncLevel =
+                    WalkState->Thread->CurrentSyncLevel;
+
+                ObjDesc->Method.Mutex->Mutex.ThreadId = WalkState->Thread->ThreadId;
+                WalkState->Thread->CurrentSyncLevel = ObjDesc->Method.SyncLevel;
+            }
+            else
+            {
+                ObjDesc->Method.Mutex->Mutex.OriginalSyncLevel =
+                    ObjDesc->Method.Mutex->Mutex.SyncLevel;
+            }
+        }
+
+        /* Always increase acquisition depth */
+
+        ObjDesc->Method.Mutex->Mutex.AcquisitionDepth++;
+    }
+
+    /*
+     * Allocate an Owner ID for this method, only if this is the first thread
+     * to begin concurrent execution. We only need one OwnerId, even if the
+     * method is invoked recursively.
+     */
+    if (!ObjDesc->Method.OwnerId)
+    {
+        Status = AcpiUtAllocateOwnerId (&ObjDesc->Method.OwnerId);
+        if (ACPI_FAILURE (Status))
+        {
+            goto Cleanup;
+        }
+    }
+
+    /*
+     * Increment the method parse tree thread count since it has been
+     * reentered one more time (even if it is the same thread)
+     */
+    ObjDesc->Method.ThreadCount++;
+    AcpiMethodCount++;
+    return_ACPI_STATUS (Status);
+
+
+Cleanup:
+    /* On error, must release the method mutex (if present) */
+
+    if (ObjDesc->Method.Mutex)
+    {
+        AcpiOsReleaseMutex (ObjDesc->Method.Mutex->Mutex.OsMutex);
+    }
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsCallControlMethod
+ *
+ * PARAMETERS:  Thread              - Info for this thread
+ *              ThisWalkState       - Current walk state
+ *              Op                  - Current Op to be walked
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Transfer execution to a called control method
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsCallControlMethod (
+    ACPI_THREAD_STATE       *Thread,
+    ACPI_WALK_STATE         *ThisWalkState,
+    ACPI_PARSE_OBJECT       *Op)
+{
+    ACPI_STATUS             Status;
+    ACPI_NAMESPACE_NODE     *MethodNode;
+    ACPI_WALK_STATE         *NextWalkState = NULL;
+    ACPI_OPERAND_OBJECT     *ObjDesc;
+    ACPI_EVALUATE_INFO      *Info;
+    UINT32                  i;
+
+
+    ACPI_FUNCTION_TRACE_PTR (DsCallControlMethod, ThisWalkState);
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Calling method %p, currentstate=%p\n",
+        ThisWalkState->PrevOp, ThisWalkState));
+
+    /*
+     * Get the namespace entry for the control method we are about to call
+     */
+    MethodNode = ThisWalkState->MethodCallNode;
+    if (!MethodNode)
+    {
+        return_ACPI_STATUS (AE_NULL_ENTRY);
+    }
+
+    ObjDesc = AcpiNsGetAttachedObject (MethodNode);
+    if (!ObjDesc)
+    {
+        return_ACPI_STATUS (AE_NULL_OBJECT);
+    }
+
+    /* Init for new method, possibly wait on method mutex */
+
+    Status = AcpiDsBeginMethodExecution (MethodNode, ObjDesc,
+                ThisWalkState);
+    if (ACPI_FAILURE (Status))
+    {
+        return_ACPI_STATUS (Status);
+    }
+
+    /* Begin method parse/execution. Create a new walk state */
+
+    NextWalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwnerId,
+                        NULL, ObjDesc, Thread);
+    if (!NextWalkState)
+    {
+        Status = AE_NO_MEMORY;
+        goto Cleanup;
+    }
+
+    /*
+     * The resolved arguments were put on the previous walk state's operand
+     * stack. Operands on the previous walk state stack always
+     * start at index 0. Also, null terminate the list of arguments
+     */
+    ThisWalkState->Operands [ThisWalkState->NumOperands] = NULL;
+
+    /*
+     * Allocate and initialize the evaluation information block
+     * TBD: this is somewhat inefficient, should change interface to
+     * DsInitAmlWalk. For now, keeps this struct off the CPU stack
+     */
+    Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
+    if (!Info)
+    {
+        Status = AE_NO_MEMORY;
+        goto Cleanup;
+    }
+
+    Info->Parameters = &ThisWalkState->Operands[0];
+
+    Status = AcpiDsInitAmlWalk (NextWalkState, NULL, MethodNode,
+                ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength,
+                Info, ACPI_IMODE_EXECUTE);
+
+    ACPI_FREE (Info);
+    if (ACPI_FAILURE (Status))
+    {
+        goto Cleanup;
+    }
+
+    /*
+     * Delete the operands on the previous walkstate operand stack
+     * (they were copied to new objects)
+     */
+    for (i = 0; i < ObjDesc->Method.ParamCount; i++)
+    {
+        AcpiUtRemoveReference (ThisWalkState->Operands [i]);
+        ThisWalkState->Operands [i] = NULL;
+    }
+
+    /* Clear the operand stack */
+
+    ThisWalkState->NumOperands = 0;
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+        "**** Begin nested execution of [%4.4s] **** WalkState=%p\n",
+        MethodNode->Name.Ascii, NextWalkState));
+
+    /* Invoke an internal method if necessary */
+
+    if (ObjDesc->Method.InfoFlags & ACPI_METHOD_INTERNAL_ONLY)
+    {
+        Status = ObjDesc->Method.Dispatch.Implementation (NextWalkState);
+        if (Status == AE_OK)
+        {
+            Status = AE_CTRL_TERMINATE;
+        }
+    }
+
+    return_ACPI_STATUS (Status);
+
+
+Cleanup:
+
+    /* On error, we must terminate the method properly */
+
+    AcpiDsTerminateControlMethod (ObjDesc, NextWalkState);
+    if (NextWalkState)
+    {
+        AcpiDsDeleteWalkState (NextWalkState);
+    }
+
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsRestartControlMethod
+ *
+ * PARAMETERS:  WalkState           - State for preempted method (caller)
+ *              ReturnDesc          - Return value from the called method
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Restart a method that was preempted by another (nested) method
+ *              invocation. Handle the return value (if any) from the callee.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsRestartControlMethod (
+    ACPI_WALK_STATE         *WalkState,
+    ACPI_OPERAND_OBJECT     *ReturnDesc)
+{
+    ACPI_STATUS             Status;
+    int                     SameAsImplicitReturn;
+
+
+    ACPI_FUNCTION_TRACE_PTR (DsRestartControlMethod, WalkState);
+
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+        "****Restart [%4.4s] Op %p ReturnValueFromCallee %p\n",
+        AcpiUtGetNodeName (WalkState->MethodNode),
+        WalkState->MethodCallOp, ReturnDesc));
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+        "    ReturnFromThisMethodUsed?=%X ResStack %p Walk %p\n",
+        WalkState->ReturnUsed,
+        WalkState->Results, WalkState));
+
+    /* Did the called method return a value? */
+
+    if (ReturnDesc)
+    {
+        /* Is the implicit return object the same as the return desc? */
+
+        SameAsImplicitReturn = (WalkState->ImplicitReturnObj == ReturnDesc);
+
+        /* Are we actually going to use the return value? */
+
+        if (WalkState->ReturnUsed)
+        {
+            /* Save the return value from the previous method */
+
+            Status = AcpiDsResultPush (ReturnDesc, WalkState);
+            if (ACPI_FAILURE (Status))
+            {
+                AcpiUtRemoveReference (ReturnDesc);
+                return_ACPI_STATUS (Status);
+            }
+
+            /*
+             * Save as THIS method's return value in case it is returned
+             * immediately to yet another method
+             */
+            WalkState->ReturnDesc = ReturnDesc;
+        }
+
+        /*
+         * The following code is the optional support for the so-called
+         * "implicit return". Some AML code assumes that the last value of the
+         * method is "implicitly" returned to the caller, in the absence of an
+         * explicit return value.
+         *
+         * Just save the last result of the method as the return value.
+         *
+         * NOTE: this is optional because the ASL language does not actually
+         * support this behavior.
+         */
+        else if (!AcpiDsDoImplicitReturn (ReturnDesc, WalkState, FALSE) ||
+                 SameAsImplicitReturn)
+        {
+            /*
+             * Delete the return value if it will not be used by the
+             * calling method or remove one reference if the explicit return
+             * is the same as the implicit return value.
+             */
+            AcpiUtRemoveReference (ReturnDesc);
+        }
+    }
+
+    return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiDsTerminateControlMethod
+ *
+ * PARAMETERS:  MethodDesc          - Method object
+ *              WalkState           - State associated with the method
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Terminate a control method. Delete everything that the method
+ *              created, delete all locals and arguments, and delete the parse
+ *              tree if requested.
+ *
+ * MUTEX:       Interpreter is locked
+ *
+ ******************************************************************************/
+
+void
+AcpiDsTerminateControlMethod (
+    ACPI_OPERAND_OBJECT     *MethodDesc,
+    ACPI_WALK_STATE         *WalkState)
+{
+
+    ACPI_FUNCTION_TRACE_PTR (DsTerminateControlMethod, WalkState);
+
+
+    /* MethodDesc is required, WalkState is optional */
+
+    if (!MethodDesc)
+    {
+        return_VOID;
+    }
+
+    if (WalkState)
+    {
+        /* Delete all arguments and locals */
+
+        AcpiDsMethodDataDeleteAll (WalkState);
+
+        /*
+         * If method is serialized, release the mutex and restore the
+         * current sync level for this thread
+         */
+        if (MethodDesc->Method.Mutex)
+        {
+            /* Acquisition Depth handles recursive calls */
+
+            MethodDesc->Method.Mutex->Mutex.AcquisitionDepth--;
+            if (!MethodDesc->Method.Mutex->Mutex.AcquisitionDepth)
+            {
+                WalkState->Thread->CurrentSyncLevel =
+                    MethodDesc->Method.Mutex->Mutex.OriginalSyncLevel;
+
+                AcpiOsReleaseMutex (MethodDesc->Method.Mutex->Mutex.OsMutex);
+                MethodDesc->Method.Mutex->Mutex.ThreadId = 0;
+            }
+        }
+
+        /*
+         * Delete any namespace objects created anywhere within the
+         * 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.InfoFlags & ACPI_METHOD_MODULE_LEVEL) &&
+             (MethodDesc->Method.ThreadCount == 1))
+        {
+            /* 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;
+            }
+        }
+    }
+
+    /* Decrement the thread count on the method */
+
+    if (MethodDesc->Method.ThreadCount)
+    {
+        MethodDesc->Method.ThreadCount--;
+    }
+    else
+    {
+        ACPI_ERROR ((AE_INFO,
+            "Invalid zero thread count in method"));
+    }
+
+    /* Are there any other threads currently executing this method? */
+
+    if (MethodDesc->Method.ThreadCount)
+    {
+        /*
+         * Additional threads. Do not release the OwnerId in this case,
+         * we immediately reuse it for the next thread executing this method
+         */
+        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+            "*** Completed execution of one thread, %u threads remaining\n",
+            MethodDesc->Method.ThreadCount));
+    }
+    else
+    {
+        /* This is the only executing thread for this method */
+
+        /*
+         * Support to dynamically change a method from NotSerialized to
+         * 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.
+         *
+         * This code is here because we must wait until the last thread exits
+         * before marking the method as serialized.
+         */
+        if (MethodDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED_PENDING)
+        {
+            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.InfoFlags & ACPI_METHOD_MODULE_LEVEL))
+        {
+            AcpiUtReleaseOwnerId (&MethodDesc->Method.OwnerId);
+        }
+    }
+
+    return_VOID;
+}
