evmisc.c revision 151600
150276Speter/****************************************************************************** 2178866Srafan * 350276Speter * Module Name: evmisc - Miscellaneous event manager support functions 450276Speter * $Revision: 79 $ 550276Speter * 650276Speter *****************************************************************************/ 750276Speter 850276Speter/****************************************************************************** 950276Speter * 1050276Speter * 1. Copyright Notice 1150276Speter * 1250276Speter * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp. 1350276Speter * All rights reserved. 1450276Speter * 1550276Speter * 2. License 1650276Speter * 1750276Speter * 2.1. This is your license from Intel Corp. under its intellectual property 1850276Speter * rights. You may have additional license terms from the party that provided 1950276Speter * you this software, covering your right to use that party's intellectual 2050276Speter * property rights. 2150276Speter * 2250276Speter * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2350276Speter * copy of the source code appearing in this file ("Covered Code") an 2450276Speter * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2550276Speter * base code distributed originally by Intel ("Original Intel Code") to copy, 2650276Speter * make derivatives, distribute, use and display any portion of the Covered 2750276Speter * Code in any form, with the right to sublicense such rights; and 2850276Speter * 29166124Srafan * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3050276Speter * license (with the right to sublicense), under only those claims of Intel 31184989Srafan * patents that are infringed by the Original Intel Code, to make, use, sell, 3250276Speter * offer to sell, and import the Covered Code and derivative works thereof 3350276Speter * solely to the minimum extent necessary to exercise the above copyright 34166124Srafan * license, and in no event shall the patent license extend to any additions 35166124Srafan * to or modifications of the Original Intel Code. No other license or right 36166124Srafan * is granted directly or by implication, estoppel or otherwise; 3766963Speter * 38166124Srafan * The above copyright and patent license is granted only if the following 39166124Srafan * conditions are met: 4050276Speter * 4150276Speter * 3. Conditions 42166124Srafan * 43166124Srafan * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44166124Srafan * Redistribution of source code of any substantial portion of the Covered 45166124Srafan * Code or modification with rights to further distribute source must include 46166124Srafan * the above Copyright Notice, the above License, this list of Conditions, 47166124Srafan * and the following Disclaimer and Export Compliance provision. In addition, 48166124Srafan * Licensee must cause all Covered Code to which Licensee contributes to 49166124Srafan * contain a file documenting the changes Licensee made to create that Covered 50166124Srafan * Code and the date of any change. Licensee must include in that file the 51166124Srafan * documentation of any changes made by any predecessor Licensee. Licensee 52166124Srafan * must include a prominent statement that the modification is derived, 53166124Srafan * directly or indirectly, from Original Intel Code. 54166124Srafan * 55166124Srafan * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56166124Srafan * Redistribution of source code of any substantial portion of the Covered 57166124Srafan * Code or modification without rights to further distribute source must 58166124Srafan * include the following Disclaimer and Export Compliance provision in the 59166124Srafan * documentation and/or other materials provided with distribution. In 60166124Srafan * addition, Licensee may not authorize further sublicense of source of any 61166124Srafan * portion of the Covered Code, and must include terms to the effect that the 62166124Srafan * license from Licensee to its licensee is limited to the intellectual 63166124Srafan * property embodied in the software Licensee provides to its licensee, and 64166124Srafan * not to intellectual property embodied in modifications its licensee may 65166124Srafan * make. 66166124Srafan * 6750276Speter * 3.3. Redistribution of Executable. Redistribution in executable form of any 6850276Speter * substantial portion of the Covered Code or modification must reproduce the 6950276Speter * above Copyright Notice, and the following Disclaimer and Export Compliance 7050276Speter * provision in the documentation and/or other materials provided with the 71166124Srafan * distribution. 7250276Speter * 73166124Srafan * 3.4. Intel retains all right, title, and interest in and to the Original 7450276Speter * Intel Code. 7566963Speter * 76166124Srafan * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7750276Speter * Intel shall be used in advertising or otherwise to promote the sale, use or 7850276Speter * other dealings in products derived from or relating to the Covered Code 7950276Speter * without prior written authorization from Intel. 80166124Srafan * 8150276Speter * 4. Disclaimer and Export Compliance 8250276Speter * 83166124Srafan * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8450276Speter * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8550276Speter * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8650276Speter * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8750276Speter * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8850276Speter * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89166124Srafan * PARTICULAR PURPOSE. 90166124Srafan * 9176726Speter * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9297049Speter * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93166124Srafan * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94166124Srafan * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95166124Srafan * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96166124Srafan * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9776726Speter * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9876726Speter * LIMITED REMEDY. 99166124Srafan * 10097049Speter * 4.3. Licensee shall not export, either directly or indirectly, any of this 10197049Speter * software or system incorporating such software without first obtaining any 102166124Srafan * required license or other approval from the U. S. Department of Commerce or 103166124Srafan * any other agency or department of the United States Government. In the 10476726Speter * event Licensee exports any such software from the United States or 10576726Speter * re-exports any such software from a foreign destination, Licensee shall 106166124Srafan * ensure that the distribution and export/re-export of the software is in 107166124Srafan * compliance with all laws, regulations, orders, or other restrictions of the 10876726Speter * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10976726Speter * any of its subsidiaries will export/re-export any technical data, process, 110166124Srafan * software, or service, directly or indirectly, to any country for which the 111166124Srafan * United States government or any agency thereof requires an export license, 112166124Srafan * other governmental approval, or letter of assurance, without first obtaining 113166124Srafan * such license, approval or letter. 114166124Srafan * 115166124Srafan *****************************************************************************/ 116166124Srafan 117166124Srafan#include <contrib/dev/acpica/acpi.h> 118166124Srafan#include <contrib/dev/acpica/acevents.h> 119166124Srafan#include <contrib/dev/acpica/acnamesp.h> 120166124Srafan#include <contrib/dev/acpica/acinterp.h> 121166124Srafan 122166124Srafan#define _COMPONENT ACPI_EVENTS 123166124Srafan ACPI_MODULE_NAME ("evmisc") 124166124Srafan 125166124Srafan 126166124Srafan/******************************************************************************* 12776726Speter * 12897049Speter * FUNCTION: AcpiEvIsNotifyObject 12976726Speter * 13097049Speter * PARAMETERS: Node - Node to check 13197049Speter * 13276726Speter * RETURN: TRUE if notifies allowed on this object 13376726Speter * 13476726Speter * DESCRIPTION: Check type of node for a object that supports notifies. 13576726Speter * 13697049Speter * TBD: This could be replaced by a flag bit in the node. 13776726Speter * 13876726Speter ******************************************************************************/ 139166124Srafan 140166124SrafanBOOLEAN 141166124SrafanAcpiEvIsNotifyObject ( 142166124Srafan ACPI_NAMESPACE_NODE *Node) 143166124Srafan{ 144166124Srafan switch (Node->Type) 145166124Srafan { 146166124Srafan case ACPI_TYPE_DEVICE: 147166124Srafan case ACPI_TYPE_PROCESSOR: 148166124Srafan case ACPI_TYPE_POWER: 149166124Srafan case ACPI_TYPE_THERMAL: 15076726Speter /* 15197049Speter * These are the ONLY objects that can receive ACPI notifications 15297049Speter */ 15397049Speter return (TRUE); 15497049Speter 15597049Speter default: 15697049Speter return (FALSE); 15797049Speter } 15897049Speter} 159166124Srafan 16097049Speter 16197049Speter/******************************************************************************* 162166124Srafan * 163166124Srafan * FUNCTION: AcpiEvQueueNotifyRequest 164166124Srafan * 165166124Srafan * PARAMETERS: Node - NS node for the notified object 166166124Srafan * NotifyValue - Value from the Notify() request 167166124Srafan * 168166124Srafan * RETURN: Status 16976726Speter * 17076726Speter * DESCRIPTION: Dispatch a device notification event to a previously 171178866Srafan * installed handler. 172174993Srafan * 173174993Srafan ******************************************************************************/ 174174993Srafan 175174993Srafan#ifdef ACPI_DEBUG_OUTPUT 176174993Srafanstatic const char *AcpiNotifyValueNames[] = 177174993Srafan{ 178174993Srafan "Bus Check", 179174993Srafan "Device Check", 180174993Srafan "Device Wake", 181174993Srafan "Eject request", 182174993Srafan "Device Check Light", 183174993Srafan "Frequency Mismatch", 184174993Srafan "Bus Mode Mismatch", 185174993Srafan "Power Fault" 186174993Srafan}; 187174993Srafan#endif 188174993Srafan 189174993SrafanACPI_STATUS 190174993SrafanAcpiEvQueueNotifyRequest ( 191174993Srafan ACPI_NAMESPACE_NODE *Node, 192174993Srafan UINT32 NotifyValue) 193174993Srafan{ 194174993Srafan ACPI_OPERAND_OBJECT *ObjDesc; 195174993Srafan ACPI_OPERAND_OBJECT *HandlerObj = NULL; 196174993Srafan ACPI_GENERIC_STATE *NotifyInfo; 197174993Srafan ACPI_STATUS Status = AE_OK; 198174993Srafan 199174993Srafan 200174993Srafan ACPI_FUNCTION_NAME ("EvQueueNotifyRequest"); 201174993Srafan 202174993Srafan 203174993Srafan /* 204174993Srafan * For value 3 (Ejection Request), some device method may need to be run. 205174993Srafan * For value 2 (Device Wake) if _PRW exists, the _PS0 method may need to be run. 206174993Srafan * For value 0x80 (Status Change) on the power button or sleep button, 207174993Srafan * initiate soft-off or sleep operation? 208174993Srafan */ 209174993Srafan ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 210174993Srafan "Dispatching Notify(%X) on node %p\n", NotifyValue, Node)); 211174993Srafan 212174993Srafan if (NotifyValue <= 7) 213178866Srafan { 214174993Srafan ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: %s\n", 215174993Srafan AcpiNotifyValueNames[NotifyValue])); 216174993Srafan } 217174993Srafan else 218174993Srafan { 219174993Srafan ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: 0x%2.2X **Device Specific**\n", 220174993Srafan NotifyValue)); 221174993Srafan } 222174993Srafan 223174993Srafan /* Get the notify object attached to the NS Node */ 224174993Srafan 225174993Srafan ObjDesc = AcpiNsGetAttachedObject (Node); 226174993Srafan if (ObjDesc) 227174993Srafan { 228178866Srafan /* We have the notify object, Get the right handler */ 229174993Srafan 230174993Srafan switch (Node->Type) 231174993Srafan { 232174993Srafan case ACPI_TYPE_DEVICE: 233174993Srafan case ACPI_TYPE_THERMAL: 234174993Srafan case ACPI_TYPE_PROCESSOR: 235174993Srafan case ACPI_TYPE_POWER: 236174993Srafan 237174993Srafan if (NotifyValue <= ACPI_MAX_SYS_NOTIFY) 238174993Srafan { 239174993Srafan HandlerObj = ObjDesc->CommonNotify.SystemNotify; 240174993Srafan } 241174993Srafan else 242174993Srafan { 243174993Srafan HandlerObj = ObjDesc->CommonNotify.DeviceNotify; 244174993Srafan } 245174993Srafan break; 246174993Srafan 247174993Srafan default: 248174993Srafan /* All other types are not supported */ 249174993Srafan return (AE_TYPE); 250174993Srafan } 251174993Srafan } 252174993Srafan 253174993Srafan /* If there is any handler to run, schedule the dispatcher */ 254174993Srafan 255174993Srafan if ((AcpiGbl_SystemNotify.Handler && (NotifyValue <= ACPI_MAX_SYS_NOTIFY)) || 256178866Srafan (AcpiGbl_DeviceNotify.Handler && (NotifyValue > ACPI_MAX_SYS_NOTIFY)) || 257174993Srafan HandlerObj) 258174993Srafan { 259174993Srafan NotifyInfo = AcpiUtCreateGenericState (); 260174993Srafan if (!NotifyInfo) 261174993Srafan { 262174993Srafan return (AE_NO_MEMORY); 263174993Srafan } 264184989Srafan 265184989Srafan NotifyInfo->Common.DataType = ACPI_DESC_TYPE_STATE_NOTIFY; 266184989Srafan NotifyInfo->Notify.Node = Node; 267184989Srafan NotifyInfo->Notify.Value = (UINT16) NotifyValue; 268184989Srafan NotifyInfo->Notify.HandlerObj = HandlerObj; 269184989Srafan 270184989Srafan Status = AcpiOsQueueForExecution (OSD_PRIORITY_HIGH, 271184989Srafan AcpiEvNotifyDispatch, NotifyInfo); 272184989Srafan if (ACPI_FAILURE (Status)) 273184989Srafan { 274184989Srafan AcpiUtDeleteGenericState (NotifyInfo); 275184989Srafan } 276184989Srafan } 277184989Srafan 278184989Srafan if (!HandlerObj) 279184989Srafan { 280184989Srafan /* 281184989Srafan * There is no per-device notify handler for this device. 282184989Srafan * This may or may not be a problem. 283184989Srafan */ 284184989Srafan ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 285184989Srafan "No notify handler for Notify(%4.4s, %X) node %p\n", 286166124Srafan AcpiUtGetNodeName (Node), NotifyValue, Node)); 287166124Srafan } 28850276Speter 28950276Speter return (Status); 29050276Speter} 29150276Speter 29297049Speter 29350276Speter/******************************************************************************* 29450276Speter * 29576726Speter * FUNCTION: AcpiEvNotifyDispatch 29650276Speter * 29750276Speter * PARAMETERS: Context - To be passsed to the notify handler 29850276Speter * 29950276Speter * RETURN: None. 30050276Speter * 30150276Speter * DESCRIPTION: Dispatch a device notification event to a previously 30250276Speter * installed handler. 30350276Speter * 30450276Speter ******************************************************************************/ 30550276Speter 30650276Spetervoid ACPI_SYSTEM_XFACE 30762449SpeterAcpiEvNotifyDispatch ( 30850276Speter void *Context) 30950276Speter{ 31050276Speter ACPI_GENERIC_STATE *NotifyInfo = (ACPI_GENERIC_STATE *) Context; 31176726Speter ACPI_NOTIFY_HANDLER GlobalHandler = NULL; 31250276Speter void *GlobalContext = NULL; 31350276Speter ACPI_OPERAND_OBJECT *HandlerObj; 31450276Speter 31550276Speter 31650276Speter ACPI_FUNCTION_ENTRY (); 31750276Speter 31850276Speter 31950276Speter /* 32050276Speter * We will invoke a global notify handler if installed. 32150276Speter * This is done _before_ we invoke the per-device handler attached to the device. 32250276Speter */ 32350276Speter if (NotifyInfo->Notify.Value <= ACPI_MAX_SYS_NOTIFY) 32450276Speter { 32550276Speter /* Global system notification handler */ 32676726Speter 32750276Speter if (AcpiGbl_SystemNotify.Handler) 32850276Speter { 32950276Speter GlobalHandler = AcpiGbl_SystemNotify.Handler; 33050276Speter GlobalContext = AcpiGbl_SystemNotify.Context; 33176726Speter } 33250276Speter } 33350276Speter else 33450276Speter { 33550276Speter /* Global driver notification handler */ 33650276Speter 33750276Speter if (AcpiGbl_DeviceNotify.Handler) 338178866Srafan { 339166124Srafan GlobalHandler = AcpiGbl_DeviceNotify.Handler; 34050276Speter GlobalContext = AcpiGbl_DeviceNotify.Context; 34150276Speter } 34250276Speter } 34350276Speter 34450276Speter /* Invoke the system handler first, if present */ 34550276Speter 34650276Speter if (GlobalHandler) 347178866Srafan { 34850276Speter GlobalHandler (NotifyInfo->Notify.Node, NotifyInfo->Notify.Value, GlobalContext); 34950276Speter } 35050276Speter 35150276Speter /* Now invoke the per-device handler, if present */ 35250276Speter 35350276Speter HandlerObj = NotifyInfo->Notify.HandlerObj; 35450276Speter if (HandlerObj) 35550276Speter { 356184989Srafan HandlerObj->Notify.Handler (NotifyInfo->Notify.Node, NotifyInfo->Notify.Value, 357184989Srafan HandlerObj->Notify.Context); 358184989Srafan } 359184989Srafan 360184989Srafan /* All done with the info object */ 361184989Srafan 362184989Srafan AcpiUtDeleteGenericState (NotifyInfo); 363184989Srafan} 364184989Srafan 365184989Srafan 366184989Srafan/******************************************************************************* 367184989Srafan * 368184989Srafan * FUNCTION: AcpiEvGlobalLockThread 369184989Srafan * 370184989Srafan * PARAMETERS: Context - From thread interface, not used 371184989Srafan * 372184989Srafan * RETURN: None 373184989Srafan * 374184989Srafan * DESCRIPTION: Invoked by SCI interrupt handler upon acquisition of the 375184989Srafan * Global Lock. Simply signal all threads that are waiting 376184989Srafan * for the lock. 377184989Srafan * 378184989Srafan ******************************************************************************/ 379184989Srafan 380166124Srafanstatic void ACPI_SYSTEM_XFACE 381166124SrafanAcpiEvGlobalLockThread ( 38250276Speter void *Context) 38350276Speter{ 38450276Speter ACPI_STATUS Status; 38550276Speter 38650276Speter 38750276Speter /* Signal threads that are waiting for the lock */ 388166124Srafan 389166124Srafan if (AcpiGbl_GlobalLockThreadCount) 39050276Speter { 39150276Speter /* Send sufficient units to the semaphore */ 392166124Srafan 393166124Srafan Status = AcpiOsSignalSemaphore (AcpiGbl_GlobalLockSemaphore, 394166124Srafan AcpiGbl_GlobalLockThreadCount); 395166124Srafan if (ACPI_FAILURE (Status)) 396166124Srafan { 397166124Srafan ACPI_REPORT_ERROR (("Could not signal Global Lock semaphore\n")); 398166124Srafan } 399166124Srafan } 400166124Srafan} 401166124Srafan 402166124Srafan 403166124Srafan/******************************************************************************* 404166124Srafan * 405166124Srafan * FUNCTION: AcpiEvGlobalLockHandler 406166124Srafan * 407166124Srafan * PARAMETERS: Context - From thread interface, not used 408166124Srafan * 409166124Srafan * RETURN: ACPI_INTERRUPT_HANDLED or ACPI_INTERRUPT_NOT_HANDLED 41066963Speter * 411166124Srafan * DESCRIPTION: Invoked directly from the SCI handler when a global lock 41250276Speter * release interrupt occurs. Grab the global lock and queue 41350276Speter * the global lock thread for execution 41450276Speter * 41550276Speter ******************************************************************************/ 41650276Speter 41750276Speterstatic UINT32 41850276SpeterAcpiEvGlobalLockHandler ( 41950276Speter void *Context) 420166124Srafan{ 42166963Speter BOOLEAN Acquired = FALSE; 42250276Speter ACPI_STATUS Status; 42350276Speter 42450276Speter 42550276Speter /* 42650276Speter * Attempt to get the lock 427166124Srafan * If we don't get it now, it will be marked pending and we will 428166124Srafan * take another interrupt when it becomes free. 42950276Speter */ 43050276Speter ACPI_ACQUIRE_GLOBAL_LOCK (AcpiGbl_CommonFACS.GlobalLock, Acquired); 43197049Speter if (Acquired) 43297049Speter { 43397049Speter /* Got the lock, now wake all threads waiting for it */ 43450276Speter 43550276Speter AcpiGbl_GlobalLockAcquired = TRUE; 43666963Speter 43750276Speter /* Run the Global Lock thread which will signal all waiting threads */ 43850276Speter 43950276Speter Status = AcpiOsQueueForExecution (OSD_PRIORITY_HIGH, 44050276Speter AcpiEvGlobalLockThread, Context); 44150276Speter if (ACPI_FAILURE (Status)) 44297049Speter { 44397049Speter ACPI_REPORT_ERROR (("Could not queue Global Lock thread, %s\n", 44497049Speter AcpiFormatException (Status))); 44566963Speter 44656639Speter return (ACPI_INTERRUPT_NOT_HANDLED); 44756639Speter } 44856639Speter } 44956639Speter 45050276Speter return (ACPI_INTERRUPT_HANDLED); 45150276Speter} 45297049Speter 45397049Speter 45497049Speter/******************************************************************************* 45597049Speter * 45697049Speter * FUNCTION: AcpiEvInitGlobalLockHandler 45797049Speter * 45897049Speter * PARAMETERS: None 45997049Speter * 46097049Speter * RETURN: Status 46150276Speter * 46250276Speter * DESCRIPTION: Install a handler for the global lock release event 46350276Speter * 46450276Speter ******************************************************************************/ 46550276Speter 46650276SpeterACPI_STATUS 46750276SpeterAcpiEvInitGlobalLockHandler (void) 46850276Speter{ 46950276Speter ACPI_STATUS Status; 47050276Speter 47150276Speter 47250276Speter ACPI_FUNCTION_TRACE ("EvInitGlobalLockHandler"); 47350276Speter 474166124Srafan 47550276Speter AcpiGbl_GlobalLockPresent = TRUE; 47650276Speter Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL, 47797049Speter AcpiEvGlobalLockHandler, NULL); 47897049Speter 47997049Speter /* 48097049Speter * If the global lock does not exist on this platform, the attempt 48150276Speter * to enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick) 48250276Speter * Map to AE_OK, but mark global lock as not present. 48350276Speter * Any attempt to actually use the global lock will be flagged 48450276Speter * with an error. 48550276Speter */ 48650276Speter if (Status == AE_NO_HARDWARE_RESPONSE) 48797049Speter { 48897049Speter AcpiGbl_GlobalLockPresent = FALSE; 48997049Speter Status = AE_OK; 49097049Speter } 49197049Speter 49250276Speter return_ACPI_STATUS (Status); 49350276Speter} 49450276Speter 495166124Srafan 496166124Srafan/****************************************************************************** 497166124Srafan * 498166124Srafan * FUNCTION: AcpiEvAcquireGlobalLock 499166124Srafan * 500166124Srafan * PARAMETERS: Timeout - Max time to wait for the lock, in millisec. 501166124Srafan * 502166124Srafan * RETURN: Status 503166124Srafan * 504166124Srafan * DESCRIPTION: Attempt to gain ownership of the Global Lock. 505166124Srafan * 506166124Srafan *****************************************************************************/ 507166124Srafan 508166124SrafanACPI_STATUS 509166124SrafanAcpiEvAcquireGlobalLock ( 510166124Srafan UINT16 Timeout) 511166124Srafan{ 512166124Srafan ACPI_STATUS Status = AE_OK; 513166124Srafan BOOLEAN Acquired = FALSE; 514166124Srafan 515166124Srafan 516166124Srafan ACPI_FUNCTION_TRACE ("EvAcquireGlobalLock"); 517166124Srafan 518166124Srafan 519166124Srafan#ifndef ACPI_APPLICATION 520166124Srafan /* Make sure that we actually have a global lock */ 521166124Srafan 522166124Srafan if (!AcpiGbl_GlobalLockPresent) 523166124Srafan { 524166124Srafan return_ACPI_STATUS (AE_NO_GLOBAL_LOCK); 525166124Srafan } 526166124Srafan#endif 527166124Srafan 528166124Srafan /* One more thread wants the global lock */ 529166124Srafan 530166124Srafan AcpiGbl_GlobalLockThreadCount++; 531166124Srafan 532166124Srafan /* If we (OS side vs. BIOS side) have the hardware lock already, we are done */ 533166124Srafan 534166124Srafan if (AcpiGbl_GlobalLockAcquired) 535166124Srafan { 536166124Srafan return_ACPI_STATUS (AE_OK); 537166124Srafan } 538166124Srafan 539166124Srafan /* We must acquire the actual hardware lock */ 540166124Srafan 541166124Srafan ACPI_ACQUIRE_GLOBAL_LOCK (AcpiGbl_CommonFACS.GlobalLock, Acquired); 542166124Srafan if (Acquired) 543166124Srafan { 544166124Srafan /* We got the lock */ 545166124Srafan 546166124Srafan ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Acquired the HW Global Lock\n")); 547166124Srafan 548166124Srafan AcpiGbl_GlobalLockAcquired = TRUE; 549166124Srafan return_ACPI_STATUS (AE_OK); 550166124Srafan } 551166124Srafan 552166124Srafan /* 553166124Srafan * Did not get the lock. The pending bit was set above, and we must now 554166124Srafan * wait until we get the global lock released interrupt. 555166124Srafan */ 556166124Srafan ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Waiting for the HW Global Lock\n")); 557166124Srafan 558166124Srafan /* 559166124Srafan * Acquire the global lock semaphore first. 560166124Srafan * Since this wait will block, we must release the interpreter 561166124Srafan */ 562166124Srafan Status = AcpiExSystemWaitSemaphore (AcpiGbl_GlobalLockSemaphore, 563166124Srafan Timeout); 564166124Srafan return_ACPI_STATUS (Status); 565166124Srafan} 566166124Srafan 567166124Srafan 568166124Srafan/******************************************************************************* 569166124Srafan * 570166124Srafan * FUNCTION: AcpiEvReleaseGlobalLock 571166124Srafan * 572166124Srafan * PARAMETERS: None 573166124Srafan * 574166124Srafan * RETURN: Status 575166124Srafan * 576166124Srafan * DESCRIPTION: Releases ownership of the Global Lock. 577166124Srafan * 578166124Srafan ******************************************************************************/ 579166124Srafan 580166124SrafanACPI_STATUS 581166124SrafanAcpiEvReleaseGlobalLock (void) 582166124Srafan{ 583166124Srafan BOOLEAN Pending = FALSE; 584166124Srafan ACPI_STATUS Status = AE_OK; 585166124Srafan 586166124Srafan 587166124Srafan ACPI_FUNCTION_TRACE ("EvReleaseGlobalLock"); 58850276Speter 58950276Speter 59050276Speter if (!AcpiGbl_GlobalLockThreadCount) 59150276Speter { 59250276Speter ACPI_REPORT_WARNING(("Cannot release HW Global Lock, it has not been acquired\n")); 59350276Speter return_ACPI_STATUS (AE_NOT_ACQUIRED); 59450276Speter } 59550276Speter 59650276Speter /* One fewer thread has the global lock */ 59750276Speter 59850276Speter AcpiGbl_GlobalLockThreadCount--; 59950276Speter if (AcpiGbl_GlobalLockThreadCount) 60050276Speter { 60150276Speter /* There are still some threads holding the lock, cannot release */ 60250276Speter 60350276Speter return_ACPI_STATUS (AE_OK); 604166124Srafan } 60550276Speter 60650276Speter /* 60750276Speter * No more threads holding lock, we can do the actual hardware 60850276Speter * release 60950276Speter */ 61050276Speter ACPI_RELEASE_GLOBAL_LOCK (AcpiGbl_CommonFACS.GlobalLock, Pending); 61150276Speter AcpiGbl_GlobalLockAcquired = FALSE; 61250276Speter 61350276Speter /* 61450276Speter * If the pending bit was set, we must write GBL_RLS to the control 61550276Speter * register 61650276Speter */ 61750276Speter if (Pending) 61850276Speter { 61950276Speter Status = AcpiSetRegister (ACPI_BITREG_GLOBAL_LOCK_RELEASE, 1, ACPI_MTX_LOCK); 62050276Speter } 62150276Speter 62250276Speter return_ACPI_STATUS (Status); 62350276Speter} 62450276Speter 62550276Speter 62650276Speter/****************************************************************************** 62750276Speter * 62850276Speter * FUNCTION: AcpiEvTerminate 62950276Speter * 63050276Speter * PARAMETERS: none 63150276Speter * 63250276Speter * RETURN: none 63350276Speter * 63450276Speter * DESCRIPTION: Disable events and free memory allocated for table storage. 63550276Speter * 63650276Speter ******************************************************************************/ 63750276Speter 63850276Spetervoid 63950276SpeterAcpiEvTerminate (void) 640166124Srafan{ 641166124Srafan ACPI_NATIVE_UINT i; 64250276Speter ACPI_STATUS Status; 64350276Speter 64450276Speter 64550276Speter ACPI_FUNCTION_TRACE ("EvTerminate"); 64650276Speter 64750276Speter 64850276Speter if (AcpiGbl_EventsInitialized) 64950276Speter { 65050276Speter /* 65150276Speter * Disable all event-related functionality. 65250276Speter * In all cases, on error, print a message but obviously we don't abort. 65350276Speter */ 65450276Speter 65550276Speter /* Disable all fixed events */ 65650276Speter 65750276Speter for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) 65850276Speter { 65950276Speter Status = AcpiDisableEvent ((UINT32) i, 0); 66066963Speter if (ACPI_FAILURE (Status)) 66150276Speter { 66250276Speter ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not disable fixed event %d\n", (UINT32) i)); 663178866Srafan } 664166124Srafan } 66550276Speter 66650276Speter /* Disable all GPEs in all GPE blocks */ 66750276Speter 66850276Speter Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock, ACPI_NOT_ISR); 66966963Speter 67066963Speter /* Remove SCI handler */ 67166963Speter 672166124Srafan Status = AcpiEvRemoveSciHandler (); 673166124Srafan if (ACPI_FAILURE(Status)) 674166124Srafan { 67550276Speter ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not remove SCI handler\n")); 67650276Speter } 677166124Srafan } 67866963Speter 67950276Speter /* Deallocate all handler objects installed within GPE info structs */ 68050276Speter 68150276Speter Status = AcpiEvWalkGpeList (AcpiEvDeleteGpeHandlers, ACPI_NOT_ISR); 68250276Speter 68350276Speter /* Return to original mode if necessary */ 68450276Speter 68550276Speter if (AcpiGbl_OriginalMode == ACPI_SYS_MODE_LEGACY) 68650276Speter { 68750276Speter Status = AcpiDisable (); 68850276Speter if (ACPI_FAILURE (Status)) 68950276Speter { 69097049Speter ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "AcpiDisable failed\n")); 69150276Speter } 69250276Speter } 69350276Speter return_VOID; 694178866Srafan} 69550276Speter 69650276Speter