utmutex.c revision 193341
1151937Sjkim/*******************************************************************************
2151937Sjkim *
3151937Sjkim * Module Name: utmutex - local mutex support
4151937Sjkim *
5151937Sjkim ******************************************************************************/
6151937Sjkim
7151937Sjkim/******************************************************************************
8151937Sjkim *
9151937Sjkim * 1. Copyright Notice
10151937Sjkim *
11193267Sjkim * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
12151937Sjkim * All rights reserved.
13151937Sjkim *
14151937Sjkim * 2. License
15151937Sjkim *
16151937Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property
17151937Sjkim * rights.  You may have additional license terms from the party that provided
18151937Sjkim * you this software, covering your right to use that party's intellectual
19151937Sjkim * property rights.
20151937Sjkim *
21151937Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22151937Sjkim * copy of the source code appearing in this file ("Covered Code") an
23151937Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24151937Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy,
25151937Sjkim * make derivatives, distribute, use and display any portion of the Covered
26151937Sjkim * Code in any form, with the right to sublicense such rights; and
27151937Sjkim *
28151937Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29151937Sjkim * license (with the right to sublicense), under only those claims of Intel
30151937Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell,
31151937Sjkim * offer to sell, and import the Covered Code and derivative works thereof
32151937Sjkim * solely to the minimum extent necessary to exercise the above copyright
33151937Sjkim * license, and in no event shall the patent license extend to any additions
34151937Sjkim * to or modifications of the Original Intel Code.  No other license or right
35151937Sjkim * is granted directly or by implication, estoppel or otherwise;
36151937Sjkim *
37151937Sjkim * The above copyright and patent license is granted only if the following
38151937Sjkim * conditions are met:
39151937Sjkim *
40151937Sjkim * 3. Conditions
41151937Sjkim *
42151937Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43151937Sjkim * Redistribution of source code of any substantial portion of the Covered
44151937Sjkim * Code or modification with rights to further distribute source must include
45151937Sjkim * the above Copyright Notice, the above License, this list of Conditions,
46151937Sjkim * and the following Disclaimer and Export Compliance provision.  In addition,
47151937Sjkim * Licensee must cause all Covered Code to which Licensee contributes to
48151937Sjkim * contain a file documenting the changes Licensee made to create that Covered
49151937Sjkim * Code and the date of any change.  Licensee must include in that file the
50151937Sjkim * documentation of any changes made by any predecessor Licensee.  Licensee
51151937Sjkim * must include a prominent statement that the modification is derived,
52151937Sjkim * directly or indirectly, from Original Intel Code.
53151937Sjkim *
54151937Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55151937Sjkim * Redistribution of source code of any substantial portion of the Covered
56151937Sjkim * Code or modification without rights to further distribute source must
57151937Sjkim * include the following Disclaimer and Export Compliance provision in the
58151937Sjkim * documentation and/or other materials provided with distribution.  In
59151937Sjkim * addition, Licensee may not authorize further sublicense of source of any
60151937Sjkim * portion of the Covered Code, and must include terms to the effect that the
61151937Sjkim * license from Licensee to its licensee is limited to the intellectual
62151937Sjkim * property embodied in the software Licensee provides to its licensee, and
63151937Sjkim * not to intellectual property embodied in modifications its licensee may
64151937Sjkim * make.
65151937Sjkim *
66151937Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any
67151937Sjkim * substantial portion of the Covered Code or modification must reproduce the
68151937Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance
69151937Sjkim * provision in the documentation and/or other materials provided with the
70151937Sjkim * distribution.
71151937Sjkim *
72151937Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original
73151937Sjkim * Intel Code.
74151937Sjkim *
75151937Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76151937Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or
77151937Sjkim * other dealings in products derived from or relating to the Covered Code
78151937Sjkim * without prior written authorization from Intel.
79151937Sjkim *
80151937Sjkim * 4. Disclaimer and Export Compliance
81151937Sjkim *
82151937Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83151937Sjkim * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84151937Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85151937Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86151937Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87151937Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88151937Sjkim * PARTICULAR PURPOSE.
89151937Sjkim *
90151937Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91151937Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92151937Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93151937Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94151937Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95151937Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96151937Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97151937Sjkim * LIMITED REMEDY.
98151937Sjkim *
99151937Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this
100151937Sjkim * software or system incorporating such software without first obtaining any
101151937Sjkim * required license or other approval from the U. S. Department of Commerce or
102151937Sjkim * any other agency or department of the United States Government.  In the
103151937Sjkim * event Licensee exports any such software from the United States or
104151937Sjkim * re-exports any such software from a foreign destination, Licensee shall
105151937Sjkim * ensure that the distribution and export/re-export of the software is in
106151937Sjkim * compliance with all laws, regulations, orders, or other restrictions of the
107151937Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108151937Sjkim * any of its subsidiaries will export/re-export any technical data, process,
109151937Sjkim * software, or service, directly or indirectly, to any country for which the
110151937Sjkim * United States government or any agency thereof requires an export license,
111151937Sjkim * other governmental approval, or letter of assurance, without first obtaining
112151937Sjkim * such license, approval or letter.
113151937Sjkim *
114151937Sjkim *****************************************************************************/
115151937Sjkim
116151937Sjkim
117151937Sjkim#define __UTMUTEX_C__
118151937Sjkim
119193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
120193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
121151937Sjkim
122151937Sjkim#define _COMPONENT          ACPI_UTILITIES
123151937Sjkim        ACPI_MODULE_NAME    ("utmutex")
124151937Sjkim
125151937Sjkim/* Local prototypes */
126151937Sjkim
127151937Sjkimstatic ACPI_STATUS
128151937SjkimAcpiUtCreateMutex (
129151937Sjkim    ACPI_MUTEX_HANDLE       MutexId);
130151937Sjkim
131151937Sjkimstatic ACPI_STATUS
132151937SjkimAcpiUtDeleteMutex (
133151937Sjkim    ACPI_MUTEX_HANDLE       MutexId);
134151937Sjkim
135151937Sjkim
136151937Sjkim/*******************************************************************************
137151937Sjkim *
138151937Sjkim * FUNCTION:    AcpiUtMutexInitialize
139151937Sjkim *
140151937Sjkim * PARAMETERS:  None.
141151937Sjkim *
142151937Sjkim * RETURN:      Status
143151937Sjkim *
144193267Sjkim * DESCRIPTION: Create the system mutex objects. This includes mutexes,
145193267Sjkim *              spin locks, and reader/writer locks.
146151937Sjkim *
147151937Sjkim ******************************************************************************/
148151937Sjkim
149151937SjkimACPI_STATUS
150151937SjkimAcpiUtMutexInitialize (
151151937Sjkim    void)
152151937Sjkim{
153151937Sjkim    UINT32                  i;
154151937Sjkim    ACPI_STATUS             Status;
155151937Sjkim
156151937Sjkim
157167802Sjkim    ACPI_FUNCTION_TRACE (UtMutexInitialize);
158151937Sjkim
159151937Sjkim
160193267Sjkim    /* Create each of the predefined mutex objects */
161193267Sjkim
162167802Sjkim    for (i = 0; i < ACPI_NUM_MUTEX; i++)
163151937Sjkim    {
164151937Sjkim        Status = AcpiUtCreateMutex (i);
165151937Sjkim        if (ACPI_FAILURE (Status))
166151937Sjkim        {
167151937Sjkim            return_ACPI_STATUS (Status);
168151937Sjkim        }
169151937Sjkim    }
170151937Sjkim
171167802Sjkim    /* Create the spinlocks for use at interrupt level */
172167802Sjkim
173151937Sjkim    Status = AcpiOsCreateLock (&AcpiGbl_GpeLock);
174167802Sjkim    if (ACPI_FAILURE (Status))
175167802Sjkim    {
176167802Sjkim        return_ACPI_STATUS (Status);
177167802Sjkim    }
178167802Sjkim
179167802Sjkim    Status = AcpiOsCreateLock (&AcpiGbl_HardwareLock);
180193267Sjkim    if (ACPI_FAILURE (Status))
181193267Sjkim    {
182193267Sjkim        return_ACPI_STATUS (Status);
183193267Sjkim    }
184193267Sjkim
185193267Sjkim    /* Create the reader/writer lock for namespace access */
186193267Sjkim
187193267Sjkim    Status = AcpiUtCreateRwLock (&AcpiGbl_NamespaceRwLock);
188151937Sjkim    return_ACPI_STATUS (Status);
189151937Sjkim}
190151937Sjkim
191151937Sjkim
192151937Sjkim/*******************************************************************************
193151937Sjkim *
194151937Sjkim * FUNCTION:    AcpiUtMutexTerminate
195151937Sjkim *
196151937Sjkim * PARAMETERS:  None.
197151937Sjkim *
198151937Sjkim * RETURN:      None.
199151937Sjkim *
200193267Sjkim * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes,
201193267Sjkim *              spin locks, and reader/writer locks.
202151937Sjkim *
203151937Sjkim ******************************************************************************/
204151937Sjkim
205151937Sjkimvoid
206151937SjkimAcpiUtMutexTerminate (
207151937Sjkim    void)
208151937Sjkim{
209151937Sjkim    UINT32                  i;
210151937Sjkim
211151937Sjkim
212167802Sjkim    ACPI_FUNCTION_TRACE (UtMutexTerminate);
213151937Sjkim
214151937Sjkim
215193267Sjkim    /* Delete each predefined mutex object */
216193267Sjkim
217167802Sjkim    for (i = 0; i < ACPI_NUM_MUTEX; i++)
218151937Sjkim    {
219151937Sjkim        (void) AcpiUtDeleteMutex (i);
220151937Sjkim    }
221151937Sjkim
222167802Sjkim    /* Delete the spinlocks */
223167802Sjkim
224151937Sjkim    AcpiOsDeleteLock (AcpiGbl_GpeLock);
225167802Sjkim    AcpiOsDeleteLock (AcpiGbl_HardwareLock);
226193267Sjkim
227193267Sjkim    /* Delete the reader/writer lock */
228193267Sjkim
229193267Sjkim    AcpiUtDeleteRwLock (&AcpiGbl_NamespaceRwLock);
230151937Sjkim    return_VOID;
231151937Sjkim}
232151937Sjkim
233151937Sjkim
234151937Sjkim/*******************************************************************************
235151937Sjkim *
236151937Sjkim * FUNCTION:    AcpiUtCreateMutex
237151937Sjkim *
238151937Sjkim * PARAMETERS:  MutexID         - ID of the mutex to be created
239151937Sjkim *
240151937Sjkim * RETURN:      Status
241151937Sjkim *
242151937Sjkim * DESCRIPTION: Create a mutex object.
243151937Sjkim *
244151937Sjkim ******************************************************************************/
245151937Sjkim
246151937Sjkimstatic ACPI_STATUS
247151937SjkimAcpiUtCreateMutex (
248151937Sjkim    ACPI_MUTEX_HANDLE       MutexId)
249151937Sjkim{
250151937Sjkim    ACPI_STATUS             Status = AE_OK;
251151937Sjkim
252151937Sjkim
253167802Sjkim    ACPI_FUNCTION_TRACE_U32 (UtCreateMutex, MutexId);
254151937Sjkim
255151937Sjkim
256167802Sjkim    if (MutexId > ACPI_MAX_MUTEX)
257151937Sjkim    {
258151937Sjkim        return_ACPI_STATUS (AE_BAD_PARAMETER);
259151937Sjkim    }
260151937Sjkim
261151937Sjkim    if (!AcpiGbl_MutexInfo[MutexId].Mutex)
262151937Sjkim    {
263167802Sjkim        Status = AcpiOsCreateMutex (&AcpiGbl_MutexInfo[MutexId].Mutex);
264151937Sjkim        AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED;
265151937Sjkim        AcpiGbl_MutexInfo[MutexId].UseCount = 0;
266151937Sjkim    }
267151937Sjkim
268151937Sjkim    return_ACPI_STATUS (Status);
269151937Sjkim}
270151937Sjkim
271151937Sjkim
272151937Sjkim/*******************************************************************************
273151937Sjkim *
274151937Sjkim * FUNCTION:    AcpiUtDeleteMutex
275151937Sjkim *
276151937Sjkim * PARAMETERS:  MutexID         - ID of the mutex to be deleted
277151937Sjkim *
278151937Sjkim * RETURN:      Status
279151937Sjkim *
280151937Sjkim * DESCRIPTION: Delete a mutex object.
281151937Sjkim *
282151937Sjkim ******************************************************************************/
283151937Sjkim
284151937Sjkimstatic ACPI_STATUS
285151937SjkimAcpiUtDeleteMutex (
286151937Sjkim    ACPI_MUTEX_HANDLE       MutexId)
287151937Sjkim{
288151937Sjkim
289167802Sjkim    ACPI_FUNCTION_TRACE_U32 (UtDeleteMutex, MutexId);
290151937Sjkim
291151937Sjkim
292167802Sjkim    if (MutexId > ACPI_MAX_MUTEX)
293151937Sjkim    {
294151937Sjkim        return_ACPI_STATUS (AE_BAD_PARAMETER);
295151937Sjkim    }
296151937Sjkim
297167802Sjkim    AcpiOsDeleteMutex (AcpiGbl_MutexInfo[MutexId].Mutex);
298151937Sjkim
299151937Sjkim    AcpiGbl_MutexInfo[MutexId].Mutex = NULL;
300151937Sjkim    AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED;
301151937Sjkim
302167802Sjkim    return_ACPI_STATUS (AE_OK);
303151937Sjkim}
304151937Sjkim
305151937Sjkim
306151937Sjkim/*******************************************************************************
307151937Sjkim *
308151937Sjkim * FUNCTION:    AcpiUtAcquireMutex
309151937Sjkim *
310151937Sjkim * PARAMETERS:  MutexID         - ID of the mutex to be acquired
311151937Sjkim *
312151937Sjkim * RETURN:      Status
313151937Sjkim *
314151937Sjkim * DESCRIPTION: Acquire a mutex object.
315151937Sjkim *
316151937Sjkim ******************************************************************************/
317151937Sjkim
318151937SjkimACPI_STATUS
319151937SjkimAcpiUtAcquireMutex (
320151937Sjkim    ACPI_MUTEX_HANDLE       MutexId)
321151937Sjkim{
322151937Sjkim    ACPI_STATUS             Status;
323167802Sjkim    ACPI_THREAD_ID          ThisThreadId;
324151937Sjkim
325151937Sjkim
326167802Sjkim    ACPI_FUNCTION_NAME (UtAcquireMutex);
327151937Sjkim
328151937Sjkim
329167802Sjkim    if (MutexId > ACPI_MAX_MUTEX)
330151937Sjkim    {
331151937Sjkim        return (AE_BAD_PARAMETER);
332151937Sjkim    }
333151937Sjkim
334151937Sjkim    ThisThreadId = AcpiOsGetThreadId ();
335151937Sjkim
336151937Sjkim#ifdef ACPI_MUTEX_DEBUG
337151937Sjkim    {
338151937Sjkim        UINT32                  i;
339151937Sjkim        /*
340151937Sjkim         * Mutex debug code, for internal debugging only.
341151937Sjkim         *
342151937Sjkim         * Deadlock prevention.  Check if this thread owns any mutexes of value
343151937Sjkim         * greater than or equal to this one.  If so, the thread has violated
344151937Sjkim         * the mutex ordering rule.  This indicates a coding error somewhere in
345151937Sjkim         * the ACPI subsystem code.
346151937Sjkim         */
347193267Sjkim        for (i = MutexId; i < ACPI_NUM_MUTEX; i++)
348151937Sjkim        {
349151937Sjkim            if (AcpiGbl_MutexInfo[i].ThreadId == ThisThreadId)
350151937Sjkim            {
351151937Sjkim                if (i == MutexId)
352151937Sjkim                {
353167802Sjkim                    ACPI_ERROR ((AE_INFO,
354193267Sjkim                        "Mutex [%s] already acquired by this thread [%p]",
355193267Sjkim                        AcpiUtGetMutexName (MutexId),
356193267Sjkim                        ACPI_CAST_PTR (void, ThisThreadId)));
357151937Sjkim
358151937Sjkim                    return (AE_ALREADY_ACQUIRED);
359151937Sjkim                }
360151937Sjkim
361167802Sjkim                ACPI_ERROR ((AE_INFO,
362193267Sjkim                    "Invalid acquire order: Thread %p owns [%s], wants [%s]",
363193267Sjkim                    ACPI_CAST_PTR (void, ThisThreadId), AcpiUtGetMutexName (i),
364151937Sjkim                    AcpiUtGetMutexName (MutexId)));
365151937Sjkim
366151937Sjkim                return (AE_ACQUIRE_DEADLOCK);
367151937Sjkim            }
368151937Sjkim        }
369151937Sjkim    }
370151937Sjkim#endif
371151937Sjkim
372151937Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
373193267Sjkim        "Thread %p attempting to acquire Mutex [%s]\n",
374193267Sjkim        ACPI_CAST_PTR (void, ThisThreadId), AcpiUtGetMutexName (MutexId)));
375151937Sjkim
376167802Sjkim    Status = AcpiOsAcquireMutex (AcpiGbl_MutexInfo[MutexId].Mutex,
377167802Sjkim                ACPI_WAIT_FOREVER);
378151937Sjkim    if (ACPI_SUCCESS (Status))
379151937Sjkim    {
380193267Sjkim        ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %p acquired Mutex [%s]\n",
381193267Sjkim            ACPI_CAST_PTR (void, ThisThreadId), AcpiUtGetMutexName (MutexId)));
382151937Sjkim
383151937Sjkim        AcpiGbl_MutexInfo[MutexId].UseCount++;
384151937Sjkim        AcpiGbl_MutexInfo[MutexId].ThreadId = ThisThreadId;
385151937Sjkim    }
386151937Sjkim    else
387151937Sjkim    {
388167802Sjkim        ACPI_EXCEPTION ((AE_INFO, Status,
389193267Sjkim            "Thread %p could not acquire Mutex [%X]",
390193267Sjkim            ACPI_CAST_PTR (void, ThisThreadId), MutexId));
391151937Sjkim    }
392151937Sjkim
393151937Sjkim    return (Status);
394151937Sjkim}
395151937Sjkim
396151937Sjkim
397151937Sjkim/*******************************************************************************
398151937Sjkim *
399151937Sjkim * FUNCTION:    AcpiUtReleaseMutex
400151937Sjkim *
401151937Sjkim * PARAMETERS:  MutexID         - ID of the mutex to be released
402151937Sjkim *
403151937Sjkim * RETURN:      Status
404151937Sjkim *
405151937Sjkim * DESCRIPTION: Release a mutex object.
406151937Sjkim *
407151937Sjkim ******************************************************************************/
408151937Sjkim
409151937SjkimACPI_STATUS
410151937SjkimAcpiUtReleaseMutex (
411151937Sjkim    ACPI_MUTEX_HANDLE       MutexId)
412151937Sjkim{
413167802Sjkim    ACPI_THREAD_ID          ThisThreadId;
414151937Sjkim
415151937Sjkim
416167802Sjkim    ACPI_FUNCTION_NAME (UtReleaseMutex);
417151937Sjkim
418151937Sjkim
419151937Sjkim    ThisThreadId = AcpiOsGetThreadId ();
420193267Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n",
421193267Sjkim        ACPI_CAST_PTR (void, ThisThreadId), AcpiUtGetMutexName (MutexId)));
422151937Sjkim
423167802Sjkim    if (MutexId > ACPI_MAX_MUTEX)
424151937Sjkim    {
425151937Sjkim        return (AE_BAD_PARAMETER);
426151937Sjkim    }
427151937Sjkim
428151937Sjkim    /*
429151937Sjkim     * Mutex must be acquired in order to release it!
430151937Sjkim     */
431151937Sjkim    if (AcpiGbl_MutexInfo[MutexId].ThreadId == ACPI_MUTEX_NOT_ACQUIRED)
432151937Sjkim    {
433167802Sjkim        ACPI_ERROR ((AE_INFO,
434167802Sjkim            "Mutex [%X] is not acquired, cannot release", MutexId));
435151937Sjkim
436151937Sjkim        return (AE_NOT_ACQUIRED);
437151937Sjkim    }
438151937Sjkim
439151937Sjkim#ifdef ACPI_MUTEX_DEBUG
440151937Sjkim    {
441151937Sjkim        UINT32                  i;
442151937Sjkim        /*
443151937Sjkim         * Mutex debug code, for internal debugging only.
444151937Sjkim         *
445151937Sjkim         * Deadlock prevention.  Check if this thread owns any mutexes of value
446151937Sjkim         * greater than this one.  If so, the thread has violated the mutex
447151937Sjkim         * ordering rule.  This indicates a coding error somewhere in
448151937Sjkim         * the ACPI subsystem code.
449151937Sjkim         */
450193267Sjkim        for (i = MutexId; i < ACPI_NUM_MUTEX; i++)
451151937Sjkim        {
452151937Sjkim            if (AcpiGbl_MutexInfo[i].ThreadId == ThisThreadId)
453151937Sjkim            {
454151937Sjkim                if (i == MutexId)
455151937Sjkim                {
456151937Sjkim                    continue;
457151937Sjkim                }
458151937Sjkim
459167802Sjkim                ACPI_ERROR ((AE_INFO,
460167802Sjkim                    "Invalid release order: owns [%s], releasing [%s]",
461151937Sjkim                    AcpiUtGetMutexName (i), AcpiUtGetMutexName (MutexId)));
462151937Sjkim
463151937Sjkim                return (AE_RELEASE_DEADLOCK);
464151937Sjkim            }
465151937Sjkim        }
466151937Sjkim    }
467151937Sjkim#endif
468151937Sjkim
469151937Sjkim    /* Mark unlocked FIRST */
470151937Sjkim
471151937Sjkim    AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED;
472151937Sjkim
473167802Sjkim    AcpiOsReleaseMutex (AcpiGbl_MutexInfo[MutexId].Mutex);
474167802Sjkim    return (AE_OK);
475151937Sjkim}
476151937Sjkim
477151937Sjkim
478