--- old/usr/src/uts/intel/io/acpica/executer/exmutex.c	jeu. déc. 26 13:49:05 2013
+++ /dev/null	jeu. déc. 26 13:48:59 2013
@@ -1,554 +0,0 @@
-
-/******************************************************************************
- *
- * Module Name: exmutex - ASL Mutex Acquire/Release functions
- *
- *****************************************************************************/
-
-/*
- * 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 __EXMUTEX_C__
-
-#include "acpi.h"
-#include "accommon.h"
-#include "acinterp.h"
-#include "acevents.h"
-
-#define _COMPONENT          ACPI_EXECUTER
-        ACPI_MODULE_NAME    ("exmutex")
-
-/* Local prototypes */
-
-static void
-AcpiExLinkMutex (
-    ACPI_OPERAND_OBJECT     *ObjDesc,
-    ACPI_THREAD_STATE       *Thread);
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiExUnlinkMutex
- *
- * PARAMETERS:  ObjDesc             - The mutex to be unlinked
- *
- * RETURN:      None
- *
- * DESCRIPTION: Remove a mutex from the "AcquiredMutex" list
- *
- ******************************************************************************/
-
-void
-AcpiExUnlinkMutex (
-    ACPI_OPERAND_OBJECT     *ObjDesc)
-{
-    ACPI_THREAD_STATE       *Thread = ObjDesc->Mutex.OwnerThread;
-
-
-    if (!Thread)
-    {
-        return;
-    }
-
-    /* Doubly linked list */
-
-    if (ObjDesc->Mutex.Next)
-    {
-        (ObjDesc->Mutex.Next)->Mutex.Prev = ObjDesc->Mutex.Prev;
-    }
-
-    if (ObjDesc->Mutex.Prev)
-    {
-        (ObjDesc->Mutex.Prev)->Mutex.Next = ObjDesc->Mutex.Next;
-
-        /*
-         * Migrate the previous sync level associated with this mutex to
-         * the previous mutex on the list so that it may be preserved.
-         * This handles the case where several mutexes have been acquired
-         * at the same level, but are not released in opposite order.
-         */
-        (ObjDesc->Mutex.Prev)->Mutex.OriginalSyncLevel =
-            ObjDesc->Mutex.OriginalSyncLevel;
-    }
-    else
-    {
-        Thread->AcquiredMutexList = ObjDesc->Mutex.Next;
-    }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiExLinkMutex
- *
- * PARAMETERS:  ObjDesc             - The mutex to be linked
- *              Thread              - Current executing thread object
- *
- * RETURN:      None
- *
- * DESCRIPTION: Add a mutex to the "AcquiredMutex" list for this walk
- *
- ******************************************************************************/
-
-static void
-AcpiExLinkMutex (
-    ACPI_OPERAND_OBJECT     *ObjDesc,
-    ACPI_THREAD_STATE       *Thread)
-{
-    ACPI_OPERAND_OBJECT     *ListHead;
-
-
-    ListHead = Thread->AcquiredMutexList;
-
-    /* This object will be the first object in the list */
-
-    ObjDesc->Mutex.Prev = NULL;
-    ObjDesc->Mutex.Next = ListHead;
-
-    /* Update old first object to point back to this object */
-
-    if (ListHead)
-    {
-        ListHead->Mutex.Prev = ObjDesc;
-    }
-
-    /* Update list head */
-
-    Thread->AcquiredMutexList = ObjDesc;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiExAcquireMutexObject
- *
- * PARAMETERS:  Timeout             - Timeout in milliseconds
- *              ObjDesc             - Mutex object
- *              ThreadId            - Current thread state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Acquire an AML mutex, low-level interface. Provides a common
- *              path that supports multiple acquires by the same thread.
- *
- * MUTEX:       Interpreter must be locked
- *
- * NOTE: This interface is called from three places:
- * 1) From AcpiExAcquireMutex, via an AML Acquire() operator
- * 2) From AcpiExAcquireGlobalLock when an AML Field access requires the
- *    global lock
- * 3) From the external interface, AcpiAcquireGlobalLock
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiExAcquireMutexObject (
-    UINT16                  Timeout,
-    ACPI_OPERAND_OBJECT     *ObjDesc,
-    ACPI_THREAD_ID          ThreadId)
-{
-    ACPI_STATUS             Status;
-
-
-    ACPI_FUNCTION_TRACE_PTR (ExAcquireMutexObject, ObjDesc);
-
-
-    if (!ObjDesc)
-    {
-        return_ACPI_STATUS (AE_BAD_PARAMETER);
-    }
-
-    /* Support for multiple acquires by the owning thread */
-
-    if (ObjDesc->Mutex.ThreadId == ThreadId)
-    {
-        /*
-         * The mutex is already owned by this thread, just increment the
-         * acquisition depth
-         */
-        ObjDesc->Mutex.AcquisitionDepth++;
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    /* Acquire the mutex, wait if necessary. Special case for Global Lock */
-
-    if (ObjDesc == AcpiGbl_GlobalLockMutex)
-    {
-        Status = AcpiEvAcquireGlobalLock (Timeout);
-    }
-    else
-    {
-        Status = AcpiExSystemWaitMutex (ObjDesc->Mutex.OsMutex,
-                    Timeout);
-    }
-
-    if (ACPI_FAILURE (Status))
-    {
-        /* Includes failure from a timeout on TimeDesc */
-
-        return_ACPI_STATUS (Status);
-    }
-
-    /* Acquired the mutex: update mutex object */
-
-    ObjDesc->Mutex.ThreadId = ThreadId;
-    ObjDesc->Mutex.AcquisitionDepth = 1;
-    ObjDesc->Mutex.OriginalSyncLevel = 0;
-    ObjDesc->Mutex.OwnerThread = NULL;      /* Used only for AML Acquire() */
-
-    return_ACPI_STATUS (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiExAcquireMutex
- *
- * PARAMETERS:  TimeDesc            - Timeout integer
- *              ObjDesc             - Mutex object
- *              WalkState           - Current method execution state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Acquire an AML mutex
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiExAcquireMutex (
-    ACPI_OPERAND_OBJECT     *TimeDesc,
-    ACPI_OPERAND_OBJECT     *ObjDesc,
-    ACPI_WALK_STATE         *WalkState)
-{
-    ACPI_STATUS             Status;
-
-
-    ACPI_FUNCTION_TRACE_PTR (ExAcquireMutex, ObjDesc);
-
-
-    if (!ObjDesc)
-    {
-        return_ACPI_STATUS (AE_BAD_PARAMETER);
-    }
-
-    /* Must have a valid thread state struct */
-
-    if (!WalkState->Thread)
-    {
-        ACPI_ERROR ((AE_INFO,
-            "Cannot acquire Mutex [%4.4s], null thread info",
-            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
-        return_ACPI_STATUS (AE_AML_INTERNAL);
-    }
-
-    /*
-     * Current sync level must be less than or equal to the sync level of the
-     * mutex. This mechanism provides some deadlock prevention
-     */
-    if (WalkState->Thread->CurrentSyncLevel > ObjDesc->Mutex.SyncLevel)
-    {
-        ACPI_ERROR ((AE_INFO,
-            "Cannot acquire Mutex [%4.4s], current SyncLevel is too large (%u)",
-            AcpiUtGetNodeName (ObjDesc->Mutex.Node),
-            WalkState->Thread->CurrentSyncLevel));
-        return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
-    }
-
-    Status = AcpiExAcquireMutexObject ((UINT16) TimeDesc->Integer.Value,
-                ObjDesc, WalkState->Thread->ThreadId);
-    if (ACPI_SUCCESS (Status) && ObjDesc->Mutex.AcquisitionDepth == 1)
-    {
-        /* Save Thread object, original/current sync levels */
-
-        ObjDesc->Mutex.OwnerThread = WalkState->Thread;
-        ObjDesc->Mutex.OriginalSyncLevel = WalkState->Thread->CurrentSyncLevel;
-        WalkState->Thread->CurrentSyncLevel = ObjDesc->Mutex.SyncLevel;
-
-        /* Link the mutex to the current thread for force-unlock at method exit */
-
-        AcpiExLinkMutex (ObjDesc, WalkState->Thread);
-    }
-
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiExReleaseMutexObject
- *
- * PARAMETERS:  ObjDesc             - The object descriptor for this op
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Release a previously acquired Mutex, low level interface.
- *              Provides a common path that supports multiple releases (after
- *              previous multiple acquires) by the same thread.
- *
- * MUTEX:       Interpreter must be locked
- *
- * NOTE: This interface is called from three places:
- * 1) From AcpiExReleaseMutex, via an AML Acquire() operator
- * 2) From AcpiExReleaseGlobalLock when an AML Field access requires the
- *    global lock
- * 3) From the external interface, AcpiReleaseGlobalLock
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiExReleaseMutexObject (
-    ACPI_OPERAND_OBJECT     *ObjDesc)
-{
-    ACPI_STATUS             Status = AE_OK;
-
-
-    ACPI_FUNCTION_TRACE (ExReleaseMutexObject);
-
-
-    if (ObjDesc->Mutex.AcquisitionDepth == 0)
-    {
-        return (AE_NOT_ACQUIRED);
-    }
-
-    /* Match multiple Acquires with multiple Releases */
-
-    ObjDesc->Mutex.AcquisitionDepth--;
-    if (ObjDesc->Mutex.AcquisitionDepth != 0)
-    {
-        /* Just decrement the depth and return */
-
-        return_ACPI_STATUS (AE_OK);
-    }
-
-    if (ObjDesc->Mutex.OwnerThread)
-    {
-        /* Unlink the mutex from the owner's list */
-
-        AcpiExUnlinkMutex (ObjDesc);
-        ObjDesc->Mutex.OwnerThread = NULL;
-    }
-
-    /* Release the mutex, special case for Global Lock */
-
-    if (ObjDesc == AcpiGbl_GlobalLockMutex)
-    {
-        Status = AcpiEvReleaseGlobalLock ();
-    }
-    else
-    {
-        AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);
-    }
-
-    /* Clear mutex info */
-
-    ObjDesc->Mutex.ThreadId = 0;
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiExReleaseMutex
- *
- * PARAMETERS:  ObjDesc             - The object descriptor for this op
- *              WalkState           - Current method execution state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Release a previously acquired Mutex.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiExReleaseMutex (
-    ACPI_OPERAND_OBJECT     *ObjDesc,
-    ACPI_WALK_STATE         *WalkState)
-{
-    ACPI_STATUS             Status = AE_OK;
-    UINT8                   PreviousSyncLevel;
-    ACPI_THREAD_STATE       *OwnerThread;
-
-
-    ACPI_FUNCTION_TRACE (ExReleaseMutex);
-
-
-    if (!ObjDesc)
-    {
-        return_ACPI_STATUS (AE_BAD_PARAMETER);
-    }
-
-    OwnerThread = ObjDesc->Mutex.OwnerThread;
-
-    /* The mutex must have been previously acquired in order to release it */
-
-    if (!OwnerThread)
-    {
-        ACPI_ERROR ((AE_INFO,
-            "Cannot release Mutex [%4.4s], not acquired",
-            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
-        return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
-    }
-
-    /* Must have a valid thread ID */
-
-    if (!WalkState->Thread)
-    {
-        ACPI_ERROR ((AE_INFO,
-            "Cannot release Mutex [%4.4s], null thread info",
-            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
-        return_ACPI_STATUS (AE_AML_INTERNAL);
-    }
-
-    /*
-     * The Mutex is owned, but this thread must be the owner.
-     * Special case for Global Lock, any thread can release
-     */
-    if ((OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
-        (ObjDesc != AcpiGbl_GlobalLockMutex))
-    {
-        ACPI_ERROR ((AE_INFO,
-            "Thread %u cannot release Mutex [%4.4s] acquired by thread %u",
-            (UINT32) WalkState->Thread->ThreadId,
-            AcpiUtGetNodeName (ObjDesc->Mutex.Node),
-            (UINT32) OwnerThread->ThreadId));
-        return_ACPI_STATUS (AE_AML_NOT_OWNER);
-    }
-
-    /*
-     * The sync level of the mutex must be equal to the current sync level. In
-     * other words, the current level means that at least one mutex at that
-     * level is currently being held. Attempting to release a mutex of a
-     * different level can only mean that the mutex ordering rule is being
-     * violated. This behavior is clarified in ACPI 4.0 specification.
-     */
-    if (ObjDesc->Mutex.SyncLevel != OwnerThread->CurrentSyncLevel)
-    {
-        ACPI_ERROR ((AE_INFO,
-            "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %u current %u",
-            AcpiUtGetNodeName (ObjDesc->Mutex.Node),
-            ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel));
-        return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
-    }
-
-    /*
-     * Get the previous SyncLevel from the head of the acquired mutex list.
-     * This handles the case where several mutexes at the same level have been
-     * acquired, but are not released in reverse order.
-     */
-    PreviousSyncLevel =
-        OwnerThread->AcquiredMutexList->Mutex.OriginalSyncLevel;
-
-    Status = AcpiExReleaseMutexObject (ObjDesc);
-    if (ACPI_FAILURE (Status))
-    {
-        return_ACPI_STATUS (Status);
-    }
-
-    if (ObjDesc->Mutex.AcquisitionDepth == 0)
-    {
-        /* Restore the previous SyncLevel */
-
-        OwnerThread->CurrentSyncLevel = PreviousSyncLevel;
-    }
-
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiExReleaseAllMutexes
- *
- * PARAMETERS:  Thread              - Current executing thread object
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Release all mutexes held by this thread
- *
- * NOTE: This function is called as the thread is exiting the interpreter.
- * Mutexes are not released when an individual control method is exited, but
- * only when the parent thread actually exits the interpreter. This allows one
- * method to acquire a mutex, and a different method to release it, as long as
- * this is performed underneath a single parent control method.
- *
- ******************************************************************************/
-
-void
-AcpiExReleaseAllMutexes (
-    ACPI_THREAD_STATE       *Thread)
-{
-    ACPI_OPERAND_OBJECT     *Next = Thread->AcquiredMutexList;
-    ACPI_OPERAND_OBJECT     *ObjDesc;
-
-
-    ACPI_FUNCTION_ENTRY ();
-
-
-    /* Traverse the list of owned mutexes, releasing each one */
-
-    while (Next)
-    {
-        ObjDesc = Next;
-        Next = ObjDesc->Mutex.Next;
-
-        ObjDesc->Mutex.Prev = NULL;
-        ObjDesc->Mutex.Next = NULL;
-        ObjDesc->Mutex.AcquisitionDepth = 0;
-
-        /* Release the mutex, special case for Global Lock */
-
-        if (ObjDesc == AcpiGbl_GlobalLockMutex)
-        {
-            /* Ignore errors */
-
-            (void) AcpiEvReleaseGlobalLock ();
-        }
-        else
-        {
-            AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);
-        }
-
-        /* Mark mutex unowned */
-
-        ObjDesc->Mutex.OwnerThread = NULL;
-        ObjDesc->Mutex.ThreadId = 0;
-
-        /* Update Thread SyncLevel (Last mutex is the important one) */
-
-        Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel;
-    }
-}
--- /dev/null	jeu. déc. 26 13:48:59 2013
+++ new/usr/src/common/acpica/components/executer/exmutex.c	jeu. déc. 26 13:49:05 2013
@@ -0,0 +1,556 @@
+/******************************************************************************
+ *
+ * Module Name: exmutex - ASL Mutex Acquire/Release functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2013, 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 __EXMUTEX_C__
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acinterp.h"
+#include "acevents.h"
+
+#define _COMPONENT          ACPI_EXECUTER
+        ACPI_MODULE_NAME    ("exmutex")
+
+/* Local prototypes */
+
+static void
+AcpiExLinkMutex (
+    ACPI_OPERAND_OBJECT     *ObjDesc,
+    ACPI_THREAD_STATE       *Thread);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiExUnlinkMutex
+ *
+ * PARAMETERS:  ObjDesc             - The mutex to be unlinked
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Remove a mutex from the "AcquiredMutex" list
+ *
+ ******************************************************************************/
+
+void
+AcpiExUnlinkMutex (
+    ACPI_OPERAND_OBJECT     *ObjDesc)
+{
+    ACPI_THREAD_STATE       *Thread = ObjDesc->Mutex.OwnerThread;
+
+
+    if (!Thread)
+    {
+        return;
+    }
+
+    /* Doubly linked list */
+
+    if (ObjDesc->Mutex.Next)
+    {
+        (ObjDesc->Mutex.Next)->Mutex.Prev = ObjDesc->Mutex.Prev;
+    }
+
+    if (ObjDesc->Mutex.Prev)
+    {
+        (ObjDesc->Mutex.Prev)->Mutex.Next = ObjDesc->Mutex.Next;
+
+        /*
+         * Migrate the previous sync level associated with this mutex to
+         * the previous mutex on the list so that it may be preserved.
+         * This handles the case where several mutexes have been acquired
+         * at the same level, but are not released in opposite order.
+         */
+        (ObjDesc->Mutex.Prev)->Mutex.OriginalSyncLevel =
+            ObjDesc->Mutex.OriginalSyncLevel;
+    }
+    else
+    {
+        Thread->AcquiredMutexList = ObjDesc->Mutex.Next;
+    }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiExLinkMutex
+ *
+ * PARAMETERS:  ObjDesc             - The mutex to be linked
+ *              Thread              - Current executing thread object
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Add a mutex to the "AcquiredMutex" list for this walk
+ *
+ ******************************************************************************/
+
+static void
+AcpiExLinkMutex (
+    ACPI_OPERAND_OBJECT     *ObjDesc,
+    ACPI_THREAD_STATE       *Thread)
+{
+    ACPI_OPERAND_OBJECT     *ListHead;
+
+
+    ListHead = Thread->AcquiredMutexList;
+
+    /* This object will be the first object in the list */
+
+    ObjDesc->Mutex.Prev = NULL;
+    ObjDesc->Mutex.Next = ListHead;
+
+    /* Update old first object to point back to this object */
+
+    if (ListHead)
+    {
+        ListHead->Mutex.Prev = ObjDesc;
+    }
+
+    /* Update list head */
+
+    Thread->AcquiredMutexList = ObjDesc;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiExAcquireMutexObject
+ *
+ * PARAMETERS:  Timeout             - Timeout in milliseconds
+ *              ObjDesc             - Mutex object
+ *              ThreadId            - Current thread state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Acquire an AML mutex, low-level interface. Provides a common
+ *              path that supports multiple acquires by the same thread.
+ *
+ * MUTEX:       Interpreter must be locked
+ *
+ * NOTE: This interface is called from three places:
+ * 1) From AcpiExAcquireMutex, via an AML Acquire() operator
+ * 2) From AcpiExAcquireGlobalLock when an AML Field access requires the
+ *    global lock
+ * 3) From the external interface, AcpiAcquireGlobalLock
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExAcquireMutexObject (
+    UINT16                  Timeout,
+    ACPI_OPERAND_OBJECT     *ObjDesc,
+    ACPI_THREAD_ID          ThreadId)
+{
+    ACPI_STATUS             Status;
+
+
+    ACPI_FUNCTION_TRACE_PTR (ExAcquireMutexObject, ObjDesc);
+
+
+    if (!ObjDesc)
+    {
+        return_ACPI_STATUS (AE_BAD_PARAMETER);
+    }
+
+    /* Support for multiple acquires by the owning thread */
+
+    if (ObjDesc->Mutex.ThreadId == ThreadId)
+    {
+        /*
+         * The mutex is already owned by this thread, just increment the
+         * acquisition depth
+         */
+        ObjDesc->Mutex.AcquisitionDepth++;
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    /* Acquire the mutex, wait if necessary. Special case for Global Lock */
+
+    if (ObjDesc == AcpiGbl_GlobalLockMutex)
+    {
+        Status = AcpiEvAcquireGlobalLock (Timeout);
+    }
+    else
+    {
+        Status = AcpiExSystemWaitMutex (ObjDesc->Mutex.OsMutex,
+                    Timeout);
+    }
+
+    if (ACPI_FAILURE (Status))
+    {
+        /* Includes failure from a timeout on TimeDesc */
+
+        return_ACPI_STATUS (Status);
+    }
+
+    /* Acquired the mutex: update mutex object */
+
+    ObjDesc->Mutex.ThreadId = ThreadId;
+    ObjDesc->Mutex.AcquisitionDepth = 1;
+    ObjDesc->Mutex.OriginalSyncLevel = 0;
+    ObjDesc->Mutex.OwnerThread = NULL;      /* Used only for AML Acquire() */
+
+    return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiExAcquireMutex
+ *
+ * PARAMETERS:  TimeDesc            - Timeout integer
+ *              ObjDesc             - Mutex object
+ *              WalkState           - Current method execution state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Acquire an AML mutex
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExAcquireMutex (
+    ACPI_OPERAND_OBJECT     *TimeDesc,
+    ACPI_OPERAND_OBJECT     *ObjDesc,
+    ACPI_WALK_STATE         *WalkState)
+{
+    ACPI_STATUS             Status;
+
+
+    ACPI_FUNCTION_TRACE_PTR (ExAcquireMutex, ObjDesc);
+
+
+    if (!ObjDesc)
+    {
+        return_ACPI_STATUS (AE_BAD_PARAMETER);
+    }
+
+    /* Must have a valid thread state struct */
+
+    if (!WalkState->Thread)
+    {
+        ACPI_ERROR ((AE_INFO,
+            "Cannot acquire Mutex [%4.4s], null thread info",
+            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
+        return_ACPI_STATUS (AE_AML_INTERNAL);
+    }
+
+    /*
+     * Current sync level must be less than or equal to the sync level of the
+     * mutex. This mechanism provides some deadlock prevention
+     */
+    if (WalkState->Thread->CurrentSyncLevel > ObjDesc->Mutex.SyncLevel)
+    {
+        ACPI_ERROR ((AE_INFO,
+            "Cannot acquire Mutex [%4.4s], current SyncLevel is too large (%u)",
+            AcpiUtGetNodeName (ObjDesc->Mutex.Node),
+            WalkState->Thread->CurrentSyncLevel));
+        return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
+    }
+
+    Status = AcpiExAcquireMutexObject ((UINT16) TimeDesc->Integer.Value,
+                ObjDesc, WalkState->Thread->ThreadId);
+    if (ACPI_SUCCESS (Status) && ObjDesc->Mutex.AcquisitionDepth == 1)
+    {
+        /* Save Thread object, original/current sync levels */
+
+        ObjDesc->Mutex.OwnerThread = WalkState->Thread;
+        ObjDesc->Mutex.OriginalSyncLevel = WalkState->Thread->CurrentSyncLevel;
+        WalkState->Thread->CurrentSyncLevel = ObjDesc->Mutex.SyncLevel;
+
+        /* Link the mutex to the current thread for force-unlock at method exit */
+
+        AcpiExLinkMutex (ObjDesc, WalkState->Thread);
+    }
+
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiExReleaseMutexObject
+ *
+ * PARAMETERS:  ObjDesc             - The object descriptor for this op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Release a previously acquired Mutex, low level interface.
+ *              Provides a common path that supports multiple releases (after
+ *              previous multiple acquires) by the same thread.
+ *
+ * MUTEX:       Interpreter must be locked
+ *
+ * NOTE: This interface is called from three places:
+ * 1) From AcpiExReleaseMutex, via an AML Acquire() operator
+ * 2) From AcpiExReleaseGlobalLock when an AML Field access requires the
+ *    global lock
+ * 3) From the external interface, AcpiReleaseGlobalLock
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExReleaseMutexObject (
+    ACPI_OPERAND_OBJECT     *ObjDesc)
+{
+    ACPI_STATUS             Status = AE_OK;
+
+
+    ACPI_FUNCTION_TRACE (ExReleaseMutexObject);
+
+
+    if (ObjDesc->Mutex.AcquisitionDepth == 0)
+    {
+        return_ACPI_STATUS (AE_NOT_ACQUIRED);
+    }
+
+    /* Match multiple Acquires with multiple Releases */
+
+    ObjDesc->Mutex.AcquisitionDepth--;
+    if (ObjDesc->Mutex.AcquisitionDepth != 0)
+    {
+        /* Just decrement the depth and return */
+
+        return_ACPI_STATUS (AE_OK);
+    }
+
+    if (ObjDesc->Mutex.OwnerThread)
+    {
+        /* Unlink the mutex from the owner's list */
+
+        AcpiExUnlinkMutex (ObjDesc);
+        ObjDesc->Mutex.OwnerThread = NULL;
+    }
+
+    /* Release the mutex, special case for Global Lock */
+
+    if (ObjDesc == AcpiGbl_GlobalLockMutex)
+    {
+        Status = AcpiEvReleaseGlobalLock ();
+    }
+    else
+    {
+        AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);
+    }
+
+    /* Clear mutex info */
+
+    ObjDesc->Mutex.ThreadId = 0;
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiExReleaseMutex
+ *
+ * PARAMETERS:  ObjDesc             - The object descriptor for this op
+ *              WalkState           - Current method execution state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Release a previously acquired Mutex.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExReleaseMutex (
+    ACPI_OPERAND_OBJECT     *ObjDesc,
+    ACPI_WALK_STATE         *WalkState)
+{
+    ACPI_STATUS             Status = AE_OK;
+    UINT8                   PreviousSyncLevel;
+    ACPI_THREAD_STATE       *OwnerThread;
+
+
+    ACPI_FUNCTION_TRACE (ExReleaseMutex);
+
+
+    if (!ObjDesc)
+    {
+        return_ACPI_STATUS (AE_BAD_PARAMETER);
+    }
+
+    OwnerThread = ObjDesc->Mutex.OwnerThread;
+
+    /* The mutex must have been previously acquired in order to release it */
+
+    if (!OwnerThread)
+    {
+        ACPI_ERROR ((AE_INFO,
+            "Cannot release Mutex [%4.4s], not acquired",
+            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
+        return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
+    }
+
+    /* Must have a valid thread ID */
+
+    if (!WalkState->Thread)
+    {
+        ACPI_ERROR ((AE_INFO,
+            "Cannot release Mutex [%4.4s], null thread info",
+            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
+        return_ACPI_STATUS (AE_AML_INTERNAL);
+    }
+
+    /*
+     * The Mutex is owned, but this thread must be the owner.
+     * Special case for Global Lock, any thread can release
+     */
+    if ((OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
+        (ObjDesc != AcpiGbl_GlobalLockMutex))
+    {
+        ACPI_ERROR ((AE_INFO,
+            "Thread %u cannot release Mutex [%4.4s] acquired by thread %u",
+            (UINT32) WalkState->Thread->ThreadId,
+            AcpiUtGetNodeName (ObjDesc->Mutex.Node),
+            (UINT32) OwnerThread->ThreadId));
+        return_ACPI_STATUS (AE_AML_NOT_OWNER);
+    }
+
+    /*
+     * The sync level of the mutex must be equal to the current sync level. In
+     * other words, the current level means that at least one mutex at that
+     * level is currently being held. Attempting to release a mutex of a
+     * different level can only mean that the mutex ordering rule is being
+     * violated. This behavior is clarified in ACPI 4.0 specification.
+     */
+    if (ObjDesc->Mutex.SyncLevel != OwnerThread->CurrentSyncLevel)
+    {
+        ACPI_ERROR ((AE_INFO,
+            "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %u current %u",
+            AcpiUtGetNodeName (ObjDesc->Mutex.Node),
+            ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel));
+        return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
+    }
+
+    /*
+     * Get the previous SyncLevel from the head of the acquired mutex list.
+     * This handles the case where several mutexes at the same level have been
+     * acquired, but are not released in reverse order.
+     */
+    PreviousSyncLevel =
+        OwnerThread->AcquiredMutexList->Mutex.OriginalSyncLevel;
+
+    Status = AcpiExReleaseMutexObject (ObjDesc);
+    if (ACPI_FAILURE (Status))
+    {
+        return_ACPI_STATUS (Status);
+    }
+
+    if (ObjDesc->Mutex.AcquisitionDepth == 0)
+    {
+        /* Restore the previous SyncLevel */
+
+        OwnerThread->CurrentSyncLevel = PreviousSyncLevel;
+    }
+
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiExReleaseAllMutexes
+ *
+ * PARAMETERS:  Thread              - Current executing thread object
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Release all mutexes held by this thread
+ *
+ * NOTE: This function is called as the thread is exiting the interpreter.
+ * Mutexes are not released when an individual control method is exited, but
+ * only when the parent thread actually exits the interpreter. This allows one
+ * method to acquire a mutex, and a different method to release it, as long as
+ * this is performed underneath a single parent control method.
+ *
+ ******************************************************************************/
+
+void
+AcpiExReleaseAllMutexes (
+    ACPI_THREAD_STATE       *Thread)
+{
+    ACPI_OPERAND_OBJECT     *Next = Thread->AcquiredMutexList;
+    ACPI_OPERAND_OBJECT     *ObjDesc;
+
+
+    ACPI_FUNCTION_NAME (ExReleaseAllMutexes);
+
+
+    /* Traverse the list of owned mutexes, releasing each one */
+
+    while (Next)
+    {
+        ObjDesc = Next;
+        Next = ObjDesc->Mutex.Next;
+
+        ObjDesc->Mutex.Prev = NULL;
+        ObjDesc->Mutex.Next = NULL;
+        ObjDesc->Mutex.AcquisitionDepth = 0;
+
+        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+            "Force-releasing held mutex: %p\n", ObjDesc));
+
+        /* Release the mutex, special case for Global Lock */
+
+        if (ObjDesc == AcpiGbl_GlobalLockMutex)
+        {
+            /* Ignore errors */
+
+            (void) AcpiEvReleaseGlobalLock ();
+        }
+        else
+        {
+            AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);
+        }
+
+        /* Mark mutex unowned */
+
+        ObjDesc->Mutex.OwnerThread = NULL;
+        ObjDesc->Mutex.ThreadId = 0;
+
+        /* Update Thread SyncLevel (Last mutex is the important one) */
+
+        Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel;
+    }
+}
