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