1*7851SDana.Myers@Sun.COM 2*7851SDana.Myers@Sun.COM /****************************************************************************** 3*7851SDana.Myers@Sun.COM * 4*7851SDana.Myers@Sun.COM * Module Name: exmutex - ASL Mutex Acquire/Release functions 5*7851SDana.Myers@Sun.COM * $Revision: 1.43 $ 6*7851SDana.Myers@Sun.COM * 7*7851SDana.Myers@Sun.COM *****************************************************************************/ 8*7851SDana.Myers@Sun.COM 9*7851SDana.Myers@Sun.COM /****************************************************************************** 10*7851SDana.Myers@Sun.COM * 11*7851SDana.Myers@Sun.COM * 1. Copyright Notice 12*7851SDana.Myers@Sun.COM * 13*7851SDana.Myers@Sun.COM * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp. 14*7851SDana.Myers@Sun.COM * All rights reserved. 15*7851SDana.Myers@Sun.COM * 16*7851SDana.Myers@Sun.COM * 2. License 17*7851SDana.Myers@Sun.COM * 18*7851SDana.Myers@Sun.COM * 2.1. This is your license from Intel Corp. under its intellectual property 19*7851SDana.Myers@Sun.COM * rights. You may have additional license terms from the party that provided 20*7851SDana.Myers@Sun.COM * you this software, covering your right to use that party's intellectual 21*7851SDana.Myers@Sun.COM * property rights. 22*7851SDana.Myers@Sun.COM * 23*7851SDana.Myers@Sun.COM * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24*7851SDana.Myers@Sun.COM * copy of the source code appearing in this file ("Covered Code") an 25*7851SDana.Myers@Sun.COM * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26*7851SDana.Myers@Sun.COM * base code distributed originally by Intel ("Original Intel Code") to copy, 27*7851SDana.Myers@Sun.COM * make derivatives, distribute, use and display any portion of the Covered 28*7851SDana.Myers@Sun.COM * Code in any form, with the right to sublicense such rights; and 29*7851SDana.Myers@Sun.COM * 30*7851SDana.Myers@Sun.COM * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31*7851SDana.Myers@Sun.COM * license (with the right to sublicense), under only those claims of Intel 32*7851SDana.Myers@Sun.COM * patents that are infringed by the Original Intel Code, to make, use, sell, 33*7851SDana.Myers@Sun.COM * offer to sell, and import the Covered Code and derivative works thereof 34*7851SDana.Myers@Sun.COM * solely to the minimum extent necessary to exercise the above copyright 35*7851SDana.Myers@Sun.COM * license, and in no event shall the patent license extend to any additions 36*7851SDana.Myers@Sun.COM * to or modifications of the Original Intel Code. No other license or right 37*7851SDana.Myers@Sun.COM * is granted directly or by implication, estoppel or otherwise; 38*7851SDana.Myers@Sun.COM * 39*7851SDana.Myers@Sun.COM * The above copyright and patent license is granted only if the following 40*7851SDana.Myers@Sun.COM * conditions are met: 41*7851SDana.Myers@Sun.COM * 42*7851SDana.Myers@Sun.COM * 3. Conditions 43*7851SDana.Myers@Sun.COM * 44*7851SDana.Myers@Sun.COM * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45*7851SDana.Myers@Sun.COM * Redistribution of source code of any substantial portion of the Covered 46*7851SDana.Myers@Sun.COM * Code or modification with rights to further distribute source must include 47*7851SDana.Myers@Sun.COM * the above Copyright Notice, the above License, this list of Conditions, 48*7851SDana.Myers@Sun.COM * and the following Disclaimer and Export Compliance provision. In addition, 49*7851SDana.Myers@Sun.COM * Licensee must cause all Covered Code to which Licensee contributes to 50*7851SDana.Myers@Sun.COM * contain a file documenting the changes Licensee made to create that Covered 51*7851SDana.Myers@Sun.COM * Code and the date of any change. Licensee must include in that file the 52*7851SDana.Myers@Sun.COM * documentation of any changes made by any predecessor Licensee. Licensee 53*7851SDana.Myers@Sun.COM * must include a prominent statement that the modification is derived, 54*7851SDana.Myers@Sun.COM * directly or indirectly, from Original Intel Code. 55*7851SDana.Myers@Sun.COM * 56*7851SDana.Myers@Sun.COM * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57*7851SDana.Myers@Sun.COM * Redistribution of source code of any substantial portion of the Covered 58*7851SDana.Myers@Sun.COM * Code or modification without rights to further distribute source must 59*7851SDana.Myers@Sun.COM * include the following Disclaimer and Export Compliance provision in the 60*7851SDana.Myers@Sun.COM * documentation and/or other materials provided with distribution. In 61*7851SDana.Myers@Sun.COM * addition, Licensee may not authorize further sublicense of source of any 62*7851SDana.Myers@Sun.COM * portion of the Covered Code, and must include terms to the effect that the 63*7851SDana.Myers@Sun.COM * license from Licensee to its licensee is limited to the intellectual 64*7851SDana.Myers@Sun.COM * property embodied in the software Licensee provides to its licensee, and 65*7851SDana.Myers@Sun.COM * not to intellectual property embodied in modifications its licensee may 66*7851SDana.Myers@Sun.COM * make. 67*7851SDana.Myers@Sun.COM * 68*7851SDana.Myers@Sun.COM * 3.3. Redistribution of Executable. Redistribution in executable form of any 69*7851SDana.Myers@Sun.COM * substantial portion of the Covered Code or modification must reproduce the 70*7851SDana.Myers@Sun.COM * above Copyright Notice, and the following Disclaimer and Export Compliance 71*7851SDana.Myers@Sun.COM * provision in the documentation and/or other materials provided with the 72*7851SDana.Myers@Sun.COM * distribution. 73*7851SDana.Myers@Sun.COM * 74*7851SDana.Myers@Sun.COM * 3.4. Intel retains all right, title, and interest in and to the Original 75*7851SDana.Myers@Sun.COM * Intel Code. 76*7851SDana.Myers@Sun.COM * 77*7851SDana.Myers@Sun.COM * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78*7851SDana.Myers@Sun.COM * Intel shall be used in advertising or otherwise to promote the sale, use or 79*7851SDana.Myers@Sun.COM * other dealings in products derived from or relating to the Covered Code 80*7851SDana.Myers@Sun.COM * without prior written authorization from Intel. 81*7851SDana.Myers@Sun.COM * 82*7851SDana.Myers@Sun.COM * 4. Disclaimer and Export Compliance 83*7851SDana.Myers@Sun.COM * 84*7851SDana.Myers@Sun.COM * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85*7851SDana.Myers@Sun.COM * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86*7851SDana.Myers@Sun.COM * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87*7851SDana.Myers@Sun.COM * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88*7851SDana.Myers@Sun.COM * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89*7851SDana.Myers@Sun.COM * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90*7851SDana.Myers@Sun.COM * PARTICULAR PURPOSE. 91*7851SDana.Myers@Sun.COM * 92*7851SDana.Myers@Sun.COM * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93*7851SDana.Myers@Sun.COM * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94*7851SDana.Myers@Sun.COM * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95*7851SDana.Myers@Sun.COM * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96*7851SDana.Myers@Sun.COM * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97*7851SDana.Myers@Sun.COM * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98*7851SDana.Myers@Sun.COM * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99*7851SDana.Myers@Sun.COM * LIMITED REMEDY. 100*7851SDana.Myers@Sun.COM * 101*7851SDana.Myers@Sun.COM * 4.3. Licensee shall not export, either directly or indirectly, any of this 102*7851SDana.Myers@Sun.COM * software or system incorporating such software without first obtaining any 103*7851SDana.Myers@Sun.COM * required license or other approval from the U. S. Department of Commerce or 104*7851SDana.Myers@Sun.COM * any other agency or department of the United States Government. In the 105*7851SDana.Myers@Sun.COM * event Licensee exports any such software from the United States or 106*7851SDana.Myers@Sun.COM * re-exports any such software from a foreign destination, Licensee shall 107*7851SDana.Myers@Sun.COM * ensure that the distribution and export/re-export of the software is in 108*7851SDana.Myers@Sun.COM * compliance with all laws, regulations, orders, or other restrictions of the 109*7851SDana.Myers@Sun.COM * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110*7851SDana.Myers@Sun.COM * any of its subsidiaries will export/re-export any technical data, process, 111*7851SDana.Myers@Sun.COM * software, or service, directly or indirectly, to any country for which the 112*7851SDana.Myers@Sun.COM * United States government or any agency thereof requires an export license, 113*7851SDana.Myers@Sun.COM * other governmental approval, or letter of assurance, without first obtaining 114*7851SDana.Myers@Sun.COM * such license, approval or letter. 115*7851SDana.Myers@Sun.COM * 116*7851SDana.Myers@Sun.COM *****************************************************************************/ 117*7851SDana.Myers@Sun.COM 118*7851SDana.Myers@Sun.COM #define __EXMUTEX_C__ 119*7851SDana.Myers@Sun.COM 120*7851SDana.Myers@Sun.COM #include "acpi.h" 121*7851SDana.Myers@Sun.COM #include "acinterp.h" 122*7851SDana.Myers@Sun.COM #include "acevents.h" 123*7851SDana.Myers@Sun.COM 124*7851SDana.Myers@Sun.COM #define _COMPONENT ACPI_EXECUTER 125*7851SDana.Myers@Sun.COM ACPI_MODULE_NAME ("exmutex") 126*7851SDana.Myers@Sun.COM 127*7851SDana.Myers@Sun.COM /* Local prototypes */ 128*7851SDana.Myers@Sun.COM 129*7851SDana.Myers@Sun.COM static void 130*7851SDana.Myers@Sun.COM AcpiExLinkMutex ( 131*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *ObjDesc, 132*7851SDana.Myers@Sun.COM ACPI_THREAD_STATE *Thread); 133*7851SDana.Myers@Sun.COM 134*7851SDana.Myers@Sun.COM 135*7851SDana.Myers@Sun.COM /******************************************************************************* 136*7851SDana.Myers@Sun.COM * 137*7851SDana.Myers@Sun.COM * FUNCTION: AcpiExUnlinkMutex 138*7851SDana.Myers@Sun.COM * 139*7851SDana.Myers@Sun.COM * PARAMETERS: ObjDesc - The mutex to be unlinked 140*7851SDana.Myers@Sun.COM * 141*7851SDana.Myers@Sun.COM * RETURN: None 142*7851SDana.Myers@Sun.COM * 143*7851SDana.Myers@Sun.COM * DESCRIPTION: Remove a mutex from the "AcquiredMutex" list 144*7851SDana.Myers@Sun.COM * 145*7851SDana.Myers@Sun.COM ******************************************************************************/ 146*7851SDana.Myers@Sun.COM 147*7851SDana.Myers@Sun.COM void 148*7851SDana.Myers@Sun.COM AcpiExUnlinkMutex ( 149*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *ObjDesc) 150*7851SDana.Myers@Sun.COM { 151*7851SDana.Myers@Sun.COM ACPI_THREAD_STATE *Thread = ObjDesc->Mutex.OwnerThread; 152*7851SDana.Myers@Sun.COM 153*7851SDana.Myers@Sun.COM 154*7851SDana.Myers@Sun.COM if (!Thread) 155*7851SDana.Myers@Sun.COM { 156*7851SDana.Myers@Sun.COM return; 157*7851SDana.Myers@Sun.COM } 158*7851SDana.Myers@Sun.COM 159*7851SDana.Myers@Sun.COM /* Doubly linked list */ 160*7851SDana.Myers@Sun.COM 161*7851SDana.Myers@Sun.COM if (ObjDesc->Mutex.Next) 162*7851SDana.Myers@Sun.COM { 163*7851SDana.Myers@Sun.COM (ObjDesc->Mutex.Next)->Mutex.Prev = ObjDesc->Mutex.Prev; 164*7851SDana.Myers@Sun.COM } 165*7851SDana.Myers@Sun.COM 166*7851SDana.Myers@Sun.COM if (ObjDesc->Mutex.Prev) 167*7851SDana.Myers@Sun.COM { 168*7851SDana.Myers@Sun.COM (ObjDesc->Mutex.Prev)->Mutex.Next = ObjDesc->Mutex.Next; 169*7851SDana.Myers@Sun.COM } 170*7851SDana.Myers@Sun.COM else 171*7851SDana.Myers@Sun.COM { 172*7851SDana.Myers@Sun.COM Thread->AcquiredMutexList = ObjDesc->Mutex.Next; 173*7851SDana.Myers@Sun.COM } 174*7851SDana.Myers@Sun.COM } 175*7851SDana.Myers@Sun.COM 176*7851SDana.Myers@Sun.COM 177*7851SDana.Myers@Sun.COM /******************************************************************************* 178*7851SDana.Myers@Sun.COM * 179*7851SDana.Myers@Sun.COM * FUNCTION: AcpiExLinkMutex 180*7851SDana.Myers@Sun.COM * 181*7851SDana.Myers@Sun.COM * PARAMETERS: ObjDesc - The mutex to be linked 182*7851SDana.Myers@Sun.COM * Thread - Current executing thread object 183*7851SDana.Myers@Sun.COM * 184*7851SDana.Myers@Sun.COM * RETURN: None 185*7851SDana.Myers@Sun.COM * 186*7851SDana.Myers@Sun.COM * DESCRIPTION: Add a mutex to the "AcquiredMutex" list for this walk 187*7851SDana.Myers@Sun.COM * 188*7851SDana.Myers@Sun.COM ******************************************************************************/ 189*7851SDana.Myers@Sun.COM 190*7851SDana.Myers@Sun.COM static void 191*7851SDana.Myers@Sun.COM AcpiExLinkMutex ( 192*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *ObjDesc, 193*7851SDana.Myers@Sun.COM ACPI_THREAD_STATE *Thread) 194*7851SDana.Myers@Sun.COM { 195*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *ListHead; 196*7851SDana.Myers@Sun.COM 197*7851SDana.Myers@Sun.COM 198*7851SDana.Myers@Sun.COM ListHead = Thread->AcquiredMutexList; 199*7851SDana.Myers@Sun.COM 200*7851SDana.Myers@Sun.COM /* This object will be the first object in the list */ 201*7851SDana.Myers@Sun.COM 202*7851SDana.Myers@Sun.COM ObjDesc->Mutex.Prev = NULL; 203*7851SDana.Myers@Sun.COM ObjDesc->Mutex.Next = ListHead; 204*7851SDana.Myers@Sun.COM 205*7851SDana.Myers@Sun.COM /* Update old first object to point back to this object */ 206*7851SDana.Myers@Sun.COM 207*7851SDana.Myers@Sun.COM if (ListHead) 208*7851SDana.Myers@Sun.COM { 209*7851SDana.Myers@Sun.COM ListHead->Mutex.Prev = ObjDesc; 210*7851SDana.Myers@Sun.COM } 211*7851SDana.Myers@Sun.COM 212*7851SDana.Myers@Sun.COM /* Update list head */ 213*7851SDana.Myers@Sun.COM 214*7851SDana.Myers@Sun.COM Thread->AcquiredMutexList = ObjDesc; 215*7851SDana.Myers@Sun.COM } 216*7851SDana.Myers@Sun.COM 217*7851SDana.Myers@Sun.COM 218*7851SDana.Myers@Sun.COM /******************************************************************************* 219*7851SDana.Myers@Sun.COM * 220*7851SDana.Myers@Sun.COM * FUNCTION: AcpiExAcquireMutexObject 221*7851SDana.Myers@Sun.COM * 222*7851SDana.Myers@Sun.COM * PARAMETERS: TimeDesc - Timeout in milliseconds 223*7851SDana.Myers@Sun.COM * ObjDesc - Mutex object 224*7851SDana.Myers@Sun.COM * Thread - Current thread state 225*7851SDana.Myers@Sun.COM * 226*7851SDana.Myers@Sun.COM * RETURN: Status 227*7851SDana.Myers@Sun.COM * 228*7851SDana.Myers@Sun.COM * DESCRIPTION: Acquire an AML mutex, low-level interface. Provides a common 229*7851SDana.Myers@Sun.COM * path that supports multiple acquires by the same thread. 230*7851SDana.Myers@Sun.COM * 231*7851SDana.Myers@Sun.COM * MUTEX: Interpreter must be locked 232*7851SDana.Myers@Sun.COM * 233*7851SDana.Myers@Sun.COM * NOTE: This interface is called from three places: 234*7851SDana.Myers@Sun.COM * 1) From AcpiExAcquireMutex, via an AML Acquire() operator 235*7851SDana.Myers@Sun.COM * 2) From AcpiExAcquireGlobalLock when an AML Field access requires the 236*7851SDana.Myers@Sun.COM * global lock 237*7851SDana.Myers@Sun.COM * 3) From the external interface, AcpiAcquireGlobalLock 238*7851SDana.Myers@Sun.COM * 239*7851SDana.Myers@Sun.COM ******************************************************************************/ 240*7851SDana.Myers@Sun.COM 241*7851SDana.Myers@Sun.COM ACPI_STATUS 242*7851SDana.Myers@Sun.COM AcpiExAcquireMutexObject ( 243*7851SDana.Myers@Sun.COM UINT16 Timeout, 244*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *ObjDesc, 245*7851SDana.Myers@Sun.COM ACPI_THREAD_ID ThreadId) 246*7851SDana.Myers@Sun.COM { 247*7851SDana.Myers@Sun.COM ACPI_STATUS Status; 248*7851SDana.Myers@Sun.COM 249*7851SDana.Myers@Sun.COM 250*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE_PTR (ExAcquireMutexObject, ObjDesc); 251*7851SDana.Myers@Sun.COM 252*7851SDana.Myers@Sun.COM 253*7851SDana.Myers@Sun.COM if (!ObjDesc) 254*7851SDana.Myers@Sun.COM { 255*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_BAD_PARAMETER); 256*7851SDana.Myers@Sun.COM } 257*7851SDana.Myers@Sun.COM 258*7851SDana.Myers@Sun.COM /* Support for multiple acquires by the owning thread */ 259*7851SDana.Myers@Sun.COM 260*7851SDana.Myers@Sun.COM if (ObjDesc->Mutex.ThreadId == ThreadId) 261*7851SDana.Myers@Sun.COM { 262*7851SDana.Myers@Sun.COM /* 263*7851SDana.Myers@Sun.COM * The mutex is already owned by this thread, just increment the 264*7851SDana.Myers@Sun.COM * acquisition depth 265*7851SDana.Myers@Sun.COM */ 266*7851SDana.Myers@Sun.COM ObjDesc->Mutex.AcquisitionDepth++; 267*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_OK); 268*7851SDana.Myers@Sun.COM } 269*7851SDana.Myers@Sun.COM 270*7851SDana.Myers@Sun.COM /* Acquire the mutex, wait if necessary. Special case for Global Lock */ 271*7851SDana.Myers@Sun.COM 272*7851SDana.Myers@Sun.COM if (ObjDesc == AcpiGbl_GlobalLockMutex) 273*7851SDana.Myers@Sun.COM { 274*7851SDana.Myers@Sun.COM Status = AcpiEvAcquireGlobalLock (Timeout); 275*7851SDana.Myers@Sun.COM } 276*7851SDana.Myers@Sun.COM else 277*7851SDana.Myers@Sun.COM { 278*7851SDana.Myers@Sun.COM Status = AcpiExSystemWaitMutex (ObjDesc->Mutex.OsMutex, 279*7851SDana.Myers@Sun.COM Timeout); 280*7851SDana.Myers@Sun.COM } 281*7851SDana.Myers@Sun.COM 282*7851SDana.Myers@Sun.COM if (ACPI_FAILURE (Status)) 283*7851SDana.Myers@Sun.COM { 284*7851SDana.Myers@Sun.COM /* Includes failure from a timeout on TimeDesc */ 285*7851SDana.Myers@Sun.COM 286*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 287*7851SDana.Myers@Sun.COM } 288*7851SDana.Myers@Sun.COM 289*7851SDana.Myers@Sun.COM /* Acquired the mutex: update mutex object */ 290*7851SDana.Myers@Sun.COM 291*7851SDana.Myers@Sun.COM ObjDesc->Mutex.ThreadId = ThreadId; 292*7851SDana.Myers@Sun.COM ObjDesc->Mutex.AcquisitionDepth = 1; 293*7851SDana.Myers@Sun.COM ObjDesc->Mutex.OriginalSyncLevel = 0; 294*7851SDana.Myers@Sun.COM ObjDesc->Mutex.OwnerThread = NULL; /* Used only for AML Acquire() */ 295*7851SDana.Myers@Sun.COM 296*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_OK); 297*7851SDana.Myers@Sun.COM } 298*7851SDana.Myers@Sun.COM 299*7851SDana.Myers@Sun.COM 300*7851SDana.Myers@Sun.COM /******************************************************************************* 301*7851SDana.Myers@Sun.COM * 302*7851SDana.Myers@Sun.COM * FUNCTION: AcpiExAcquireMutex 303*7851SDana.Myers@Sun.COM * 304*7851SDana.Myers@Sun.COM * PARAMETERS: TimeDesc - Timeout integer 305*7851SDana.Myers@Sun.COM * ObjDesc - Mutex object 306*7851SDana.Myers@Sun.COM * WalkState - Current method execution state 307*7851SDana.Myers@Sun.COM * 308*7851SDana.Myers@Sun.COM * RETURN: Status 309*7851SDana.Myers@Sun.COM * 310*7851SDana.Myers@Sun.COM * DESCRIPTION: Acquire an AML mutex 311*7851SDana.Myers@Sun.COM * 312*7851SDana.Myers@Sun.COM ******************************************************************************/ 313*7851SDana.Myers@Sun.COM 314*7851SDana.Myers@Sun.COM ACPI_STATUS 315*7851SDana.Myers@Sun.COM AcpiExAcquireMutex ( 316*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *TimeDesc, 317*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *ObjDesc, 318*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState) 319*7851SDana.Myers@Sun.COM { 320*7851SDana.Myers@Sun.COM ACPI_STATUS Status; 321*7851SDana.Myers@Sun.COM 322*7851SDana.Myers@Sun.COM 323*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE_PTR (ExAcquireMutex, ObjDesc); 324*7851SDana.Myers@Sun.COM 325*7851SDana.Myers@Sun.COM 326*7851SDana.Myers@Sun.COM if (!ObjDesc) 327*7851SDana.Myers@Sun.COM { 328*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_BAD_PARAMETER); 329*7851SDana.Myers@Sun.COM } 330*7851SDana.Myers@Sun.COM 331*7851SDana.Myers@Sun.COM /* Must have a valid thread ID */ 332*7851SDana.Myers@Sun.COM 333*7851SDana.Myers@Sun.COM if (!WalkState->Thread) 334*7851SDana.Myers@Sun.COM { 335*7851SDana.Myers@Sun.COM ACPI_ERROR ((AE_INFO, "Cannot acquire Mutex [%4.4s], null thread info", 336*7851SDana.Myers@Sun.COM AcpiUtGetNodeName (ObjDesc->Mutex.Node))); 337*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_AML_INTERNAL); 338*7851SDana.Myers@Sun.COM } 339*7851SDana.Myers@Sun.COM 340*7851SDana.Myers@Sun.COM /* 341*7851SDana.Myers@Sun.COM * Current sync level must be less than or equal to the sync level of the 342*7851SDana.Myers@Sun.COM * mutex. This mechanism provides some deadlock prevention 343*7851SDana.Myers@Sun.COM */ 344*7851SDana.Myers@Sun.COM if (WalkState->Thread->CurrentSyncLevel > ObjDesc->Mutex.SyncLevel) 345*7851SDana.Myers@Sun.COM { 346*7851SDana.Myers@Sun.COM ACPI_ERROR ((AE_INFO, 347*7851SDana.Myers@Sun.COM "Cannot acquire Mutex [%4.4s], current SyncLevel is too large (%d)", 348*7851SDana.Myers@Sun.COM AcpiUtGetNodeName (ObjDesc->Mutex.Node), 349*7851SDana.Myers@Sun.COM WalkState->Thread->CurrentSyncLevel)); 350*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_AML_MUTEX_ORDER); 351*7851SDana.Myers@Sun.COM } 352*7851SDana.Myers@Sun.COM 353*7851SDana.Myers@Sun.COM Status = AcpiExAcquireMutexObject ((UINT16) TimeDesc->Integer.Value, 354*7851SDana.Myers@Sun.COM ObjDesc, WalkState->Thread->ThreadId); 355*7851SDana.Myers@Sun.COM if (ACPI_SUCCESS (Status) && ObjDesc->Mutex.AcquisitionDepth == 1) 356*7851SDana.Myers@Sun.COM { 357*7851SDana.Myers@Sun.COM /* Save Thread object, original/current sync levels */ 358*7851SDana.Myers@Sun.COM 359*7851SDana.Myers@Sun.COM ObjDesc->Mutex.OwnerThread = WalkState->Thread; 360*7851SDana.Myers@Sun.COM ObjDesc->Mutex.OriginalSyncLevel = WalkState->Thread->CurrentSyncLevel; 361*7851SDana.Myers@Sun.COM WalkState->Thread->CurrentSyncLevel = ObjDesc->Mutex.SyncLevel; 362*7851SDana.Myers@Sun.COM 363*7851SDana.Myers@Sun.COM /* Link the mutex to the current thread for force-unlock at method exit */ 364*7851SDana.Myers@Sun.COM 365*7851SDana.Myers@Sun.COM AcpiExLinkMutex (ObjDesc, WalkState->Thread); 366*7851SDana.Myers@Sun.COM } 367*7851SDana.Myers@Sun.COM 368*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 369*7851SDana.Myers@Sun.COM } 370*7851SDana.Myers@Sun.COM 371*7851SDana.Myers@Sun.COM 372*7851SDana.Myers@Sun.COM /******************************************************************************* 373*7851SDana.Myers@Sun.COM * 374*7851SDana.Myers@Sun.COM * FUNCTION: AcpiExReleaseMutexObject 375*7851SDana.Myers@Sun.COM * 376*7851SDana.Myers@Sun.COM * PARAMETERS: ObjDesc - The object descriptor for this op 377*7851SDana.Myers@Sun.COM * 378*7851SDana.Myers@Sun.COM * RETURN: Status 379*7851SDana.Myers@Sun.COM * 380*7851SDana.Myers@Sun.COM * DESCRIPTION: Release a previously acquired Mutex, low level interface. 381*7851SDana.Myers@Sun.COM * Provides a common path that supports multiple releases (after 382*7851SDana.Myers@Sun.COM * previous multiple acquires) by the same thread. 383*7851SDana.Myers@Sun.COM * 384*7851SDana.Myers@Sun.COM * MUTEX: Interpreter must be locked 385*7851SDana.Myers@Sun.COM * 386*7851SDana.Myers@Sun.COM * NOTE: This interface is called from three places: 387*7851SDana.Myers@Sun.COM * 1) From AcpiExReleaseMutex, via an AML Acquire() operator 388*7851SDana.Myers@Sun.COM * 2) From AcpiExReleaseGlobalLock when an AML Field access requires the 389*7851SDana.Myers@Sun.COM * global lock 390*7851SDana.Myers@Sun.COM * 3) From the external interface, AcpiReleaseGlobalLock 391*7851SDana.Myers@Sun.COM * 392*7851SDana.Myers@Sun.COM ******************************************************************************/ 393*7851SDana.Myers@Sun.COM 394*7851SDana.Myers@Sun.COM ACPI_STATUS 395*7851SDana.Myers@Sun.COM AcpiExReleaseMutexObject ( 396*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *ObjDesc) 397*7851SDana.Myers@Sun.COM { 398*7851SDana.Myers@Sun.COM ACPI_STATUS Status = AE_OK; 399*7851SDana.Myers@Sun.COM 400*7851SDana.Myers@Sun.COM 401*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE (ExReleaseMutexObject); 402*7851SDana.Myers@Sun.COM 403*7851SDana.Myers@Sun.COM 404*7851SDana.Myers@Sun.COM if (ObjDesc->Mutex.AcquisitionDepth == 0) 405*7851SDana.Myers@Sun.COM { 406*7851SDana.Myers@Sun.COM return (AE_NOT_ACQUIRED); 407*7851SDana.Myers@Sun.COM } 408*7851SDana.Myers@Sun.COM 409*7851SDana.Myers@Sun.COM /* Match multiple Acquires with multiple Releases */ 410*7851SDana.Myers@Sun.COM 411*7851SDana.Myers@Sun.COM ObjDesc->Mutex.AcquisitionDepth--; 412*7851SDana.Myers@Sun.COM if (ObjDesc->Mutex.AcquisitionDepth != 0) 413*7851SDana.Myers@Sun.COM { 414*7851SDana.Myers@Sun.COM /* Just decrement the depth and return */ 415*7851SDana.Myers@Sun.COM 416*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_OK); 417*7851SDana.Myers@Sun.COM } 418*7851SDana.Myers@Sun.COM 419*7851SDana.Myers@Sun.COM if (ObjDesc->Mutex.OwnerThread) 420*7851SDana.Myers@Sun.COM { 421*7851SDana.Myers@Sun.COM /* Unlink the mutex from the owner's list */ 422*7851SDana.Myers@Sun.COM 423*7851SDana.Myers@Sun.COM AcpiExUnlinkMutex (ObjDesc); 424*7851SDana.Myers@Sun.COM ObjDesc->Mutex.OwnerThread = NULL; 425*7851SDana.Myers@Sun.COM } 426*7851SDana.Myers@Sun.COM 427*7851SDana.Myers@Sun.COM /* Release the mutex, special case for Global Lock */ 428*7851SDana.Myers@Sun.COM 429*7851SDana.Myers@Sun.COM if (ObjDesc == AcpiGbl_GlobalLockMutex) 430*7851SDana.Myers@Sun.COM { 431*7851SDana.Myers@Sun.COM Status = AcpiEvReleaseGlobalLock (); 432*7851SDana.Myers@Sun.COM } 433*7851SDana.Myers@Sun.COM else 434*7851SDana.Myers@Sun.COM { 435*7851SDana.Myers@Sun.COM AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex); 436*7851SDana.Myers@Sun.COM } 437*7851SDana.Myers@Sun.COM 438*7851SDana.Myers@Sun.COM /* Clear mutex info */ 439*7851SDana.Myers@Sun.COM 440*7851SDana.Myers@Sun.COM ObjDesc->Mutex.ThreadId = 0; 441*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 442*7851SDana.Myers@Sun.COM } 443*7851SDana.Myers@Sun.COM 444*7851SDana.Myers@Sun.COM 445*7851SDana.Myers@Sun.COM /******************************************************************************* 446*7851SDana.Myers@Sun.COM * 447*7851SDana.Myers@Sun.COM * FUNCTION: AcpiExReleaseMutex 448*7851SDana.Myers@Sun.COM * 449*7851SDana.Myers@Sun.COM * PARAMETERS: ObjDesc - The object descriptor for this op 450*7851SDana.Myers@Sun.COM * WalkState - Current method execution state 451*7851SDana.Myers@Sun.COM * 452*7851SDana.Myers@Sun.COM * RETURN: Status 453*7851SDana.Myers@Sun.COM * 454*7851SDana.Myers@Sun.COM * DESCRIPTION: Release a previously acquired Mutex. 455*7851SDana.Myers@Sun.COM * 456*7851SDana.Myers@Sun.COM ******************************************************************************/ 457*7851SDana.Myers@Sun.COM 458*7851SDana.Myers@Sun.COM ACPI_STATUS 459*7851SDana.Myers@Sun.COM AcpiExReleaseMutex ( 460*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *ObjDesc, 461*7851SDana.Myers@Sun.COM ACPI_WALK_STATE *WalkState) 462*7851SDana.Myers@Sun.COM { 463*7851SDana.Myers@Sun.COM ACPI_STATUS Status = AE_OK; 464*7851SDana.Myers@Sun.COM 465*7851SDana.Myers@Sun.COM 466*7851SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE (ExReleaseMutex); 467*7851SDana.Myers@Sun.COM 468*7851SDana.Myers@Sun.COM 469*7851SDana.Myers@Sun.COM if (!ObjDesc) 470*7851SDana.Myers@Sun.COM { 471*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_BAD_PARAMETER); 472*7851SDana.Myers@Sun.COM } 473*7851SDana.Myers@Sun.COM 474*7851SDana.Myers@Sun.COM /* The mutex must have been previously acquired in order to release it */ 475*7851SDana.Myers@Sun.COM 476*7851SDana.Myers@Sun.COM if (!ObjDesc->Mutex.OwnerThread) 477*7851SDana.Myers@Sun.COM { 478*7851SDana.Myers@Sun.COM ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], not acquired", 479*7851SDana.Myers@Sun.COM AcpiUtGetNodeName (ObjDesc->Mutex.Node))); 480*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED); 481*7851SDana.Myers@Sun.COM } 482*7851SDana.Myers@Sun.COM 483*7851SDana.Myers@Sun.COM /* 484*7851SDana.Myers@Sun.COM * The Mutex is owned, but this thread must be the owner. 485*7851SDana.Myers@Sun.COM * Special case for Global Lock, any thread can release 486*7851SDana.Myers@Sun.COM */ 487*7851SDana.Myers@Sun.COM if ((ObjDesc->Mutex.OwnerThread->ThreadId != WalkState->Thread->ThreadId) && 488*7851SDana.Myers@Sun.COM (ObjDesc != AcpiGbl_GlobalLockMutex)) 489*7851SDana.Myers@Sun.COM { 490*7851SDana.Myers@Sun.COM ACPI_ERROR ((AE_INFO, 491*7851SDana.Myers@Sun.COM "Thread %X cannot release Mutex [%4.4s] acquired by thread %X", 492*7851SDana.Myers@Sun.COM WalkState->Thread->ThreadId, 493*7851SDana.Myers@Sun.COM AcpiUtGetNodeName (ObjDesc->Mutex.Node), 494*7851SDana.Myers@Sun.COM ObjDesc->Mutex.OwnerThread->ThreadId)); 495*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_AML_NOT_OWNER); 496*7851SDana.Myers@Sun.COM } 497*7851SDana.Myers@Sun.COM 498*7851SDana.Myers@Sun.COM /* Must have a valid thread ID */ 499*7851SDana.Myers@Sun.COM 500*7851SDana.Myers@Sun.COM if (!WalkState->Thread) 501*7851SDana.Myers@Sun.COM { 502*7851SDana.Myers@Sun.COM ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], null thread info", 503*7851SDana.Myers@Sun.COM AcpiUtGetNodeName (ObjDesc->Mutex.Node))); 504*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_AML_INTERNAL); 505*7851SDana.Myers@Sun.COM } 506*7851SDana.Myers@Sun.COM 507*7851SDana.Myers@Sun.COM /* 508*7851SDana.Myers@Sun.COM * The sync level of the mutex must be less than or equal to the current 509*7851SDana.Myers@Sun.COM * sync level 510*7851SDana.Myers@Sun.COM */ 511*7851SDana.Myers@Sun.COM if (ObjDesc->Mutex.SyncLevel > WalkState->Thread->CurrentSyncLevel) 512*7851SDana.Myers@Sun.COM { 513*7851SDana.Myers@Sun.COM ACPI_ERROR ((AE_INFO, 514*7851SDana.Myers@Sun.COM "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d", 515*7851SDana.Myers@Sun.COM AcpiUtGetNodeName (ObjDesc->Mutex.Node), 516*7851SDana.Myers@Sun.COM ObjDesc->Mutex.SyncLevel, WalkState->Thread->CurrentSyncLevel)); 517*7851SDana.Myers@Sun.COM return_ACPI_STATUS (AE_AML_MUTEX_ORDER); 518*7851SDana.Myers@Sun.COM } 519*7851SDana.Myers@Sun.COM 520*7851SDana.Myers@Sun.COM Status = AcpiExReleaseMutexObject (ObjDesc); 521*7851SDana.Myers@Sun.COM 522*7851SDana.Myers@Sun.COM if (ObjDesc->Mutex.AcquisitionDepth == 0) 523*7851SDana.Myers@Sun.COM { 524*7851SDana.Myers@Sun.COM /* Restore the original SyncLevel */ 525*7851SDana.Myers@Sun.COM 526*7851SDana.Myers@Sun.COM WalkState->Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel; 527*7851SDana.Myers@Sun.COM } 528*7851SDana.Myers@Sun.COM return_ACPI_STATUS (Status); 529*7851SDana.Myers@Sun.COM } 530*7851SDana.Myers@Sun.COM 531*7851SDana.Myers@Sun.COM 532*7851SDana.Myers@Sun.COM /******************************************************************************* 533*7851SDana.Myers@Sun.COM * 534*7851SDana.Myers@Sun.COM * FUNCTION: AcpiExReleaseAllMutexes 535*7851SDana.Myers@Sun.COM * 536*7851SDana.Myers@Sun.COM * PARAMETERS: Thread - Current executing thread object 537*7851SDana.Myers@Sun.COM * 538*7851SDana.Myers@Sun.COM * RETURN: Status 539*7851SDana.Myers@Sun.COM * 540*7851SDana.Myers@Sun.COM * DESCRIPTION: Release all mutexes held by this thread 541*7851SDana.Myers@Sun.COM * 542*7851SDana.Myers@Sun.COM * NOTE: This function is called as the thread is exiting the interpreter. 543*7851SDana.Myers@Sun.COM * Mutexes are not released when an individual control method is exited, but 544*7851SDana.Myers@Sun.COM * only when the parent thread actually exits the interpreter. This allows one 545*7851SDana.Myers@Sun.COM * method to acquire a mutex, and a different method to release it, as long as 546*7851SDana.Myers@Sun.COM * this is performed underneath a single parent control method. 547*7851SDana.Myers@Sun.COM * 548*7851SDana.Myers@Sun.COM ******************************************************************************/ 549*7851SDana.Myers@Sun.COM 550*7851SDana.Myers@Sun.COM void 551*7851SDana.Myers@Sun.COM AcpiExReleaseAllMutexes ( 552*7851SDana.Myers@Sun.COM ACPI_THREAD_STATE *Thread) 553*7851SDana.Myers@Sun.COM { 554*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *Next = Thread->AcquiredMutexList; 555*7851SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *ObjDesc; 556*7851SDana.Myers@Sun.COM 557*7851SDana.Myers@Sun.COM 558*7851SDana.Myers@Sun.COM ACPI_FUNCTION_ENTRY (); 559*7851SDana.Myers@Sun.COM 560*7851SDana.Myers@Sun.COM 561*7851SDana.Myers@Sun.COM /* Traverse the list of owned mutexes, releasing each one */ 562*7851SDana.Myers@Sun.COM 563*7851SDana.Myers@Sun.COM while (Next) 564*7851SDana.Myers@Sun.COM { 565*7851SDana.Myers@Sun.COM ObjDesc = Next; 566*7851SDana.Myers@Sun.COM Next = ObjDesc->Mutex.Next; 567*7851SDana.Myers@Sun.COM 568*7851SDana.Myers@Sun.COM ObjDesc->Mutex.Prev = NULL; 569*7851SDana.Myers@Sun.COM ObjDesc->Mutex.Next = NULL; 570*7851SDana.Myers@Sun.COM ObjDesc->Mutex.AcquisitionDepth = 0; 571*7851SDana.Myers@Sun.COM 572*7851SDana.Myers@Sun.COM /* Release the mutex, special case for Global Lock */ 573*7851SDana.Myers@Sun.COM 574*7851SDana.Myers@Sun.COM if (ObjDesc == AcpiGbl_GlobalLockMutex) 575*7851SDana.Myers@Sun.COM { 576*7851SDana.Myers@Sun.COM /* Ignore errors */ 577*7851SDana.Myers@Sun.COM 578*7851SDana.Myers@Sun.COM (void) AcpiEvReleaseGlobalLock (); 579*7851SDana.Myers@Sun.COM } 580*7851SDana.Myers@Sun.COM else 581*7851SDana.Myers@Sun.COM { 582*7851SDana.Myers@Sun.COM AcpiOsReleaseMutex (ObjDesc->Mutex.OsMutex); 583*7851SDana.Myers@Sun.COM } 584*7851SDana.Myers@Sun.COM 585*7851SDana.Myers@Sun.COM /* Mark mutex unowned */ 586*7851SDana.Myers@Sun.COM 587*7851SDana.Myers@Sun.COM ObjDesc->Mutex.OwnerThread = NULL; 588*7851SDana.Myers@Sun.COM ObjDesc->Mutex.ThreadId = 0; 589*7851SDana.Myers@Sun.COM 590*7851SDana.Myers@Sun.COM /* Update Thread SyncLevel (Last mutex is the important one) */ 591*7851SDana.Myers@Sun.COM 592*7851SDana.Myers@Sun.COM Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel; 593*7851SDana.Myers@Sun.COM } 594*7851SDana.Myers@Sun.COM } 595*7851SDana.Myers@Sun.COM 596*7851SDana.Myers@Sun.COM 597