1ae115bc7Smrj /******************************************************************************* 2ae115bc7Smrj * 3ae115bc7Smrj * Module Name: utmutex - local mutex support 4ae115bc7Smrj * 5ae115bc7Smrj ******************************************************************************/ 6ae115bc7Smrj 726f3cdf0SGordon Ross /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 9ae115bc7Smrj * All rights reserved. 10ae115bc7Smrj * 1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1326f3cdf0SGordon Ross * are met: 1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1626f3cdf0SGordon Ross * without modification. 1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2126f3cdf0SGordon Ross * binary redistribution. 2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2426f3cdf0SGordon Ross * from this software without specific prior written permission. 25ae115bc7Smrj * 2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2826f3cdf0SGordon Ross * Software Foundation. 29ae115bc7Smrj * 3026f3cdf0SGordon Ross * NO WARRANTY 3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4226f3cdf0SGordon Ross */ 43ae115bc7Smrj 44ae115bc7Smrj #include "acpi.h" 45aa2aa9a6SDana Myers #include "accommon.h" 46ae115bc7Smrj 47ae115bc7Smrj #define _COMPONENT ACPI_UTILITIES 48ae115bc7Smrj ACPI_MODULE_NAME ("utmutex") 49ae115bc7Smrj 50ae115bc7Smrj /* Local prototypes */ 51ae115bc7Smrj 52ae115bc7Smrj static ACPI_STATUS 53ae115bc7Smrj AcpiUtCreateMutex ( 54ae115bc7Smrj ACPI_MUTEX_HANDLE MutexId); 55ae115bc7Smrj 5626f3cdf0SGordon Ross static void 57ae115bc7Smrj AcpiUtDeleteMutex ( 58ae115bc7Smrj ACPI_MUTEX_HANDLE MutexId); 59ae115bc7Smrj 60ae115bc7Smrj 61ae115bc7Smrj /******************************************************************************* 62ae115bc7Smrj * 63ae115bc7Smrj * FUNCTION: AcpiUtMutexInitialize 64ae115bc7Smrj * 65ae115bc7Smrj * PARAMETERS: None. 66ae115bc7Smrj * 67ae115bc7Smrj * RETURN: Status 68ae115bc7Smrj * 69aa2aa9a6SDana Myers * DESCRIPTION: Create the system mutex objects. This includes mutexes, 70aa2aa9a6SDana Myers * spin locks, and reader/writer locks. 71ae115bc7Smrj * 72ae115bc7Smrj ******************************************************************************/ 73ae115bc7Smrj 74ae115bc7Smrj ACPI_STATUS 75ae115bc7Smrj AcpiUtMutexInitialize ( 76ae115bc7Smrj void) 77ae115bc7Smrj { 78ae115bc7Smrj UINT32 i; 79ae115bc7Smrj ACPI_STATUS Status; 80ae115bc7Smrj 81ae115bc7Smrj 82ae115bc7Smrj ACPI_FUNCTION_TRACE (UtMutexInitialize); 83ae115bc7Smrj 84ae115bc7Smrj 85aa2aa9a6SDana Myers /* Create each of the predefined mutex objects */ 86aa2aa9a6SDana Myers 87ae115bc7Smrj for (i = 0; i < ACPI_NUM_MUTEX; i++) 88ae115bc7Smrj { 89ae115bc7Smrj Status = AcpiUtCreateMutex (i); 90ae115bc7Smrj if (ACPI_FAILURE (Status)) 91ae115bc7Smrj { 92ae115bc7Smrj return_ACPI_STATUS (Status); 93ae115bc7Smrj } 94ae115bc7Smrj } 95ae115bc7Smrj 96*385cc6b4SJerry Jelinek /* Create the spinlocks for use at interrupt level or for speed */ 97ae115bc7Smrj 98ae115bc7Smrj Status = AcpiOsCreateLock (&AcpiGbl_GpeLock); 99ae115bc7Smrj if (ACPI_FAILURE (Status)) 100ae115bc7Smrj { 101ae115bc7Smrj return_ACPI_STATUS (Status); 102ae115bc7Smrj } 103ae115bc7Smrj 104ae115bc7Smrj Status = AcpiOsCreateLock (&AcpiGbl_HardwareLock); 105aa2aa9a6SDana Myers if (ACPI_FAILURE (Status)) 106aa2aa9a6SDana Myers { 107aa2aa9a6SDana Myers return_ACPI_STATUS (Status); 108aa2aa9a6SDana Myers } 109aa2aa9a6SDana Myers 110*385cc6b4SJerry Jelinek Status = AcpiOsCreateLock (&AcpiGbl_ReferenceCountLock); 111*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 112*385cc6b4SJerry Jelinek { 113*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 114*385cc6b4SJerry Jelinek } 115*385cc6b4SJerry Jelinek 11626f3cdf0SGordon Ross /* Mutex for _OSI support */ 117*385cc6b4SJerry Jelinek 11826f3cdf0SGordon Ross Status = AcpiOsCreateMutex (&AcpiGbl_OsiMutex); 11926f3cdf0SGordon Ross if (ACPI_FAILURE (Status)) 12026f3cdf0SGordon Ross { 12126f3cdf0SGordon Ross return_ACPI_STATUS (Status); 12226f3cdf0SGordon Ross } 12326f3cdf0SGordon Ross 124aa2aa9a6SDana Myers /* Create the reader/writer lock for namespace access */ 125aa2aa9a6SDana Myers 126aa2aa9a6SDana Myers Status = AcpiUtCreateRwLock (&AcpiGbl_NamespaceRwLock); 127*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 128*385cc6b4SJerry Jelinek { 129*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 130*385cc6b4SJerry Jelinek } 131*385cc6b4SJerry Jelinek 132*385cc6b4SJerry Jelinek #ifdef ACPI_DEBUGGER 133*385cc6b4SJerry Jelinek 134*385cc6b4SJerry Jelinek /* Debugger Support */ 135*385cc6b4SJerry Jelinek 136*385cc6b4SJerry Jelinek Status = AcpiOsCreateMutex (&AcpiGbl_DbCommandReady); 137*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 138*385cc6b4SJerry Jelinek { 139*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 140*385cc6b4SJerry Jelinek } 141*385cc6b4SJerry Jelinek 142*385cc6b4SJerry Jelinek Status = AcpiOsCreateMutex (&AcpiGbl_DbCommandComplete); 143*385cc6b4SJerry Jelinek #endif 144*385cc6b4SJerry Jelinek 145ae115bc7Smrj return_ACPI_STATUS (Status); 146ae115bc7Smrj } 147ae115bc7Smrj 148ae115bc7Smrj 149ae115bc7Smrj /******************************************************************************* 150ae115bc7Smrj * 151ae115bc7Smrj * FUNCTION: AcpiUtMutexTerminate 152ae115bc7Smrj * 153ae115bc7Smrj * PARAMETERS: None. 154ae115bc7Smrj * 155ae115bc7Smrj * RETURN: None. 156ae115bc7Smrj * 157aa2aa9a6SDana Myers * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes, 158aa2aa9a6SDana Myers * spin locks, and reader/writer locks. 159ae115bc7Smrj * 160ae115bc7Smrj ******************************************************************************/ 161ae115bc7Smrj 162ae115bc7Smrj void 163ae115bc7Smrj AcpiUtMutexTerminate ( 164ae115bc7Smrj void) 165ae115bc7Smrj { 166ae115bc7Smrj UINT32 i; 167ae115bc7Smrj 168ae115bc7Smrj 169ae115bc7Smrj ACPI_FUNCTION_TRACE (UtMutexTerminate); 170ae115bc7Smrj 171ae115bc7Smrj 172aa2aa9a6SDana Myers /* Delete each predefined mutex object */ 173aa2aa9a6SDana Myers 174ae115bc7Smrj for (i = 0; i < ACPI_NUM_MUTEX; i++) 175ae115bc7Smrj { 17626f3cdf0SGordon Ross AcpiUtDeleteMutex (i); 177ae115bc7Smrj } 178ae115bc7Smrj 17926f3cdf0SGordon Ross AcpiOsDeleteMutex (AcpiGbl_OsiMutex); 18026f3cdf0SGordon Ross 181ae115bc7Smrj /* Delete the spinlocks */ 182ae115bc7Smrj 183ae115bc7Smrj AcpiOsDeleteLock (AcpiGbl_GpeLock); 184ae115bc7Smrj AcpiOsDeleteLock (AcpiGbl_HardwareLock); 185*385cc6b4SJerry Jelinek AcpiOsDeleteLock (AcpiGbl_ReferenceCountLock); 186aa2aa9a6SDana Myers 187aa2aa9a6SDana Myers /* Delete the reader/writer lock */ 188aa2aa9a6SDana Myers 189aa2aa9a6SDana Myers AcpiUtDeleteRwLock (&AcpiGbl_NamespaceRwLock); 190*385cc6b4SJerry Jelinek 191*385cc6b4SJerry Jelinek #ifdef ACPI_DEBUGGER 192*385cc6b4SJerry Jelinek AcpiOsDeleteMutex (AcpiGbl_DbCommandReady); 193*385cc6b4SJerry Jelinek AcpiOsDeleteMutex (AcpiGbl_DbCommandComplete); 194*385cc6b4SJerry Jelinek #endif 195*385cc6b4SJerry Jelinek 196ae115bc7Smrj return_VOID; 197ae115bc7Smrj } 198ae115bc7Smrj 199ae115bc7Smrj 200ae115bc7Smrj /******************************************************************************* 201ae115bc7Smrj * 202ae115bc7Smrj * FUNCTION: AcpiUtCreateMutex 203ae115bc7Smrj * 204ae115bc7Smrj * PARAMETERS: MutexID - ID of the mutex to be created 205ae115bc7Smrj * 206ae115bc7Smrj * RETURN: Status 207ae115bc7Smrj * 208ae115bc7Smrj * DESCRIPTION: Create a mutex object. 209ae115bc7Smrj * 210ae115bc7Smrj ******************************************************************************/ 211ae115bc7Smrj 212ae115bc7Smrj static ACPI_STATUS 213ae115bc7Smrj AcpiUtCreateMutex ( 214ae115bc7Smrj ACPI_MUTEX_HANDLE MutexId) 215ae115bc7Smrj { 216ae115bc7Smrj ACPI_STATUS Status = AE_OK; 217ae115bc7Smrj 218ae115bc7Smrj 219ae115bc7Smrj ACPI_FUNCTION_TRACE_U32 (UtCreateMutex, MutexId); 220ae115bc7Smrj 221ae115bc7Smrj 222ae115bc7Smrj if (!AcpiGbl_MutexInfo[MutexId].Mutex) 223ae115bc7Smrj { 224ae115bc7Smrj Status = AcpiOsCreateMutex (&AcpiGbl_MutexInfo[MutexId].Mutex); 225ae115bc7Smrj AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED; 226ae115bc7Smrj AcpiGbl_MutexInfo[MutexId].UseCount = 0; 227ae115bc7Smrj } 228ae115bc7Smrj 229ae115bc7Smrj return_ACPI_STATUS (Status); 230ae115bc7Smrj } 231ae115bc7Smrj 232ae115bc7Smrj 233ae115bc7Smrj /******************************************************************************* 234ae115bc7Smrj * 235ae115bc7Smrj * FUNCTION: AcpiUtDeleteMutex 236ae115bc7Smrj * 237ae115bc7Smrj * PARAMETERS: MutexID - ID of the mutex to be deleted 238ae115bc7Smrj * 239ae115bc7Smrj * RETURN: Status 240ae115bc7Smrj * 241ae115bc7Smrj * DESCRIPTION: Delete a mutex object. 242ae115bc7Smrj * 243ae115bc7Smrj ******************************************************************************/ 244ae115bc7Smrj 24526f3cdf0SGordon Ross static void 246ae115bc7Smrj AcpiUtDeleteMutex ( 247ae115bc7Smrj ACPI_MUTEX_HANDLE MutexId) 248ae115bc7Smrj { 249ae115bc7Smrj 250ae115bc7Smrj ACPI_FUNCTION_TRACE_U32 (UtDeleteMutex, MutexId); 251ae115bc7Smrj 252ae115bc7Smrj 253ae115bc7Smrj AcpiOsDeleteMutex (AcpiGbl_MutexInfo[MutexId].Mutex); 254ae115bc7Smrj 255ae115bc7Smrj AcpiGbl_MutexInfo[MutexId].Mutex = NULL; 256ae115bc7Smrj AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED; 257*385cc6b4SJerry Jelinek 258*385cc6b4SJerry Jelinek return_VOID; 259ae115bc7Smrj } 260ae115bc7Smrj 261ae115bc7Smrj 262ae115bc7Smrj /******************************************************************************* 263ae115bc7Smrj * 264ae115bc7Smrj * FUNCTION: AcpiUtAcquireMutex 265ae115bc7Smrj * 266ae115bc7Smrj * PARAMETERS: MutexID - ID of the mutex to be acquired 267ae115bc7Smrj * 268ae115bc7Smrj * RETURN: Status 269ae115bc7Smrj * 270ae115bc7Smrj * DESCRIPTION: Acquire a mutex object. 271ae115bc7Smrj * 272ae115bc7Smrj ******************************************************************************/ 273ae115bc7Smrj 274ae115bc7Smrj ACPI_STATUS 275ae115bc7Smrj AcpiUtAcquireMutex ( 276ae115bc7Smrj ACPI_MUTEX_HANDLE MutexId) 277ae115bc7Smrj { 278ae115bc7Smrj ACPI_STATUS Status; 279ae115bc7Smrj ACPI_THREAD_ID ThisThreadId; 280ae115bc7Smrj 281ae115bc7Smrj 282ae115bc7Smrj ACPI_FUNCTION_NAME (UtAcquireMutex); 283ae115bc7Smrj 284ae115bc7Smrj 285ae115bc7Smrj if (MutexId > ACPI_MAX_MUTEX) 286ae115bc7Smrj { 287ae115bc7Smrj return (AE_BAD_PARAMETER); 288ae115bc7Smrj } 289ae115bc7Smrj 290ae115bc7Smrj ThisThreadId = AcpiOsGetThreadId (); 291ae115bc7Smrj 292ae115bc7Smrj #ifdef ACPI_MUTEX_DEBUG 293ae115bc7Smrj { 294ae115bc7Smrj UINT32 i; 295ae115bc7Smrj /* 296ae115bc7Smrj * Mutex debug code, for internal debugging only. 297ae115bc7Smrj * 298ae115bc7Smrj * Deadlock prevention. Check if this thread owns any mutexes of value 299ae115bc7Smrj * greater than or equal to this one. If so, the thread has violated 300ae115bc7Smrj * the mutex ordering rule. This indicates a coding error somewhere in 301ae115bc7Smrj * the ACPI subsystem code. 302ae115bc7Smrj */ 303db2bae30SDana Myers for (i = MutexId; i < ACPI_NUM_MUTEX; i++) 304ae115bc7Smrj { 305ae115bc7Smrj if (AcpiGbl_MutexInfo[i].ThreadId == ThisThreadId) 306ae115bc7Smrj { 307ae115bc7Smrj if (i == MutexId) 308ae115bc7Smrj { 309ae115bc7Smrj ACPI_ERROR ((AE_INFO, 31026f3cdf0SGordon Ross "Mutex [%s] already acquired by this thread [%u]", 311aa2aa9a6SDana Myers AcpiUtGetMutexName (MutexId), 31226f3cdf0SGordon Ross (UINT32) ThisThreadId)); 313ae115bc7Smrj 314ae115bc7Smrj return (AE_ALREADY_ACQUIRED); 315ae115bc7Smrj } 316ae115bc7Smrj 317ae115bc7Smrj ACPI_ERROR ((AE_INFO, 31826f3cdf0SGordon Ross "Invalid acquire order: Thread %u owns [%s], wants [%s]", 31926f3cdf0SGordon Ross (UINT32) ThisThreadId, AcpiUtGetMutexName (i), 320ae115bc7Smrj AcpiUtGetMutexName (MutexId))); 321ae115bc7Smrj 322ae115bc7Smrj return (AE_ACQUIRE_DEADLOCK); 323ae115bc7Smrj } 324ae115bc7Smrj } 325ae115bc7Smrj } 326ae115bc7Smrj #endif 327ae115bc7Smrj 328ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, 32926f3cdf0SGordon Ross "Thread %u attempting to acquire Mutex [%s]\n", 33026f3cdf0SGordon Ross (UINT32) ThisThreadId, AcpiUtGetMutexName (MutexId))); 331ae115bc7Smrj 332*385cc6b4SJerry Jelinek Status = AcpiOsAcquireMutex ( 333*385cc6b4SJerry Jelinek AcpiGbl_MutexInfo[MutexId].Mutex, ACPI_WAIT_FOREVER); 334ae115bc7Smrj if (ACPI_SUCCESS (Status)) 335ae115bc7Smrj { 336*385cc6b4SJerry Jelinek ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, 337*385cc6b4SJerry Jelinek "Thread %u acquired Mutex [%s]\n", 33826f3cdf0SGordon Ross (UINT32) ThisThreadId, AcpiUtGetMutexName (MutexId))); 339ae115bc7Smrj 340ae115bc7Smrj AcpiGbl_MutexInfo[MutexId].UseCount++; 341ae115bc7Smrj AcpiGbl_MutexInfo[MutexId].ThreadId = ThisThreadId; 342ae115bc7Smrj } 343ae115bc7Smrj else 344ae115bc7Smrj { 345ae115bc7Smrj ACPI_EXCEPTION ((AE_INFO, Status, 34626f3cdf0SGordon Ross "Thread %u could not acquire Mutex [0x%X]", 34726f3cdf0SGordon Ross (UINT32) ThisThreadId, MutexId)); 348ae115bc7Smrj } 349ae115bc7Smrj 350ae115bc7Smrj return (Status); 351ae115bc7Smrj } 352ae115bc7Smrj 353ae115bc7Smrj 354ae115bc7Smrj /******************************************************************************* 355ae115bc7Smrj * 356ae115bc7Smrj * FUNCTION: AcpiUtReleaseMutex 357ae115bc7Smrj * 358ae115bc7Smrj * PARAMETERS: MutexID - ID of the mutex to be released 359ae115bc7Smrj * 360ae115bc7Smrj * RETURN: Status 361ae115bc7Smrj * 362ae115bc7Smrj * DESCRIPTION: Release a mutex object. 363ae115bc7Smrj * 364ae115bc7Smrj ******************************************************************************/ 365ae115bc7Smrj 366ae115bc7Smrj ACPI_STATUS 367ae115bc7Smrj AcpiUtReleaseMutex ( 368ae115bc7Smrj ACPI_MUTEX_HANDLE MutexId) 369ae115bc7Smrj { 370ae115bc7Smrj ACPI_FUNCTION_NAME (UtReleaseMutex); 371ae115bc7Smrj 372ae115bc7Smrj 37326f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n", 374*385cc6b4SJerry Jelinek (UINT32) AcpiOsGetThreadId (), AcpiUtGetMutexName (MutexId))); 375ae115bc7Smrj 376ae115bc7Smrj if (MutexId > ACPI_MAX_MUTEX) 377ae115bc7Smrj { 378ae115bc7Smrj return (AE_BAD_PARAMETER); 379ae115bc7Smrj } 380ae115bc7Smrj 381ae115bc7Smrj /* 382ae115bc7Smrj * Mutex must be acquired in order to release it! 383ae115bc7Smrj */ 384ae115bc7Smrj if (AcpiGbl_MutexInfo[MutexId].ThreadId == ACPI_MUTEX_NOT_ACQUIRED) 385ae115bc7Smrj { 386ae115bc7Smrj ACPI_ERROR ((AE_INFO, 38726f3cdf0SGordon Ross "Mutex [0x%X] is not acquired, cannot release", MutexId)); 388ae115bc7Smrj 389ae115bc7Smrj return (AE_NOT_ACQUIRED); 390ae115bc7Smrj } 391ae115bc7Smrj 392ae115bc7Smrj #ifdef ACPI_MUTEX_DEBUG 393ae115bc7Smrj { 394ae115bc7Smrj UINT32 i; 395ae115bc7Smrj /* 396ae115bc7Smrj * Mutex debug code, for internal debugging only. 397ae115bc7Smrj * 398ae115bc7Smrj * Deadlock prevention. Check if this thread owns any mutexes of value 399ae115bc7Smrj * greater than this one. If so, the thread has violated the mutex 400ae115bc7Smrj * ordering rule. This indicates a coding error somewhere in 401ae115bc7Smrj * the ACPI subsystem code. 402ae115bc7Smrj */ 403db2bae30SDana Myers for (i = MutexId; i < ACPI_NUM_MUTEX; i++) 404ae115bc7Smrj { 405*385cc6b4SJerry Jelinek if (AcpiGbl_MutexInfo[i].ThreadId == AcpiOsGetThreadId ()) 406ae115bc7Smrj { 407ae115bc7Smrj if (i == MutexId) 408ae115bc7Smrj { 409ae115bc7Smrj continue; 410ae115bc7Smrj } 411ae115bc7Smrj 412ae115bc7Smrj ACPI_ERROR ((AE_INFO, 413ae115bc7Smrj "Invalid release order: owns [%s], releasing [%s]", 414ae115bc7Smrj AcpiUtGetMutexName (i), AcpiUtGetMutexName (MutexId))); 415ae115bc7Smrj 416ae115bc7Smrj return (AE_RELEASE_DEADLOCK); 417ae115bc7Smrj } 418ae115bc7Smrj } 419ae115bc7Smrj } 420ae115bc7Smrj #endif 421ae115bc7Smrj 422ae115bc7Smrj /* Mark unlocked FIRST */ 423ae115bc7Smrj 424ae115bc7Smrj AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED; 425ae115bc7Smrj 426ae115bc7Smrj AcpiOsReleaseMutex (AcpiGbl_MutexInfo[MutexId].Mutex); 427ae115bc7Smrj return (AE_OK); 428ae115bc7Smrj } 429