evmisc.c revision 138287
17055Sdg/****************************************************************************** 221830Sjoerg * 321830Sjoerg * Module Name: evmisc - Miscellaneous event manager support functions 47055Sdg * $Revision: 79 $ 57055Sdg * 67055Sdg *****************************************************************************/ 77055Sdg 87055Sdg/****************************************************************************** 97055Sdg * 107055Sdg * 1. Copyright Notice 117055Sdg * 127055Sdg * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp. 137055Sdg * All rights reserved. 147055Sdg * 157055Sdg * 2. License 167055Sdg * 177055Sdg * 2.1. This is your license from Intel Corp. under its intellectual property 187055Sdg * rights. You may have additional license terms from the party that provided 197055Sdg * you this software, covering your right to use that party's intellectual 207055Sdg * property rights. 217055Sdg * 227055Sdg * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 237055Sdg * copy of the source code appearing in this file ("Covered Code") an 247055Sdg * irrevocable, perpetual, worldwide license under Intel's copyrights in the 257055Sdg * base code distributed originally by Intel ("Original Intel Code") to copy, 267055Sdg * make derivatives, distribute, use and display any portion of the Covered 277055Sdg * Code in any form, with the right to sublicense such rights; and 287055Sdg * 297055Sdg * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 307055Sdg * license (with the right to sublicense), under only those claims of Intel 317055Sdg * patents that are infringed by the Original Intel Code, to make, use, sell, 327055Sdg * offer to sell, and import the Covered Code and derivative works thereof 337055Sdg * solely to the minimum extent necessary to exercise the above copyright 347055Sdg * license, and in no event shall the patent license extend to any additions 357061Sdg * to or modifications of the Original Intel Code. No other license or right 3650477Speter * is granted directly or by implication, estoppel or otherwise; 377055Sdg * 387055Sdg * The above copyright and patent license is granted only if the following 3932356Seivind * conditions are met: 4032350Seivind * 4154263Sshin * 3. Conditions 4231742Seivind * 43105577Srwatson * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4431742Seivind * Redistribution of source code of any substantial portion of the Covered 457055Sdg * Code or modification with rights to further distribute source must include 467055Sdg * the above Copyright Notice, the above License, this list of Conditions, 4793375Smdodd * and the following Disclaimer and Export Compliance provision. In addition, 48105577Srwatson * Licensee must cause all Covered Code to which Licensee contributes to 4993375Smdodd * contain a file documenting the changes Licensee made to create that Covered 507055Sdg * Code and the date of any change. Licensee must include in that file the 5193375Smdodd * documentation of any changes made by any predecessor Licensee. Licensee 527055Sdg * must include a prominent statement that the modification is derived, 5393375Smdodd * directly or indirectly, from Original Intel Code. 547055Sdg * 557055Sdg * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 567055Sdg * Redistribution of source code of any substantial portion of the Covered 577055Sdg * Code or modification without rights to further distribute source must 587055Sdg * include the following Disclaimer and Export Compliance provision in the 5993375Smdodd * documentation and/or other materials provided with distribution. In 6093375Smdodd * addition, Licensee may not authorize further sublicense of source of any 6193375Smdodd * portion of the Covered Code, and must include terms to the effect that the 6293373Smdodd * license from Licensee to its licensee is limited to the intellectual 637055Sdg * property embodied in the software Licensee provides to its licensee, and 6454263Sshin * not to intellectual property embodied in modifications its licensee may 657055Sdg * make. 667055Sdg * 6732350Seivind * 3.3. Redistribution of Executable. Redistribution in executable form of any 687055Sdg * substantial portion of the Covered Code or modification must reproduce the 6954263Sshin * above Copyright Notice, and the following Disclaimer and Export Compliance 7054263Sshin * provision in the documentation and/or other materials provided with the 7154263Sshin * distribution. 727055Sdg * 7311819Sjulian * 3.4. Intel retains all right, title, and interest in and to the Original 7421830Sjoerg * Intel Code. 7511819Sjulian * 7611819Sjulian * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7711819Sjulian * Intel shall be used in advertising or otherwise to promote the sale, use or 787055Sdg * other dealings in products derived from or relating to the Covered Code 797055Sdg * without prior written authorization from Intel. 807055Sdg * 817055Sdg * 4. Disclaimer and Export Compliance 827055Sdg * 837055Sdg * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 847055Sdg * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 857055Sdg * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 867055Sdg * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8721830Sjoerg * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8821830Sjoerg * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8921830Sjoerg * PARTICULAR PURPOSE. 9021830Sjoerg * 9121830Sjoerg * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9221830Sjoerg * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9321830Sjoerg * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9421830Sjoerg * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9521830Sjoerg * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9693382Smdodd * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9793382Smdodd * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9893382Smdodd * LIMITED REMEDY. 9993383Smdodd * 10093084Sbde * 4.3. Licensee shall not export, either directly or indirectly, any of this 10193383Smdodd * software or system incorporating such software without first obtaining any 10293383Smdodd * required license or other approval from the U. S. Department of Commerce or 103106939Ssam * any other agency or department of the United States Government. In the 10468180Sume * event Licensee exports any such software from the United States or 10593383Smdodd * re-exports any such software from a foreign destination, Licensee shall 10693369Smdodd * ensure that the distribution and export/re-export of the software is in 10793369Smdodd * compliance with all laws, regulations, orders, or other restrictions of the 10893369Smdodd * U.S. Export Administration Regulations. Licensee agrees that neither it nor 1097055Sdg * any of its subsidiaries will export/re-export any technical data, process, 1107055Sdg * software, or service, directly or indirectly, to any country for which the 1117055Sdg * United States government or any agency thereof requires an export license, 1127055Sdg * other governmental approval, or letter of assurance, without first obtaining 1137055Sdg * such license, approval or letter. 1147055Sdg * 1157055Sdg *****************************************************************************/ 11693383Smdodd 11754799Sgreen#include "acpi.h" 11893367Smdodd#include "acevents.h" 11954799Sgreen#include "acnamesp.h" 1207055Sdg#include "acinterp.h" 1217055Sdg 1227055Sdg#define _COMPONENT ACPI_EVENTS 12321830Sjoerg ACPI_MODULE_NAME ("evmisc") 12469152Sjlemon 12593373Smdodd 12693367Smdodd/******************************************************************************* 12793367Smdodd * 12893369Smdodd * FUNCTION: AcpiEvIsNotifyObject 1297055Sdg * 130105577Srwatson * PARAMETERS: Node - Node to check 131105577Srwatson * 132105577Srwatson * RETURN: TRUE if notifies allowed on this object 133105577Srwatson * 134105577Srwatson * DESCRIPTION: Check type of node for a object that supports notifies. 135105577Srwatson * 1367055Sdg * TBD: This could be replaced by a flag bit in the node. 1377055Sdg * 13834961Sphk ******************************************************************************/ 13943305Sdillon 1407055SdgBOOLEAN 14193369SmdoddAcpiEvIsNotifyObject ( 1427055Sdg ACPI_NAMESPACE_NODE *Node) 14321830Sjoerg{ 1447055Sdg switch (Node->Type) 1457055Sdg { 1467055Sdg case ACPI_TYPE_DEVICE: 1477055Sdg case ACPI_TYPE_PROCESSOR: 1487055Sdg case ACPI_TYPE_POWER: 1497055Sdg case ACPI_TYPE_THERMAL: 1507055Sdg /* 15193369Smdodd * These are the ONLY objects that can receive ACPI notifications 1527055Sdg */ 1537055Sdg return (TRUE); 1547055Sdg 1557055Sdg default: 1567055Sdg return (FALSE); 1577055Sdg } 15834961Sphk} 1597055Sdg 1607055Sdg 1617055Sdg/******************************************************************************* 1627055Sdg * 1637055Sdg * FUNCTION: AcpiEvQueueNotifyRequest 16421830Sjoerg * 16593369Smdodd * PARAMETERS: Node - NS node for the notified object 1667055Sdg * NotifyValue - Value from the Notify() request 16721830Sjoerg * 1687055Sdg * RETURN: Status 16921830Sjoerg * 1707055Sdg * DESCRIPTION: Dispatch a device notification event to a previously 17154263Sshin * installed handler. 17254263Sshin * 17393375Smdodd ******************************************************************************/ 17474093Sbmilekic 17593369Smdodd#ifdef ACPI_DEBUG_OUTPUT 17654263Sshinstatic const char *AcpiNotifyValueNames[] = 17754263Sshin{ 17854263Sshin "Bus Check", 17954263Sshin "Device Check", 18011819Sjulian "Device Wake", 18111819Sjulian "Eject request", 18221830Sjoerg "Device Check Light", 18311819Sjulian "Frequency Mismatch", 18493373Smdodd "Bus Mode Mismatch", 18511819Sjulian "Power Fault" 18611819Sjulian}; 18721830Sjoerg#endif 18821830Sjoerg 18921830SjoergACPI_STATUS 19036908SjulianAcpiEvQueueNotifyRequest ( 19121830Sjoerg ACPI_NAMESPACE_NODE *Node, 19221830Sjoerg UINT32 NotifyValue) 19321830Sjoerg{ 19421830Sjoerg ACPI_OPERAND_OBJECT *ObjDesc; 19530834Sjulian ACPI_OPERAND_OBJECT *HandlerObj = NULL; 19621830Sjoerg ACPI_GENERIC_STATE *NotifyInfo; 19721830Sjoerg ACPI_STATUS Status = AE_OK; 19821830Sjoerg 19921830Sjoerg 20021830Sjoerg ACPI_FUNCTION_NAME ("EvQueueNotifyRequest"); 20121830Sjoerg 20221830Sjoerg 20321830Sjoerg /* 20421830Sjoerg * For value 3 (Ejection Request), some device method may need to be run. 20521830Sjoerg * For value 2 (Device Wake) if _PRW exists, the _PS0 method may need to be run. 206111119Simp * For value 0x80 (Status Change) on the power button or sleep button, 20721830Sjoerg * initiate soft-off or sleep operation? 20821830Sjoerg */ 20921830Sjoerg ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 21021830Sjoerg "Dispatching Notify(%X) on node %p\n", NotifyValue, Node)); 21193371Smdodd 21293371Smdodd if (NotifyValue <= 7) 21393373Smdodd { 21421830Sjoerg ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: %s\n", 21521830Sjoerg AcpiNotifyValueNames[NotifyValue])); 21621830Sjoerg } 21721830Sjoerg else 21821830Sjoerg { 21921830Sjoerg ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: 0x%2.2X **Device Specific**\n", 22021830Sjoerg NotifyValue)); 2217055Sdg } 2227055Sdg 22321830Sjoerg /* Get the notify object attached to the NS Node */ 2247055Sdg 22593373Smdodd ObjDesc = AcpiNsGetAttachedObject (Node); 2267055Sdg if (ObjDesc) 2277055Sdg { 2287055Sdg /* We have the notify object, Get the right handler */ 22952248Smsmith 23052248Smsmith switch (Node->Type) 23193376Smdodd { 23252248Smsmith case ACPI_TYPE_DEVICE: 23393376Smdodd case ACPI_TYPE_THERMAL: 23493376Smdodd case ACPI_TYPE_PROCESSOR: 23552248Smsmith case ACPI_TYPE_POWER: 23652248Smsmith 23752248Smsmith if (NotifyValue <= ACPI_MAX_SYS_NOTIFY) 2387055Sdg { 2397055Sdg HandlerObj = ObjDesc->CommonNotify.SystemNotify; 2407055Sdg } 24136992Sjulian else 2427055Sdg { 24393375Smdodd HandlerObj = ObjDesc->CommonNotify.DeviceNotify; 2447055Sdg } 2457055Sdg break; 2467055Sdg 2477055Sdg default: 2487055Sdg /* All other types are not supported */ 2497055Sdg return (AE_TYPE); 2507055Sdg } 2517055Sdg } 2527055Sdg 2537055Sdg /* If there is any handler to run, schedule the dispatcher */ 2547055Sdg 2557055Sdg if ((AcpiGbl_SystemNotify.Handler && (NotifyValue <= ACPI_MAX_SYS_NOTIFY)) || 2567055Sdg (AcpiGbl_DeviceNotify.Handler && (NotifyValue > ACPI_MAX_SYS_NOTIFY)) || 2577055Sdg HandlerObj) 2587055Sdg { 2597055Sdg NotifyInfo = AcpiUtCreateGenericState (); 2607055Sdg if (!NotifyInfo) 2617055Sdg { 2627055Sdg return (AE_NO_MEMORY); 2637055Sdg } 2647055Sdg 2657055Sdg NotifyInfo->Common.DataType = ACPI_DESC_TYPE_STATE_NOTIFY; 2667055Sdg NotifyInfo->Notify.Node = Node; 2677055Sdg NotifyInfo->Notify.Value = (UINT16) NotifyValue; 2687055Sdg NotifyInfo->Notify.HandlerObj = HandlerObj; 2697055Sdg 2707055Sdg Status = AcpiOsQueueForExecution (OSD_PRIORITY_HIGH, 2717055Sdg AcpiEvNotifyDispatch, NotifyInfo); 2727055Sdg if (ACPI_FAILURE (Status)) 2737055Sdg { 2747055Sdg AcpiUtDeleteGenericState (NotifyInfo); 2757055Sdg } 2767055Sdg } 2777055Sdg 2787055Sdg if (!HandlerObj) 2797055Sdg { 2807055Sdg /* 2817055Sdg * There is no per-device notify handler for this device. 2827055Sdg * This may or may not be a problem. 2837055Sdg */ 284105598Sbrooks ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 2857055Sdg "No notify handler for Notify(%4.4s, %X) node %p\n", 2867055Sdg AcpiUtGetNodeName (Node), NotifyValue, Node)); 2877055Sdg } 28893380Smdodd 28993380Smdodd return (Status); 29093380Smdodd} 2917055Sdg 29293367Smdodd 293111119Simp/******************************************************************************* 2947055Sdg * 2957055Sdg * FUNCTION: AcpiEvNotifyDispatch 2967055Sdg * 2977055Sdg * PARAMETERS: Context - To be passsed to the notify handler 2987055Sdg * 2997055Sdg * RETURN: None. 30093375Smdodd * 30121830Sjoerg * DESCRIPTION: Dispatch a device notification event to a previously 3027055Sdg * installed handler. 30336908Sjulian * 3047055Sdg ******************************************************************************/ 3057055Sdg 3067055Sdgvoid ACPI_SYSTEM_XFACE 3077055SdgAcpiEvNotifyDispatch ( 308111119Simp void *Context) 3097055Sdg{ 3107055Sdg ACPI_GENERIC_STATE *NotifyInfo = (ACPI_GENERIC_STATE *) Context; 3117055Sdg ACPI_NOTIFY_HANDLER GlobalHandler = NULL; 3127055Sdg void *GlobalContext = NULL; 31393375Smdodd ACPI_OPERAND_OBJECT *HandlerObj; 3147055Sdg 31552248Smsmith 31693375Smdodd ACPI_FUNCTION_ENTRY (); 31752248Smsmith 31893375Smdodd 31993373Smdodd /* 32093377Smdodd * We will invoke a global notify handler if installed. 32136908Sjulian * This is done _before_ we invoke the per-device handler attached to the device. 32236908Sjulian */ 32336908Sjulian if (NotifyInfo->Notify.Value <= ACPI_MAX_SYS_NOTIFY) 32436908Sjulian { 32536908Sjulian /* Global system notification handler */ 32636908Sjulian 32736908Sjulian if (AcpiGbl_SystemNotify.Handler) 32836908Sjulian { 32936908Sjulian GlobalHandler = AcpiGbl_SystemNotify.Handler; 33093377Smdodd GlobalContext = AcpiGbl_SystemNotify.Context; 33136908Sjulian } 33236908Sjulian } 33336908Sjulian else 33436908Sjulian { 33593373Smdodd /* Global driver notification handler */ 33636908Sjulian 33793373Smdodd if (AcpiGbl_DeviceNotify.Handler) 33836908Sjulian { 33993373Smdodd GlobalHandler = AcpiGbl_DeviceNotify.Handler; 34093369Smdodd GlobalContext = AcpiGbl_DeviceNotify.Context; 34136908Sjulian } 34236908Sjulian } 34336908Sjulian 34469152Sjlemon /* Invoke the system handler first, if present */ 3457055Sdg 3467055Sdg if (GlobalHandler) 3477055Sdg { 3487055Sdg GlobalHandler (NotifyInfo->Notify.Node, NotifyInfo->Notify.Value, GlobalContext); 34993379Smdodd } 3507055Sdg 3517055Sdg /* Now invoke the per-device handler, if present */ 3527055Sdg 3537055Sdg HandlerObj = NotifyInfo->Notify.HandlerObj; 3547055Sdg if (HandlerObj) 3557055Sdg { 3567055Sdg HandlerObj->Notify.Handler (NotifyInfo->Notify.Node, NotifyInfo->Notify.Value, 3577055Sdg HandlerObj->Notify.Context); 3587055Sdg } 3597055Sdg 360106939Ssam /* All done with the info object */ 361106939Ssam 3627055Sdg AcpiUtDeleteGenericState (NotifyInfo); 3637055Sdg} 3647055Sdg 36593367Smdodd 36693367Smdodd/******************************************************************************* 367106939Ssam * 3687055Sdg * FUNCTION: AcpiEvGlobalLockThread 369106939Ssam * 370106939Ssam * PARAMETERS: Context - From thread interface, not used 37193379Smdodd * 372106939Ssam * RETURN: None 373106939Ssam * 374106939Ssam * DESCRIPTION: Invoked by SCI interrupt handler upon acquisition of the 375106939Ssam * Global Lock. Simply signal all threads that are waiting 376106939Ssam * for the lock. 377106939Ssam * 37893379Smdodd ******************************************************************************/ 37993379Smdodd 38093379Smdoddstatic void ACPI_SYSTEM_XFACE 38193379SmdoddAcpiEvGlobalLockThread ( 38293379Smdodd void *Context) 383105577Srwatson{ 384105577Srwatson ACPI_STATUS Status; 385105577Srwatson 386105577Srwatson 38793379Smdodd /* Signal threads that are waiting for the lock */ 38893379Smdodd 38993379Smdodd if (AcpiGbl_GlobalLockThreadCount) 39093379Smdodd { 39193379Smdodd /* Send sufficient units to the semaphore */ 39293379Smdodd 39393379Smdodd Status = AcpiOsSignalSemaphore (AcpiGbl_GlobalLockSemaphore, 39493379Smdodd AcpiGbl_GlobalLockThreadCount); 39593379Smdodd if (ACPI_FAILURE (Status)) 39693379Smdodd { 39793379Smdodd ACPI_REPORT_ERROR (("Could not signal Global Lock semaphore\n")); 39893379Smdodd } 39921830Sjoerg } 40093381Smdodd} 40193381Smdodd 40221830Sjoerg 40321830Sjoerg/******************************************************************************* 40421830Sjoerg * 4057055Sdg * FUNCTION: AcpiEvGlobalLockHandler 40621830Sjoerg * 4077055Sdg * PARAMETERS: Context - From thread interface, not used 40821830Sjoerg * 40921830Sjoerg * RETURN: ACPI_INTERRUPT_HANDLED or ACPI_INTERRUPT_NOT_HANDLED 41021830Sjoerg * 41121830Sjoerg * DESCRIPTION: Invoked directly from the SCI handler when a global lock 41221830Sjoerg * release interrupt occurs. Grab the global lock and queue 41321830Sjoerg * the global lock thread for execution 41421830Sjoerg * 41521830Sjoerg ******************************************************************************/ 41621830Sjoerg 41721830Sjoergstatic UINT32 418106939SsamAcpiEvGlobalLockHandler ( 419106939Ssam void *Context) 420106939Ssam{ 42193379Smdodd BOOLEAN Acquired = FALSE; 42293379Smdodd ACPI_STATUS Status; 42393379Smdodd 42493379Smdodd 42593379Smdodd /* 4267055Sdg * Attempt to get the lock 42793377Smdodd * If we don't get it now, it will be marked pending and we will 4287055Sdg * take another interrupt when it becomes free. 4297055Sdg */ 4307055Sdg ACPI_ACQUIRE_GLOBAL_LOCK (AcpiGbl_CommonFACS.GlobalLock, Acquired); 43121830Sjoerg if (Acquired) 43293379Smdodd { 43393379Smdodd /* Got the lock, now wake all threads waiting for it */ 4347055Sdg 43593379Smdodd AcpiGbl_GlobalLockAcquired = TRUE; 43621830Sjoerg 43793371Smdodd /* Run the Global Lock thread which will signal all waiting threads */ 43821830Sjoerg 43993371Smdodd Status = AcpiOsQueueForExecution (OSD_PRIORITY_HIGH, 44021830Sjoerg AcpiEvGlobalLockThread, Context); 44193373Smdodd if (ACPI_FAILURE (Status)) 44221830Sjoerg { 44321830Sjoerg ACPI_REPORT_ERROR (("Could not queue Global Lock thread, %s\n", 44421830Sjoerg AcpiFormatException (Status))); 44521830Sjoerg 44693371Smdodd return (ACPI_INTERRUPT_NOT_HANDLED); 44721830Sjoerg } 44893371Smdodd } 44993373Smdodd 45093369Smdodd return (ACPI_INTERRUPT_HANDLED); 45121830Sjoerg} 45221830Sjoerg 45321830Sjoerg 45493377Smdodd/******************************************************************************* 45593377Smdodd * 45693379Smdodd * FUNCTION: AcpiEvInitGlobalLockHandler 45793379Smdodd * 4587055Sdg * PARAMETERS: None 45993379Smdodd * 46093377Smdodd * RETURN: Status 46121830Sjoerg * 46293377Smdodd * DESCRIPTION: Install a handler for the global lock release event 46393377Smdodd * 46421830Sjoerg ******************************************************************************/ 4657055Sdg 4667055SdgACPI_STATUS 46736265SdgAcpiEvInitGlobalLockHandler (void) 46836192Sdg{ 4697055Sdg ACPI_STATUS Status; 4707055Sdg 4717055Sdg 4727055Sdg ACPI_FUNCTION_TRACE ("EvInitGlobalLockHandler"); 4737055Sdg 47478295Sjlemon 47578295Sjlemon AcpiGbl_GlobalLockPresent = TRUE; 4767055Sdg Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL, 4777055Sdg AcpiEvGlobalLockHandler, NULL); 4787055Sdg 4797055Sdg /* 48054263Sshin * If the global lock does not exist on this platform, the attempt 48154263Sshin * to enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick) 48254263Sshin * Map to AE_OK, but mark global lock as not present. 48354263Sshin * Any attempt to actually use the global lock will be flagged 48454263Sshin * with an error. 48554263Sshin */ 48621830Sjoerg if (Status == AE_NO_HARDWARE_RESPONSE) 48721830Sjoerg { 48821830Sjoerg AcpiGbl_GlobalLockPresent = FALSE; 48921830Sjoerg Status = AE_OK; 49021830Sjoerg } 49121830Sjoerg 4927055Sdg return_ACPI_STATUS (Status); 4937055Sdg} 4947055Sdg 4957055Sdg 4967055Sdg/****************************************************************************** 4977055Sdg * 4987055Sdg * FUNCTION: AcpiEvAcquireGlobalLock 49921830Sjoerg * 5007055Sdg * PARAMETERS: Timeout - Max time to wait for the lock, in millisec. 5017055Sdg * 5027055Sdg * RETURN: Status 5037055Sdg * 50421830Sjoerg * DESCRIPTION: Attempt to gain ownership of the Global Lock. 50521830Sjoerg * 50621830Sjoerg *****************************************************************************/ 50721830Sjoerg 50821830SjoergACPI_STATUS 50921830SjoergAcpiEvAcquireGlobalLock ( 51021830Sjoerg UINT16 Timeout) 51193369Smdodd{ 51221830Sjoerg ACPI_STATUS Status = AE_OK; 51321830Sjoerg BOOLEAN Acquired = FALSE; 5147055Sdg 51521830Sjoerg 5167055Sdg ACPI_FUNCTION_TRACE ("EvAcquireGlobalLock"); 5177055Sdg 5187055Sdg 5197055Sdg#ifndef ACPI_APPLICATION 5207055Sdg /* Make sure that we actually have a global lock */ 52121830Sjoerg 5227055Sdg if (!AcpiGbl_GlobalLockPresent) 52321830Sjoerg { 5247055Sdg return_ACPI_STATUS (AE_NO_GLOBAL_LOCK); 52593377Smdodd } 5267055Sdg#endif 5277055Sdg 52869152Sjlemon /* One more thread wants the global lock */ 52993377Smdodd 53093377Smdodd AcpiGbl_GlobalLockThreadCount++; 53193377Smdodd 53293377Smdodd /* If we (OS side vs. BIOS side) have the hardware lock already, we are done */ 53393377Smdodd 53493377Smdodd if (AcpiGbl_GlobalLockAcquired) 53593377Smdodd { 5367055Sdg return_ACPI_STATUS (AE_OK); 53793380Smdodd } 5387055Sdg 5397055Sdg /* We must acquire the actual hardware lock */ 5407055Sdg 5417055Sdg ACPI_ACQUIRE_GLOBAL_LOCK (AcpiGbl_CommonFACS.GlobalLock, Acquired); 54293383Smdodd if (Acquired) 54393367Smdodd { 54493383Smdodd /* We got the lock */ 5457055Sdg 54693367Smdodd ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Acquired the HW Global Lock\n")); 54793367Smdodd 5487055Sdg AcpiGbl_GlobalLockAcquired = TRUE; 5497055Sdg return_ACPI_STATUS (AE_OK); 55093373Smdodd } 5517055Sdg 55293379Smdodd /* 55393379Smdodd * Did not get the lock. The pending bit was set above, and we must now 55493379Smdodd * wait until we get the global lock released interrupt. 5557055Sdg */ 55693379Smdodd ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Waiting for the HW Global Lock\n")); 557106939Ssam 55868180Sume /* 55993379Smdodd * Acquire the global lock semaphore first. 56016063Sgpalmer * Since this wait will block, we must release the interpreter 56121830Sjoerg */ 56221830Sjoerg Status = AcpiExSystemWaitSemaphore (AcpiGbl_GlobalLockSemaphore, 56321830Sjoerg Timeout); 56483130Sjlemon return_ACPI_STATUS (Status); 56593379Smdodd} 56693379Smdodd 56793379Smdodd 56893379Smdodd/******************************************************************************* 56993379Smdodd * 57093379Smdodd * FUNCTION: AcpiEvReleaseGlobalLock 57121831Sjoerg * 57221831Sjoerg * PARAMETERS: None 57321831Sjoerg * 57493369Smdodd * RETURN: Status 57593379Smdodd * 57693383Smdodd * DESCRIPTION: Releases ownership of the Global Lock. 57793383Smdodd * 57893383Smdodd ******************************************************************************/ 57993379Smdodd 5807055SdgACPI_STATUS 58168180SumeAcpiEvReleaseGlobalLock (void) 58293382Smdodd{ 58393382Smdodd BOOLEAN Pending = FALSE; 58493382Smdodd ACPI_STATUS Status = AE_OK; 58593382Smdodd 58693382Smdodd 58793382Smdodd ACPI_FUNCTION_TRACE ("EvReleaseGlobalLock"); 58893382Smdodd 58993382Smdodd 59093382Smdodd if (!AcpiGbl_GlobalLockThreadCount) 59193382Smdodd { 59293382Smdodd ACPI_REPORT_WARNING(("Cannot release HW Global Lock, it has not been acquired\n")); 59393382Smdodd return_ACPI_STATUS (AE_NOT_ACQUIRED); 59493382Smdodd } 59593382Smdodd 59693382Smdodd /* One fewer thread has the global lock */ 59793382Smdodd 59893382Smdodd AcpiGbl_GlobalLockThreadCount--; 59993382Smdodd if (AcpiGbl_GlobalLockThreadCount) 60093382Smdodd { 60193382Smdodd /* There are still some threads holding the lock, cannot release */ 60293382Smdodd 60393382Smdodd return_ACPI_STATUS (AE_OK); 60493382Smdodd } 60593382Smdodd 60693382Smdodd /* 60793382Smdodd * No more threads holding lock, we can do the actual hardware 60893382Smdodd * release 60993382Smdodd */ 61093382Smdodd ACPI_RELEASE_GLOBAL_LOCK (AcpiGbl_CommonFACS.GlobalLock, Pending); 61193382Smdodd AcpiGbl_GlobalLockAcquired = FALSE; 61293382Smdodd 61393382Smdodd /* 61493382Smdodd * If the pending bit was set, we must write GBL_RLS to the control 61593382Smdodd * register 61693382Smdodd */ 61793382Smdodd if (Pending) 61893382Smdodd { 61993382Smdodd Status = AcpiSetRegister (ACPI_BITREG_GLOBAL_LOCK_RELEASE, 1, ACPI_MTX_LOCK); 62093382Smdodd } 62193382Smdodd 62293382Smdodd return_ACPI_STATUS (Status); 62393382Smdodd} 62493382Smdodd 62593382Smdodd 62693382Smdodd/****************************************************************************** 62793382Smdodd * 62893382Smdodd * FUNCTION: AcpiEvTerminate 62993382Smdodd * 63093382Smdodd * PARAMETERS: none 63193382Smdodd * 63293382Smdodd * RETURN: none 63393382Smdodd * 63493382Smdodd * DESCRIPTION: Disable events and free memory allocated for table storage. 63593382Smdodd * 63693382Smdodd ******************************************************************************/ 63793382Smdodd 63893382Smdoddvoid 63993382SmdoddAcpiEvTerminate (void) 64093382Smdodd{ 64193382Smdodd ACPI_NATIVE_UINT i; 64293382Smdodd ACPI_STATUS Status; 64393382Smdodd 64493382Smdodd 64593382Smdodd ACPI_FUNCTION_TRACE ("EvTerminate"); 64693382Smdodd 64793382Smdodd 64893382Smdodd if (AcpiGbl_EventsInitialized) 64993382Smdodd { 65093382Smdodd /* 651104302Sphk * Disable all event-related functionality. 65293382Smdodd * In all cases, on error, print a message but obviously we don't abort. 65393382Smdodd */ 65493382Smdodd 65593382Smdodd /* Disable all fixed events */ 65693382Smdodd 65793382Smdodd for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) 65893382Smdodd { 65993382Smdodd Status = AcpiDisableEvent ((UINT32) i, 0); 66093382Smdodd if (ACPI_FAILURE (Status)) 66193382Smdodd { 66293382Smdodd ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not disable fixed event %d\n", (UINT32) i)); 66393382Smdodd } 66493382Smdodd } 66593382Smdodd 66693382Smdodd /* Disable all GPEs in all GPE blocks */ 66793382Smdodd 66893382Smdodd Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock, ACPI_NOT_ISR); 66993382Smdodd 67093382Smdodd /* Remove SCI handler */ 67193382Smdodd 67293382Smdodd Status = AcpiEvRemoveSciHandler (); 67393382Smdodd if (ACPI_FAILURE(Status)) 67493382Smdodd { 67593382Smdodd ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not remove SCI handler\n")); 67693382Smdodd } 67793382Smdodd } 67868180Sume 67968180Sume /* Deallocate all handler objects installed within GPE info structs */ 68068180Sume 68168180Sume Status = AcpiEvWalkGpeList (AcpiEvDeleteGpeHandlers, ACPI_NOT_ISR); 68268180Sume 68368180Sume /* Return to original mode if necessary */ 68468180Sume 68568180Sume if (AcpiGbl_OriginalMode == ACPI_SYS_MODE_LEGACY) 68668180Sume { 68768180Sume Status = AcpiDisable (); 68868180Sume if (ACPI_FAILURE (Status)) 68968180Sume { 69068180Sume ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "AcpiDisable failed\n")); 69168180Sume } 69268180Sume } 69368180Sume return_VOID; 69468180Sume} 69568180Sume 69668180Sume