1ddbd7b91SNathan Whitehorn/******************************************************************************
2ddbd7b91SNathan Whitehorn *
3ddbd7b91SNathan Whitehorn * Module Name: exmutex - ASL Mutex Acquire/Release functions
4ddbd7b91SNathan Whitehorn *
5ddbd7b91SNathan Whitehorn *****************************************************************************/
6ddbd7b91SNathan Whitehorn
7ddbd7b91SNathan Whitehorn/******************************************************************************
8ddbd7b91SNathan Whitehorn *
9ddbd7b91SNathan Whitehorn * 1. Copyright Notice
10ddbd7b91SNathan Whitehorn *
11ff2e2f81SFredrik Holmqvist * Some or all of this work - Copyright (c) 1999 - 2018, Intel Corp.
12ddbd7b91SNathan Whitehorn * All rights reserved.
13ddbd7b91SNathan Whitehorn *
14ddbd7b91SNathan Whitehorn * 2. License
15ddbd7b91SNathan Whitehorn *
16ddbd7b91SNathan Whitehorn * 2.1. This is your license from Intel Corp. under its intellectual property
179b0d045cSFredrik Holmqvist * rights. You may have additional license terms from the party that provided
18ddbd7b91SNathan Whitehorn * you this software, covering your right to use that party's intellectual
19ddbd7b91SNathan Whitehorn * property rights.
20ddbd7b91SNathan Whitehorn *
21ddbd7b91SNathan Whitehorn * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22ddbd7b91SNathan Whitehorn * copy of the source code appearing in this file ("Covered Code") an
23ddbd7b91SNathan Whitehorn * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24ddbd7b91SNathan Whitehorn * base code distributed originally by Intel ("Original Intel Code") to copy,
25ddbd7b91SNathan Whitehorn * make derivatives, distribute, use and display any portion of the Covered
26ddbd7b91SNathan Whitehorn * Code in any form, with the right to sublicense such rights; and
27ddbd7b91SNathan Whitehorn *
28ddbd7b91SNathan Whitehorn * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29ddbd7b91SNathan Whitehorn * license (with the right to sublicense), under only those claims of Intel
30ddbd7b91SNathan Whitehorn * patents that are infringed by the Original Intel Code, to make, use, sell,
31ddbd7b91SNathan Whitehorn * offer to sell, and import the Covered Code and derivative works thereof
32ddbd7b91SNathan Whitehorn * solely to the minimum extent necessary to exercise the above copyright
33ddbd7b91SNathan Whitehorn * license, and in no event shall the patent license extend to any additions
349b0d045cSFredrik Holmqvist * to or modifications of the Original Intel Code. No other license or right
35ddbd7b91SNathan Whitehorn * is granted directly or by implication, estoppel or otherwise;
36ddbd7b91SNathan Whitehorn *
37ddbd7b91SNathan Whitehorn * The above copyright and patent license is granted only if the following
38ddbd7b91SNathan Whitehorn * conditions are met:
39ddbd7b91SNathan Whitehorn *
40ddbd7b91SNathan Whitehorn * 3. Conditions
41ddbd7b91SNathan Whitehorn *
42ddbd7b91SNathan Whitehorn * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43ddbd7b91SNathan Whitehorn * Redistribution of source code of any substantial portion of the Covered
44ddbd7b91SNathan Whitehorn * Code or modification with rights to further distribute source must include
45ddbd7b91SNathan Whitehorn * the above Copyright Notice, the above License, this list of Conditions,
469b0d045cSFredrik Holmqvist * and the following Disclaimer and Export Compliance provision. In addition,
47ddbd7b91SNathan Whitehorn * Licensee must cause all Covered Code to which Licensee contributes to
48ddbd7b91SNathan Whitehorn * contain a file documenting the changes Licensee made to create that Covered
499b0d045cSFredrik Holmqvist * Code and the date of any change. Licensee must include in that file the
509b0d045cSFredrik Holmqvist * documentation of any changes made by any predecessor Licensee. Licensee
51ddbd7b91SNathan Whitehorn * must include a prominent statement that the modification is derived,
52ddbd7b91SNathan Whitehorn * directly or indirectly, from Original Intel Code.
53ddbd7b91SNathan Whitehorn *
54ddbd7b91SNathan Whitehorn * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55ddbd7b91SNathan Whitehorn * Redistribution of source code of any substantial portion of the Covered
56ddbd7b91SNathan Whitehorn * Code or modification without rights to further distribute source must
57ddbd7b91SNathan Whitehorn * include the following Disclaimer and Export Compliance provision in the
589b0d045cSFredrik Holmqvist * documentation and/or other materials provided with distribution. In
59ddbd7b91SNathan Whitehorn * addition, Licensee may not authorize further sublicense of source of any
60ddbd7b91SNathan Whitehorn * portion of the Covered Code, and must include terms to the effect that the
61ddbd7b91SNathan Whitehorn * license from Licensee to its licensee is limited to the intellectual
62ddbd7b91SNathan Whitehorn * property embodied in the software Licensee provides to its licensee, and
63ddbd7b91SNathan Whitehorn * not to intellectual property embodied in modifications its licensee may
64ddbd7b91SNathan Whitehorn * make.
65ddbd7b91SNathan Whitehorn *
66ddbd7b91SNathan Whitehorn * 3.3. Redistribution of Executable. Redistribution in executable form of any
67ddbd7b91SNathan Whitehorn * substantial portion of the Covered Code or modification must reproduce the
68ddbd7b91SNathan Whitehorn * above Copyright Notice, and the following Disclaimer and Export Compliance
69ddbd7b91SNathan Whitehorn * provision in the documentation and/or other materials provided with the
70ddbd7b91SNathan Whitehorn * distribution.
71ddbd7b91SNathan Whitehorn *
72ddbd7b91SNathan Whitehorn * 3.4. Intel retains all right, title, and interest in and to the Original
73ddbd7b91SNathan Whitehorn * Intel Code.
74ddbd7b91SNathan Whitehorn *
75ddbd7b91SNathan Whitehorn * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76ddbd7b91SNathan Whitehorn * Intel shall be used in advertising or otherwise to promote the sale, use or
77ddbd7b91SNathan Whitehorn * other dealings in products derived from or relating to the Covered Code
78ddbd7b91SNathan Whitehorn * without prior written authorization from Intel.
79ddbd7b91SNathan Whitehorn *
80ddbd7b91SNathan Whitehorn * 4. Disclaimer and Export Compliance
81ddbd7b91SNathan Whitehorn *
82ddbd7b91SNathan Whitehorn * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
839b0d045cSFredrik Holmqvist * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
849b0d045cSFredrik Holmqvist * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
859b0d045cSFredrik Holmqvist * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
869b0d045cSFredrik Holmqvist * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87ddbd7b91SNathan Whitehorn * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88ddbd7b91SNathan Whitehorn * PARTICULAR PURPOSE.
89ddbd7b91SNathan Whitehorn *
90ddbd7b91SNathan Whitehorn * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91ddbd7b91SNathan Whitehorn * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92ddbd7b91SNathan Whitehorn * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93ddbd7b91SNathan Whitehorn * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94ddbd7b91SNathan Whitehorn * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
959b0d045cSFredrik Holmqvist * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96ddbd7b91SNathan Whitehorn * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97ddbd7b91SNathan Whitehorn * LIMITED REMEDY.
98ddbd7b91SNathan Whitehorn *
99ddbd7b91SNathan Whitehorn * 4.3. Licensee shall not export, either directly or indirectly, any of this
100ddbd7b91SNathan Whitehorn * software or system incorporating such software without first obtaining any
101ddbd7b91SNathan Whitehorn * required license or other approval from the U. S. Department of Commerce or
1029b0d045cSFredrik Holmqvist * any other agency or department of the United States Government. In the
103ddbd7b91SNathan Whitehorn * event Licensee exports any such software from the United States or
104ddbd7b91SNathan Whitehorn * re-exports any such software from a foreign destination, Licensee shall
105ddbd7b91SNathan Whitehorn * ensure that the distribution and export/re-export of the software is in
106ddbd7b91SNathan Whitehorn * compliance with all laws, regulations, orders, or other restrictions of the
107ddbd7b91SNathan Whitehorn * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108ddbd7b91SNathan Whitehorn * any of its subsidiaries will export/re-export any technical data, process,
109ddbd7b91SNathan Whitehorn * software, or service, directly or indirectly, to any country for which the
110ddbd7b91SNathan Whitehorn * United States government or any agency thereof requires an export license,
111ddbd7b91SNathan Whitehorn * other governmental approval, or letter of assurance, without first obtaining
112ddbd7b91SNathan Whitehorn * such license, approval or letter.
113ddbd7b91SNathan Whitehorn *
114ff2e2f81SFredrik Holmqvist *****************************************************************************
115ff2e2f81SFredrik Holmqvist *
116ff2e2f81SFredrik Holmqvist * Alternatively, you may choose to be licensed under the terms of the
117ff2e2f81SFredrik Holmqvist * following license:
118ff2e2f81SFredrik Holmqvist *
119ff2e2f81SFredrik Holmqvist * Redistribution and use in source and binary forms, with or without
120ff2e2f81SFredrik Holmqvist * modification, are permitted provided that the following conditions
121ff2e2f81SFredrik Holmqvist * are met:
122ff2e2f81SFredrik Holmqvist * 1. Redistributions of source code must retain the above copyright
123ff2e2f81SFredrik Holmqvist *    notice, this list of conditions, and the following disclaimer,
124ff2e2f81SFredrik Holmqvist *    without modification.
125ff2e2f81SFredrik Holmqvist * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126ff2e2f81SFredrik Holmqvist *    substantially similar to the "NO WARRANTY" disclaimer below
127ff2e2f81SFredrik Holmqvist *    ("Disclaimer") and any redistribution must be conditioned upon
128ff2e2f81SFredrik Holmqvist *    including a substantially similar Disclaimer requirement for further
129ff2e2f81SFredrik Holmqvist *    binary redistribution.
130ff2e2f81SFredrik Holmqvist * 3. Neither the names of the above-listed copyright holders nor the names
131ff2e2f81SFredrik Holmqvist *    of any contributors may be used to endorse or promote products derived
132ff2e2f81SFredrik Holmqvist *    from this software without specific prior written permission.
133ff2e2f81SFredrik Holmqvist *
134ff2e2f81SFredrik Holmqvist * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135ff2e2f81SFredrik Holmqvist * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136ff2e2f81SFredrik Holmqvist * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137ff2e2f81SFredrik Holmqvist * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138ff2e2f81SFredrik Holmqvist * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139ff2e2f81SFredrik Holmqvist * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140ff2e2f81SFredrik Holmqvist * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141ff2e2f81SFredrik Holmqvist * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142ff2e2f81SFredrik Holmqvist * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143ff2e2f81SFredrik Holmqvist * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144ff2e2f81SFredrik Holmqvist * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145ff2e2f81SFredrik Holmqvist *
146ff2e2f81SFredrik Holmqvist * Alternatively, you may choose to be licensed under the terms of the
147ff2e2f81SFredrik Holmqvist * GNU General Public License ("GPL") version 2 as published by the Free
148ff2e2f81SFredrik Holmqvist * Software Foundation.
149ff2e2f81SFredrik Holmqvist *
150ddbd7b91SNathan Whitehorn *****************************************************************************/
151ddbd7b91SNathan Whitehorn
152ddbd7b91SNathan Whitehorn#include "acpi.h"
15380377d9aSJérôme Duval#include "accommon.h"
154ddbd7b91SNathan Whitehorn#include "acinterp.h"
15579414580SJérôme Duval#include "acevents.h"
156ddbd7b91SNathan Whitehorn
157ddbd7b91SNathan Whitehorn#define _COMPONENT          ACPI_EXECUTER
158ddbd7b91SNathan Whitehorn        ACPI_MODULE_NAME    ("exmutex")
159ddbd7b91SNathan Whitehorn
16043547dbeSJérôme Duval/* Local prototypes */
16143547dbeSJérôme Duval
16243547dbeSJérôme Duvalstatic void
16343547dbeSJérôme DuvalAcpiExLinkMutex (
16443547dbeSJérôme Duval    ACPI_OPERAND_OBJECT     *ObjDesc,
16543547dbeSJérôme Duval    ACPI_THREAD_STATE       *Thread);
16643547dbeSJérôme Duval
167ddbd7b91SNathan Whitehorn
168ddbd7b91SNathan Whitehorn/*******************************************************************************
169ddbd7b91SNathan Whitehorn *
170ddbd7b91SNathan Whitehorn * FUNCTION:    AcpiExUnlinkMutex
171ddbd7b91SNathan Whitehorn *
172ddbd7b91SNathan Whitehorn * PARAMETERS:  ObjDesc             - The mutex to be unlinked
173ddbd7b91SNathan Whitehorn *
17443547dbeSJérôme Duval * RETURN:      None
175ddbd7b91SNathan Whitehorn *
176ddbd7b91SNathan Whitehorn * DESCRIPTION: Remove a mutex from the "AcquiredMutex" list
177ddbd7b91SNathan Whitehorn *
178ddbd7b91SNathan Whitehorn ******************************************************************************/
179ddbd7b91SNathan Whitehorn
180ddbd7b91SNathan Whitehornvoid
181ddbd7b91SNathan WhitehornAcpiExUnlinkMutex (
182ddbd7b91SNathan Whitehorn    ACPI_OPERAND_OBJECT     *ObjDesc)
183ddbd7b91SNathan Whitehorn{
184ddbd7b91SNathan Whitehorn    ACPI_THREAD_STATE       *Thread = ObjDesc->Mutex.OwnerThread;
185ddbd7b91SNathan Whitehorn
186ddbd7b91SNathan Whitehorn
187ddbd7b91SNathan Whitehorn    if (!Thread)
188ddbd7b91SNathan Whitehorn    {
189ddbd7b91SNathan Whitehorn        return;
190ddbd7b91SNathan Whitehorn    }
191ddbd7b91SNathan Whitehorn
192ddbd7b91SNathan Whitehorn    /* Doubly linked list */
193ddbd7b91SNathan Whitehorn
194ddbd7b91SNathan Whitehorn    if (ObjDesc->Mutex.Next)
195ddbd7b91SNathan Whitehorn    {
196ddbd7b91SNathan Whitehorn        (ObjDesc->Mutex.Next)->Mutex.Prev = ObjDesc->Mutex.Prev;
197ddbd7b91SNathan Whitehorn    }
198ddbd7b91SNathan Whitehorn
199ddbd7b91SNathan Whitehorn    if (ObjDesc->Mutex.Prev)
200ddbd7b91SNathan Whitehorn    {
201ddbd7b91SNathan Whitehorn        (ObjDesc->Mutex.Prev)->Mutex.Next = ObjDesc->Mutex.Next;
20280377d9aSJérôme Duval
20380377d9aSJérôme Duval        /*
204ffb873afSFredrik Holmqvist         * Migrate the previous sync level associated with this mutex to
205ffb873afSFredrik Holmqvist         * the previous mutex on the list so that it may be preserved.
206ffb873afSFredrik Holmqvist         * This handles the case where several mutexes have been acquired
207ffb873afSFredrik Holmqvist         * at the same level, but are not released in opposite order.
20880377d9aSJérôme Duval         */
20980377d9aSJérôme Duval        (ObjDesc->Mutex.Prev)->Mutex.OriginalSyncLevel =
21080377d9aSJérôme Duval            ObjDesc->Mutex.OriginalSyncLevel;
211ddbd7b91SNathan Whitehorn    }
212ddbd7b91SNathan Whitehorn    else
213ddbd7b91SNathan Whitehorn    {
214ddbd7b91SNathan Whitehorn        Thread->AcquiredMutexList = ObjDesc->Mutex.Next;
215ddbd7b91SNathan Whitehorn    }
216ddbd7b91SNathan Whitehorn}
217ddbd7b91SNathan Whitehorn
218ddbd7b91SNathan Whitehorn
219ddbd7b91SNathan Whitehorn/*******************************************************************************
220ddbd7b91SNathan Whitehorn *
221ddbd7b91SNathan Whitehorn * FUNCTION:    AcpiExLinkMutex
222ddbd7b91SNathan Whitehorn *
223ffb873afSFredrik Holmqvist * PARAMETERS:  ObjDesc             - The mutex to be linked
224ffb873afSFredrik Holmqvist *              Thread              - Current executing thread object
225ddbd7b91SNathan Whitehorn *
22643547dbeSJérôme Duval * RETURN:      None
227ddbd7b91SNathan Whitehorn *
228ddbd7b91SNathan Whitehorn * DESCRIPTION: Add a mutex to the "AcquiredMutex" list for this walk
229ddbd7b91SNathan Whitehorn *
230ddbd7b91SNathan Whitehorn ******************************************************************************/
231ddbd7b91SNathan Whitehorn
23243547dbeSJérôme Duvalstatic void
233ddbd7b91SNathan WhitehornAcpiExLinkMutex (
234ddbd7b91SNathan Whitehorn    ACPI_OPERAND_OBJECT     *ObjDesc,
235ddbd7b91SNathan Whitehorn    ACPI_THREAD_STATE       *Thread)
236ddbd7b91SNathan Whitehorn{
237ddbd7b91SNathan Whitehorn    ACPI_OPERAND_OBJECT     *ListHead;
238ddbd7b91SNathan Whitehorn
239ddbd7b91SNathan Whitehorn
240ddbd7b91SNathan Whitehorn    ListHead = Thread->AcquiredMutexList;
241ddbd7b91SNathan Whitehorn
242ddbd7b91SNathan Whitehorn    /* This object will be the first object in the list */
243ddbd7b91SNathan Whitehorn
244ddbd7b91SNathan Whitehorn    ObjDesc->Mutex.Prev = NULL;
245ddbd7b91SNathan Whitehorn    ObjDesc->Mutex.Next = ListHead;
246ddbd7b91SNathan Whitehorn
247ddbd7b91SNathan Whitehorn    /* Update old first object to point back to this object */
248ddbd7b91SNathan Whitehorn
249ddbd7b91SNathan Whitehorn    if (ListHead)
250ddbd7b91SNathan Whitehorn    {
251ddbd7b91SNathan Whitehorn        ListHead->Mutex.Prev = ObjDesc;
252ddbd7b91SNathan Whitehorn    }
253ddbd7b91SNathan Whitehorn
254ddbd7b91SNathan Whitehorn    /* Update list head */
255ddbd7b91SNathan Whitehorn
256ddbd7b91SNathan Whitehorn    Thread->AcquiredMutexList = ObjDesc;
257ddbd7b91SNathan Whitehorn}
258ddbd7b91SNathan Whitehorn
259ddbd7b91SNathan Whitehorn
2602608583eSJérôme Duval/*******************************************************************************
2612608583eSJérôme Duval *
2622608583eSJérôme Duval * FUNCTION:    AcpiExAcquireMutexObject
2632608583eSJérôme Duval *
264ffb873afSFredrik Holmqvist * PARAMETERS:  Timeout             - Timeout in milliseconds
2652608583eSJérôme Duval *              ObjDesc             - Mutex object
266ffb873afSFredrik Holmqvist *              ThreadId            - Current thread state
2672608583eSJérôme Duval *
2682608583eSJérôme Duval * RETURN:      Status
2692608583eSJérôme Duval *
2702608583eSJérôme Duval * DESCRIPTION: Acquire an AML mutex, low-level interface. Provides a common
2712608583eSJérôme Duval *              path that supports multiple acquires by the same thread.
2722608583eSJérôme Duval *
2732608583eSJérôme Duval * MUTEX:       Interpreter must be locked
2742608583eSJérôme Duval *
2752608583eSJérôme Duval * NOTE: This interface is called from three places:
2762608583eSJérôme Duval * 1) From AcpiExAcquireMutex, via an AML Acquire() operator
2772608583eSJérôme Duval * 2) From AcpiExAcquireGlobalLock when an AML Field access requires the
2782608583eSJérôme Duval *    global lock
2792608583eSJérôme Duval * 3) From the external interface, AcpiAcquireGlobalLock
2802608583eSJérôme Duval *
2812608583eSJérôme Duval ******************************************************************************/
2822608583eSJérôme Duval
2832608583eSJérôme DuvalACPI_STATUS
2842608583eSJérôme DuvalAcpiExAcquireMutexObject (
2852608583eSJérôme Duval    UINT16                  Timeout,
2862608583eSJérôme Duval    ACPI_OPERAND_OBJECT     *ObjDesc,
2872608583eSJérôme Duval    ACPI_THREAD_ID          ThreadId)
2882608583eSJérôme Duval{
2892608583eSJérôme Duval    ACPI_STATUS             Status;
2902608583eSJérôme Duval
2912608583eSJérôme Duval
2922608583eSJérôme Duval    ACPI_FUNCTION_TRACE_PTR (ExAcquireMutexObject, ObjDesc);
2932608583eSJérôme Duval
2942608583eSJérôme Duval
2952608583eSJérôme Duval    if (!ObjDesc)
2962608583eSJérôme Duval    {
2972608583eSJérôme Duval        return_ACPI_STATUS (AE_BAD_PARAMETER);
2982608583eSJérôme Duval    }
2992608583eSJérôme Duval
3002608583eSJérôme Duval    /* Support for multiple acquires by the owning thread */
3012608583eSJérôme Duval
3022608583eSJérôme Duval    if (ObjDesc->Mutex.ThreadId == ThreadId)
3032608583eSJérôme Duval    {
3042608583eSJérôme Duval        /*
3052608583eSJérôme Duval         * The mutex is already owned by this thread, just increment the
3062608583eSJérôme Duval         * acquisition depth
3072608583eSJérôme Duval         */
3082608583eSJérôme Duval        ObjDesc->Mutex.AcquisitionDepth++;
3092608583eSJérôme Duval        return_ACPI_STATUS (AE_OK);
3102608583eSJérôme Duval    }
3112608583eSJérôme Duval
3122608583eSJérôme Duval    /* Acquire the mutex, wait if necessary. Special case for Global Lock */
3132608583eSJérôme Duval
3142608583eSJérôme Duval    if (ObjDesc == AcpiGbl_GlobalLockMutex)
3152608583eSJérôme Duval    {
3162608583eSJérôme Duval        Status = AcpiEvAcquireGlobalLock (Timeout);
3172608583eSJérôme Duval    }
3182608583eSJérôme Duval    else
3192608583eSJérôme Duval    {
320b64e8511SFredrik Holmqvist        Status = AcpiExSystemWaitMutex (ObjDesc->Mutex.OsMutex, Timeout);
3212608583eSJérôme Duval    }
3222608583eSJérôme Duval
3232608583eSJérôme Duval    if (ACPI_FAILURE (Status))
3242608583eSJérôme Duval    {
3252608583eSJérôme Duval        /* Includes failure from a timeout on TimeDesc */
3262608583eSJérôme Duval
3272608583eSJérôme Duval        return_ACPI_STATUS (Status);
3282608583eSJérôme Duval    }
3292608583eSJérôme Duval
3302608583eSJérôme Duval    /* Acquired the mutex: update mutex object */
3312608583eSJérôme Duval
3322608583eSJérôme Duval    ObjDesc->Mutex.ThreadId = ThreadId;
3332608583eSJérôme Duval    ObjDesc->Mutex.AcquisitionDepth = 1;
3342608583eSJérôme Duval    ObjDesc->Mutex.OriginalSyncLevel = 0;
3352608583eSJérôme Duval    ObjDesc->Mutex.OwnerThread = NULL;      /* Used only for AML Acquire() */
3362608583eSJérôme Duval
3372608583eSJérôme Duval    return_ACPI_STATUS (AE_OK);
3382608583eSJérôme Duval}
3392608583eSJérôme Duval
3402608583eSJérôme Duval
341ddbd7b91SNathan Whitehorn/*******************************************************************************
342ddbd7b91SNathan Whitehorn *
343ddbd7b91SNathan Whitehorn * FUNCTION:    AcpiExAcquireMutex
344ddbd7b91SNathan Whitehorn *
34543547dbeSJérôme Duval * PARAMETERS:  TimeDesc            - Timeout integer
34643547dbeSJérôme Duval *              ObjDesc             - Mutex object
34743547dbeSJérôme Duval *              WalkState           - Current method execution state
348ddbd7b91SNathan Whitehorn *
349ddbd7b91SNathan Whitehorn * RETURN:      Status
350ddbd7b91SNathan Whitehorn *
351ddbd7b91SNathan Whitehorn * DESCRIPTION: Acquire an AML mutex
352ddbd7b91SNathan Whitehorn *
353ddbd7b91SNathan Whitehorn ******************************************************************************/
354ddbd7b91SNathan Whitehorn
355ddbd7b91SNathan WhitehornACPI_STATUS
356ddbd7b91SNathan WhitehornAcpiExAcquireMutex (
357ddbd7b91SNathan Whitehorn    ACPI_OPERAND_OBJECT     *TimeDesc,
358ddbd7b91SNathan Whitehorn    ACPI_OPERAND_OBJECT     *ObjDesc,
359ddbd7b91SNathan Whitehorn    ACPI_WALK_STATE         *WalkState)
360ddbd7b91SNathan Whitehorn{
361ddbd7b91SNathan Whitehorn    ACPI_STATUS             Status;
362ddbd7b91SNathan Whitehorn
363ddbd7b91SNathan Whitehorn
36443547dbeSJérôme Duval    ACPI_FUNCTION_TRACE_PTR (ExAcquireMutex, ObjDesc);
365ddbd7b91SNathan Whitehorn
366ddbd7b91SNathan Whitehorn
367ddbd7b91SNathan Whitehorn    if (!ObjDesc)
368ddbd7b91SNathan Whitehorn    {
369ddbd7b91SNathan Whitehorn        return_ACPI_STATUS (AE_BAD_PARAMETER);
370ddbd7b91SNathan Whitehorn    }
371ddbd7b91SNathan Whitehorn
372ffb873afSFredrik Holmqvist    /* Must have a valid thread state struct */
373ddbd7b91SNathan Whitehorn
374ddbd7b91SNathan Whitehorn    if (!WalkState->Thread)
375ddbd7b91SNathan Whitehorn    {
376ffb873afSFredrik Holmqvist        ACPI_ERROR ((AE_INFO,
377ffb873afSFredrik Holmqvist            "Cannot acquire Mutex [%4.4s], null thread info",
37843547dbeSJérôme Duval            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
379ddbd7b91SNathan Whitehorn        return_ACPI_STATUS (AE_AML_INTERNAL);
380ddbd7b91SNathan Whitehorn    }
381ddbd7b91SNathan Whitehorn
382ddbd7b91SNathan Whitehorn    /*
383b64e8511SFredrik Holmqvist     * Current sync level must be less than or equal to the sync level
384b64e8511SFredrik Holmqvist     * of the mutex. This mechanism provides some deadlock prevention.
385ddbd7b91SNathan Whitehorn     */
386ddbd7b91SNathan Whitehorn    if (WalkState->Thread->CurrentSyncLevel > ObjDesc->Mutex.SyncLevel)
387ddbd7b91SNathan Whitehorn    {
38843547dbeSJérôme Duval        ACPI_ERROR ((AE_INFO,
389b64e8511SFredrik Holmqvist            "Cannot acquire Mutex [%4.4s], "
390b64e8511SFredrik Holmqvist            "current SyncLevel is too large (%u)",
39139d02f89SJérôme Duval            AcpiUtGetNodeName (ObjDesc->Mutex.Node),
39239d02f89SJérôme Duval            WalkState->Thread->CurrentSyncLevel));
393ddbd7b91SNathan Whitehorn        return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
394ddbd7b91SNathan Whitehorn    }
395ddbd7b91SNathan Whitehorn
396b64e8511SFredrik Holmqvist    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
397b64e8511SFredrik Holmqvist        "Acquiring: Mutex SyncLevel %u, Thread SyncLevel %u, "
398b64e8511SFredrik Holmqvist        "Depth %u TID %p\n",
399b64e8511SFredrik Holmqvist        ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel,
400b64e8511SFredrik Holmqvist        ObjDesc->Mutex.AcquisitionDepth, WalkState->Thread));
401b64e8511SFredrik Holmqvist
4022608583eSJérôme Duval    Status = AcpiExAcquireMutexObject ((UINT16) TimeDesc->Integer.Value,
403b64e8511SFredrik Holmqvist        ObjDesc, WalkState->Thread->ThreadId);
404b64e8511SFredrik Holmqvist
4052608583eSJérôme Duval    if (ACPI_SUCCESS (Status) && ObjDesc->Mutex.AcquisitionDepth == 1)
406ddbd7b91SNathan Whitehorn    {
4072608583eSJérôme Duval        /* Save Thread object, original/current sync levels */
4082608583eSJérôme Duval
4092608583eSJérôme Duval        ObjDesc->Mutex.OwnerThread = WalkState->Thread;
410b64e8511SFredrik Holmqvist        ObjDesc->Mutex.OriginalSyncLevel =
411b64e8511SFredrik Holmqvist            WalkState->Thread->CurrentSyncLevel;
412b64e8511SFredrik Holmqvist        WalkState->Thread->CurrentSyncLevel =
413b64e8511SFredrik Holmqvist            ObjDesc->Mutex.SyncLevel;
4142608583eSJérôme Duval
4152608583eSJérôme Duval        /* Link the mutex to the current thread for force-unlock at method exit */
4162608583eSJérôme Duval
4172608583eSJérôme Duval        AcpiExLinkMutex (ObjDesc, WalkState->Thread);
418ddbd7b91SNathan Whitehorn    }
419ddbd7b91SNathan Whitehorn
420b64e8511SFredrik Holmqvist    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
421b64e8511SFredrik Holmqvist        "Acquired: Mutex SyncLevel %u, Thread SyncLevel %u, Depth %u\n",
422b64e8511SFredrik Holmqvist        ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel,
423b64e8511SFredrik Holmqvist        ObjDesc->Mutex.AcquisitionDepth));
424b64e8511SFredrik Holmqvist
4252608583eSJérôme Duval    return_ACPI_STATUS (Status);
4262608583eSJérôme Duval}
42779414580SJérôme Duval
4282608583eSJérôme Duval
4292608583eSJérôme Duval/*******************************************************************************
4302608583eSJérôme Duval *
4312608583eSJérôme Duval * FUNCTION:    AcpiExReleaseMutexObject
4322608583eSJérôme Duval *
4332608583eSJérôme Duval * PARAMETERS:  ObjDesc             - The object descriptor for this op
4342608583eSJérôme Duval *
4352608583eSJérôme Duval * RETURN:      Status
4362608583eSJérôme Duval *
4372608583eSJérôme Duval * DESCRIPTION: Release a previously acquired Mutex, low level interface.
4382608583eSJérôme Duval *              Provides a common path that supports multiple releases (after
4392608583eSJérôme Duval *              previous multiple acquires) by the same thread.
4402608583eSJérôme Duval *
4412608583eSJérôme Duval * MUTEX:       Interpreter must be locked
4422608583eSJérôme Duval *
4432608583eSJérôme Duval * NOTE: This interface is called from three places:
4442608583eSJérôme Duval * 1) From AcpiExReleaseMutex, via an AML Acquire() operator
4452608583eSJérôme Duval * 2) From AcpiExReleaseGlobalLock when an AML Field access requires the
4462608583eSJérôme Duval *    global lock
4472608583eSJérôme Duval * 3) From the external interface, AcpiReleaseGlobalLock
4482608583eSJérôme Duval *
4492608583eSJérôme Duval ******************************************************************************/
4502608583eSJérôme Duval
4512608583eSJérôme DuvalACPI_STATUS
4522608583eSJérôme DuvalAcpiExReleaseMutexObject (
4532608583eSJérôme Duval    ACPI_OPERAND_OBJECT     *ObjDesc)
4542608583eSJérôme Duval{
4552608583eSJérôme Duval    ACPI_STATUS             Status = AE_OK;
4562608583eSJérôme Duval
4572608583eSJérôme Duval
4582608583eSJérôme Duval    ACPI_FUNCTION_TRACE (ExReleaseMutexObject);
4592608583eSJérôme Duval
4602608583eSJérôme Duval
4612608583eSJérôme Duval    if (ObjDesc->Mutex.AcquisitionDepth == 0)
46279414580SJérôme Duval    {
4639b0d045cSFredrik Holmqvist        return_ACPI_STATUS (AE_NOT_ACQUIRED);
46479414580SJérôme Duval    }
4652608583eSJérôme Duval
4662608583eSJérôme Duval    /* Match multiple Acquires with multiple Releases */
4672608583eSJérôme Duval
4682608583eSJérôme Duval    ObjDesc->Mutex.AcquisitionDepth--;
4692608583eSJérôme Duval    if (ObjDesc->Mutex.AcquisitionDepth != 0)
47079414580SJérôme Duval    {
4712608583eSJérôme Duval        /* Just decrement the depth and return */
4722608583eSJérôme Duval
4732608583eSJérôme Duval        return_ACPI_STATUS (AE_OK);
47479414580SJérôme Duval    }
475ddbd7b91SNathan Whitehorn
4762608583eSJérôme Duval    if (ObjDesc->Mutex.OwnerThread)
477ddbd7b91SNathan Whitehorn    {
4782608583eSJérôme Duval        /* Unlink the mutex from the owner's list */
479ddbd7b91SNathan Whitehorn
4802608583eSJérôme Duval        AcpiExUnlinkMutex (ObjDesc);
4812608583eSJérôme Duval        ObjDesc->Mutex.OwnerThread = NULL;
482ddbd7b91SNathan Whitehorn    }
483ddbd7b91SNathan Whitehorn
4842608583eSJérôme Duval    /* Release the mutex, special case for Global Lock */
485ddbd7b91SNathan Whitehorn
4862608583eSJérôme Duval    if (ObjDesc == AcpiGbl_GlobalLockMutex)
4872608583eSJérôme Duval    {
4882608583eSJérôme Duval        Status = AcpiEvReleaseGlobalLock ();
4892608583eSJérôme Duval    }
4902608583eSJérôme Duval    else
4912608583eSJérôme Duval    {
4922608583eSJérôme Duval        AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);
4932608583eSJérôme Duval    }
494ddbd7b91SNathan Whitehorn
4952608583eSJérôme Duval    /* Clear mutex info */
496ddbd7b91SNathan Whitehorn
4972608583eSJérôme Duval    ObjDesc->Mutex.ThreadId = 0;
4982608583eSJérôme Duval    return_ACPI_STATUS (Status);
499ddbd7b91SNathan Whitehorn}
500ddbd7b91SNathan Whitehorn
501ddbd7b91SNathan Whitehorn
502ddbd7b91SNathan Whitehorn/*******************************************************************************
503ddbd7b91SNathan Whitehorn *
504ddbd7b91SNathan Whitehorn * FUNCTION:    AcpiExReleaseMutex
505ddbd7b91SNathan Whitehorn *
506ddbd7b91SNathan Whitehorn * PARAMETERS:  ObjDesc             - The object descriptor for this op
50743547dbeSJérôme Duval *              WalkState           - Current method execution state
508ddbd7b91SNathan Whitehorn *
509ddbd7b91SNathan Whitehorn * RETURN:      Status
510ddbd7b91SNathan Whitehorn *
511ddbd7b91SNathan Whitehorn * DESCRIPTION: Release a previously acquired Mutex.
512ddbd7b91SNathan Whitehorn *
513ddbd7b91SNathan Whitehorn ******************************************************************************/
514ddbd7b91SNathan Whitehorn
515ddbd7b91SNathan WhitehornACPI_STATUS
516ddbd7b91SNathan WhitehornAcpiExReleaseMutex (
517ddbd7b91SNathan Whitehorn    ACPI_OPERAND_OBJECT     *ObjDesc,
518ddbd7b91SNathan Whitehorn    ACPI_WALK_STATE         *WalkState)
519ddbd7b91SNathan Whitehorn{
52080377d9aSJérôme Duval    UINT8                   PreviousSyncLevel;
521ffb873afSFredrik Holmqvist    ACPI_THREAD_STATE       *OwnerThread;
522b64e8511SFredrik Holmqvist    ACPI_STATUS             Status = AE_OK;
523ddbd7b91SNathan Whitehorn
524ddbd7b91SNathan Whitehorn
52543547dbeSJérôme Duval    ACPI_FUNCTION_TRACE (ExReleaseMutex);
526ddbd7b91SNathan Whitehorn
527ddbd7b91SNathan Whitehorn
528ddbd7b91SNathan Whitehorn    if (!ObjDesc)
529ddbd7b91SNathan Whitehorn    {
530ddbd7b91SNathan Whitehorn        return_ACPI_STATUS (AE_BAD_PARAMETER);
531ddbd7b91SNathan Whitehorn    }
532ddbd7b91SNathan Whitehorn
533ffb873afSFredrik Holmqvist    OwnerThread = ObjDesc->Mutex.OwnerThread;
534ffb873afSFredrik Holmqvist
535ddbd7b91SNathan Whitehorn    /* The mutex must have been previously acquired in order to release it */
536ddbd7b91SNathan Whitehorn
537ffb873afSFredrik Holmqvist    if (!OwnerThread)
538ddbd7b91SNathan Whitehorn    {
539ffb873afSFredrik Holmqvist        ACPI_ERROR ((AE_INFO,
540ffb873afSFredrik Holmqvist            "Cannot release Mutex [%4.4s], not acquired",
54143547dbeSJérôme Duval            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
542ddbd7b91SNathan Whitehorn        return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
543ddbd7b91SNathan Whitehorn    }
544ddbd7b91SNathan Whitehorn
54557c418cdSFredrik Holmqvist    /* Must have a valid thread ID */
54657c418cdSFredrik Holmqvist
54757c418cdSFredrik Holmqvist    if (!WalkState->Thread)
54857c418cdSFredrik Holmqvist    {
549ffb873afSFredrik Holmqvist        ACPI_ERROR ((AE_INFO,
550ffb873afSFredrik Holmqvist            "Cannot release Mutex [%4.4s], null thread info",
55157c418cdSFredrik Holmqvist            AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
55257c418cdSFredrik Holmqvist        return_ACPI_STATUS (AE_AML_INTERNAL);
55357c418cdSFredrik Holmqvist    }
55457c418cdSFredrik Holmqvist
555ddbd7b91SNathan Whitehorn    /*
556ddbd7b91SNathan Whitehorn     * The Mutex is owned, but this thread must be the owner.
557ddbd7b91SNathan Whitehorn     * Special case for Global Lock, any thread can release
558ddbd7b91SNathan Whitehorn     */
559ffb873afSFredrik Holmqvist    if ((OwnerThread->ThreadId != WalkState->Thread->ThreadId) &&
5602608583eSJérôme Duval        (ObjDesc != AcpiGbl_GlobalLockMutex))
561ddbd7b91SNathan Whitehorn    {
56243547dbeSJérôme Duval        ACPI_ERROR ((AE_INFO,
56312474ac0SFredrik Holmqvist            "Thread %u cannot release Mutex [%4.4s] acquired by thread %u",
56412474ac0SFredrik Holmqvist            (UINT32) WalkState->Thread->ThreadId,
565ddbd7b91SNathan Whitehorn            AcpiUtGetNodeName (ObjDesc->Mutex.Node),
56612474ac0SFredrik Holmqvist            (UINT32) OwnerThread->ThreadId));
567ddbd7b91SNathan Whitehorn        return_ACPI_STATUS (AE_AML_NOT_OWNER);
568ddbd7b91SNathan Whitehorn    }
569ddbd7b91SNathan Whitehorn
570ddbd7b91SNathan Whitehorn    /*
57180377d9aSJérôme Duval     * The sync level of the mutex must be equal to the current sync level. In
57280377d9aSJérôme Duval     * other words, the current level means that at least one mutex at that
57380377d9aSJérôme Duval     * level is currently being held. Attempting to release a mutex of a
57480377d9aSJérôme Duval     * different level can only mean that the mutex ordering rule is being
57580377d9aSJérôme Duval     * violated. This behavior is clarified in ACPI 4.0 specification.
576ddbd7b91SNathan Whitehorn     */
577ffb873afSFredrik Holmqvist    if (ObjDesc->Mutex.SyncLevel != OwnerThread->CurrentSyncLevel)
578ddbd7b91SNathan Whitehorn    {
57943547dbeSJérôme Duval        ACPI_ERROR ((AE_INFO,
580b64e8511SFredrik Holmqvist            "Cannot release Mutex [%4.4s], SyncLevel mismatch: "
581b64e8511SFredrik Holmqvist            "mutex %u current %u",
5822608583eSJérôme Duval            AcpiUtGetNodeName (ObjDesc->Mutex.Node),
5832608583eSJérôme Duval            ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel));
584ddbd7b91SNathan Whitehorn        return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
585ddbd7b91SNathan Whitehorn    }
586ddbd7b91SNathan Whitehorn
58780377d9aSJérôme Duval    /*
58880377d9aSJérôme Duval     * Get the previous SyncLevel from the head of the acquired mutex list.
58980377d9aSJérôme Duval     * This handles the case where several mutexes at the same level have been
59080377d9aSJérôme Duval     * acquired, but are not released in reverse order.
59180377d9aSJérôme Duval     */
59280377d9aSJérôme Duval    PreviousSyncLevel =
593ffb873afSFredrik Holmqvist        OwnerThread->AcquiredMutexList->Mutex.OriginalSyncLevel;
59480377d9aSJérôme Duval
595b64e8511SFredrik Holmqvist    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
596b64e8511SFredrik Holmqvist        "Releasing: Object SyncLevel %u, Thread SyncLevel %u, "
597b64e8511SFredrik Holmqvist        "Prev SyncLevel %u, Depth %u TID %p\n",
598b64e8511SFredrik Holmqvist        ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel,
599b64e8511SFredrik Holmqvist        PreviousSyncLevel, ObjDesc->Mutex.AcquisitionDepth,
600b64e8511SFredrik Holmqvist        WalkState->Thread));
601b64e8511SFredrik Holmqvist
6022608583eSJérôme Duval    Status = AcpiExReleaseMutexObject (ObjDesc);
60380377d9aSJérôme Duval    if (ACPI_FAILURE (Status))
60480377d9aSJérôme Duval    {
60580377d9aSJérôme Duval        return_ACPI_STATUS (Status);
60680377d9aSJérôme Duval    }
607ddbd7b91SNathan Whitehorn
6082608583eSJérôme Duval    if (ObjDesc->Mutex.AcquisitionDepth == 0)
609ddbd7b91SNathan Whitehorn    {
61080377d9aSJérôme Duval        /* Restore the previous SyncLevel */
611ddbd7b91SNathan Whitehorn
612ffb873afSFredrik Holmqvist        OwnerThread->CurrentSyncLevel = PreviousSyncLevel;
61379414580SJérôme Duval    }
614ffb873afSFredrik Holmqvist
615b64e8511SFredrik Holmqvist    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
616b64e8511SFredrik Holmqvist        "Released: Object SyncLevel %u, Thread SyncLevel, %u, "
617b64e8511SFredrik Holmqvist        "Prev SyncLevel %u, Depth %u\n",
618b64e8511SFredrik Holmqvist        ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel,
619b64e8511SFredrik Holmqvist        PreviousSyncLevel, ObjDesc->Mutex.AcquisitionDepth));
620b64e8511SFredrik Holmqvist
621ddbd7b91SNathan Whitehorn    return_ACPI_STATUS (Status);
622ddbd7b91SNathan Whitehorn}
623ddbd7b91SNathan Whitehorn
624ddbd7b91SNathan Whitehorn
625ddbd7b91SNathan Whitehorn/*******************************************************************************
626ddbd7b91SNathan Whitehorn *
627ddbd7b91SNathan Whitehorn * FUNCTION:    AcpiExReleaseAllMutexes
628ddbd7b91SNathan Whitehorn *
629ffb873afSFredrik Holmqvist * PARAMETERS:  Thread              - Current executing thread object
630ddbd7b91SNathan Whitehorn *
631ddbd7b91SNathan Whitehorn * RETURN:      Status
632ddbd7b91SNathan Whitehorn *
63343547dbeSJérôme Duval * DESCRIPTION: Release all mutexes held by this thread
634ddbd7b91SNathan Whitehorn *
63579414580SJérôme Duval * NOTE: This function is called as the thread is exiting the interpreter.
63679414580SJérôme Duval * Mutexes are not released when an individual control method is exited, but
63779414580SJérôme Duval * only when the parent thread actually exits the interpreter. This allows one
63879414580SJérôme Duval * method to acquire a mutex, and a different method to release it, as long as
63979414580SJérôme Duval * this is performed underneath a single parent control method.
64079414580SJérôme Duval *
641ddbd7b91SNathan Whitehorn ******************************************************************************/
642ddbd7b91SNathan Whitehorn
643ddbd7b91SNathan Whitehornvoid
644ddbd7b91SNathan WhitehornAcpiExReleaseAllMutexes (
645ddbd7b91SNathan Whitehorn    ACPI_THREAD_STATE       *Thread)
646ddbd7b91SNathan Whitehorn{
647ddbd7b91SNathan Whitehorn    ACPI_OPERAND_OBJECT     *Next = Thread->AcquiredMutexList;
64879414580SJérôme Duval    ACPI_OPERAND_OBJECT     *ObjDesc;
649ddbd7b91SNathan Whitehorn
650ddbd7b91SNathan Whitehorn
651b64e8511SFredrik Holmqvist    ACPI_FUNCTION_TRACE (ExReleaseAllMutexes);
652ddbd7b91SNathan Whitehorn
653ddbd7b91SNathan Whitehorn
654ddbd7b91SNathan Whitehorn    /* Traverse the list of owned mutexes, releasing each one */
655ddbd7b91SNathan Whitehorn
656ddbd7b91SNathan Whitehorn    while (Next)
657ddbd7b91SNathan Whitehorn    {
65879414580SJérôme Duval        ObjDesc = Next;
6599b0d045cSFredrik Holmqvist        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
660b64e8511SFredrik Holmqvist            "Mutex [%4.4s] force-release, SyncLevel %u Depth %u\n",
661b64e8511SFredrik Holmqvist            ObjDesc->Mutex.Node->Name.Ascii, ObjDesc->Mutex.SyncLevel,
662b64e8511SFredrik Holmqvist            ObjDesc->Mutex.AcquisitionDepth));
6639b0d045cSFredrik Holmqvist
66479414580SJérôme Duval        /* Release the mutex, special case for Global Lock */
665ddbd7b91SNathan Whitehorn
6662608583eSJérôme Duval        if (ObjDesc == AcpiGbl_GlobalLockMutex)
66779414580SJérôme Duval        {
66879414580SJérôme Duval            /* Ignore errors */
669ddbd7b91SNathan Whitehorn
67079414580SJérôme Duval            (void) AcpiEvReleaseGlobalLock ();
67179414580SJérôme Duval        }
67279414580SJérôme Duval        else
673ddbd7b91SNathan Whitehorn        {
67479414580SJérôme Duval            AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex);
675ddbd7b91SNathan Whitehorn        }
676ddbd7b91SNathan Whitehorn
677b64e8511SFredrik Holmqvist        /* Update Thread SyncLevel (Last mutex is the important one) */
678b64e8511SFredrik Holmqvist
679b64e8511SFredrik Holmqvist        Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel;
680b64e8511SFredrik Holmqvist
681ddbd7b91SNathan Whitehorn        /* Mark mutex unowned */
682ddbd7b91SNathan Whitehorn
683b64e8511SFredrik Holmqvist        Next = ObjDesc->Mutex.Next;
684b64e8511SFredrik Holmqvist
685b64e8511SFredrik Holmqvist        ObjDesc->Mutex.Prev = NULL;
686b64e8511SFredrik Holmqvist        ObjDesc->Mutex.Next = NULL;
687b64e8511SFredrik Holmqvist        ObjDesc->Mutex.AcquisitionDepth = 0;
68879414580SJérôme Duval        ObjDesc->Mutex.OwnerThread = NULL;
6892608583eSJérôme Duval        ObjDesc->Mutex.ThreadId = 0;
690599289f2SAugustin Cavalier    }
691b64e8511SFredrik Holmqvist
692b64e8511SFredrik Holmqvist    return_VOID;
693ddbd7b91SNathan Whitehorn}
694