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