evxface.c revision 193341
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: evxface - External interfaces for ACPI events 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 767754Smsmith/****************************************************************************** 867754Smsmith * 967754Smsmith * 1. Copyright Notice 1067754Smsmith * 11193267Sjkim * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 1270243Smsmith * All rights reserved. 1367754Smsmith * 1467754Smsmith * 2. License 1567754Smsmith * 1667754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1767754Smsmith * rights. You may have additional license terms from the party that provided 1867754Smsmith * you this software, covering your right to use that party's intellectual 1967754Smsmith * property rights. 2067754Smsmith * 2167754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2267754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2367754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2467754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2567754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2667754Smsmith * Code in any form, with the right to sublicense such rights; and 2767754Smsmith * 2867754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 2967754Smsmith * license (with the right to sublicense), under only those claims of Intel 3067754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3167754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3267754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3367754Smsmith * license, and in no event shall the patent license extend to any additions 3467754Smsmith * to or modifications of the Original Intel Code. No other license or right 3567754Smsmith * is granted directly or by implication, estoppel or otherwise; 3667754Smsmith * 3767754Smsmith * The above copyright and patent license is granted only if the following 3867754Smsmith * conditions are met: 3967754Smsmith * 4067754Smsmith * 3. Conditions 4167754Smsmith * 4267754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43167802Sjkim * Redistribution of source code of any substantial portion of the Covered 4467754Smsmith * Code or modification with rights to further distribute source must include 4567754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4667754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4767754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 4867754Smsmith * contain a file documenting the changes Licensee made to create that Covered 4967754Smsmith * Code and the date of any change. Licensee must include in that file the 5067754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5167754Smsmith * must include a prominent statement that the modification is derived, 5267754Smsmith * directly or indirectly, from Original Intel Code. 5367754Smsmith * 5467754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5567754Smsmith * Redistribution of source code of any substantial portion of the Covered 5667754Smsmith * Code or modification without rights to further distribute source must 5767754Smsmith * include the following Disclaimer and Export Compliance provision in the 5867754Smsmith * documentation and/or other materials provided with distribution. In 5967754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6067754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6167754Smsmith * license from Licensee to its licensee is limited to the intellectual 6267754Smsmith * property embodied in the software Licensee provides to its licensee, and 6367754Smsmith * not to intellectual property embodied in modifications its licensee may 6467754Smsmith * make. 6567754Smsmith * 6667754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 6767754Smsmith * substantial portion of the Covered Code or modification must reproduce the 6867754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 6967754Smsmith * provision in the documentation and/or other materials provided with the 7067754Smsmith * distribution. 7167754Smsmith * 7267754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7367754Smsmith * Intel Code. 7467754Smsmith * 7567754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7667754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7767754Smsmith * other dealings in products derived from or relating to the Covered Code 7867754Smsmith * without prior written authorization from Intel. 7967754Smsmith * 8067754Smsmith * 4. Disclaimer and Export Compliance 8167754Smsmith * 8267754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8367754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8467754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8567754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8667754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8767754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8867754Smsmith * PARTICULAR PURPOSE. 8967754Smsmith * 9067754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9167754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9267754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9367754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9467754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9567754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9667754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9767754Smsmith * LIMITED REMEDY. 9867754Smsmith * 9967754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10067754Smsmith * software or system incorporating such software without first obtaining any 10167754Smsmith * required license or other approval from the U. S. Department of Commerce or 10267754Smsmith * any other agency or department of the United States Government. In the 10367754Smsmith * event Licensee exports any such software from the United States or 10467754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10567754Smsmith * ensure that the distribution and export/re-export of the software is in 10667754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 10767754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10867754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 10967754Smsmith * software, or service, directly or indirectly, to any country for which the 11067754Smsmith * United States government or any agency thereof requires an export license, 11167754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11267754Smsmith * such license, approval or letter. 11367754Smsmith * 11467754Smsmith *****************************************************************************/ 11567754Smsmith 11667754Smsmith 11767754Smsmith#define __EVXFACE_C__ 11867754Smsmith 119193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 120193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 121193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 122193341Sjkim#include <contrib/dev/acpica/include/acevents.h> 123193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 12467754Smsmith 12577424Smsmith#define _COMPONENT ACPI_EVENTS 12691116Smsmith ACPI_MODULE_NAME ("evxface") 12767754Smsmith 12867754Smsmith 12977424Smsmith/******************************************************************************* 13067754Smsmith * 131138287Smarks * FUNCTION: AcpiInstallExceptionHandler 132138287Smarks * 133138287Smarks * PARAMETERS: Handler - Pointer to the handler function for the 134138287Smarks * event 135138287Smarks * 136138287Smarks * RETURN: Status 137138287Smarks * 138138287Smarks * DESCRIPTION: Saves the pointer to the handler function 139138287Smarks * 140138287Smarks ******************************************************************************/ 141138287Smarks 142138287SmarksACPI_STATUS 143138287SmarksAcpiInstallExceptionHandler ( 144138287Smarks ACPI_EXCEPTION_HANDLER Handler) 145138287Smarks{ 146138287Smarks ACPI_STATUS Status; 147138287Smarks 148138287Smarks 149167802Sjkim ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler); 150138287Smarks 151138287Smarks 152138287Smarks Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 153138287Smarks if (ACPI_FAILURE (Status)) 154138287Smarks { 155138287Smarks return_ACPI_STATUS (Status); 156138287Smarks } 157138287Smarks 158138287Smarks /* Don't allow two handlers. */ 159138287Smarks 160138287Smarks if (AcpiGbl_ExceptionHandler) 161138287Smarks { 162138287Smarks Status = AE_ALREADY_EXISTS; 163138287Smarks goto Cleanup; 164138287Smarks } 165138287Smarks 166138287Smarks /* Install the handler */ 167138287Smarks 168138287Smarks AcpiGbl_ExceptionHandler = Handler; 169138287Smarks 170138287SmarksCleanup: 171138287Smarks (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 172138287Smarks return_ACPI_STATUS (Status); 173138287Smarks} 174138287Smarks 175167802SjkimACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler) 176138287Smarks 177167802Sjkim 178138287Smarks/******************************************************************************* 179138287Smarks * 18067754Smsmith * FUNCTION: AcpiInstallFixedEventHandler 18167754Smsmith * 18267754Smsmith * PARAMETERS: Event - Event type to enable. 18367754Smsmith * Handler - Pointer to the handler function for the 18467754Smsmith * event 18567754Smsmith * Context - Value passed to the handler on each GPE 18667754Smsmith * 18767754Smsmith * RETURN: Status 18867754Smsmith * 18967754Smsmith * DESCRIPTION: Saves the pointer to the handler function and then enables the 19067754Smsmith * event. 19167754Smsmith * 19267754Smsmith ******************************************************************************/ 19367754Smsmith 19467754SmsmithACPI_STATUS 19567754SmsmithAcpiInstallFixedEventHandler ( 19667754Smsmith UINT32 Event, 19777424Smsmith ACPI_EVENT_HANDLER Handler, 19867754Smsmith void *Context) 19967754Smsmith{ 20077424Smsmith ACPI_STATUS Status; 20167754Smsmith 20267754Smsmith 203167802Sjkim ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler); 20467754Smsmith 20567754Smsmith 20677424Smsmith /* Parameter validation */ 20777424Smsmith 20877424Smsmith if (Event > ACPI_EVENT_MAX) 20977424Smsmith { 21067754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 21167754Smsmith } 21267754Smsmith 21391116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 21491116Smsmith if (ACPI_FAILURE (Status)) 21591116Smsmith { 21691116Smsmith return_ACPI_STATUS (Status); 21791116Smsmith } 21867754Smsmith 21967754Smsmith /* Don't allow two handlers. */ 22067754Smsmith 22167754Smsmith if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler) 22267754Smsmith { 22387031Smsmith Status = AE_ALREADY_EXISTS; 22467754Smsmith goto Cleanup; 22567754Smsmith } 22667754Smsmith 22785756Smsmith /* Install the handler before enabling the event */ 22867754Smsmith 22967754Smsmith AcpiGbl_FixedEventHandlers[Event].Handler = Handler; 23067754Smsmith AcpiGbl_FixedEventHandlers[Event].Context = Context; 23167754Smsmith 232117521Snjl Status = AcpiEnableEvent (Event, 0); 23391116Smsmith if (ACPI_FAILURE (Status)) 23467754Smsmith { 235167802Sjkim ACPI_WARNING ((AE_INFO, "Could not enable fixed event %X", Event)); 23667754Smsmith 23767754Smsmith /* Remove the handler */ 23867754Smsmith 23967754Smsmith AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 24067754Smsmith AcpiGbl_FixedEventHandlers[Event].Context = NULL; 24177424Smsmith } 24277424Smsmith else 24377424Smsmith { 24482367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 24582367Smsmith "Enabled fixed event %X, Handler=%p\n", Event, Handler)); 24667754Smsmith } 24767754Smsmith 24867754Smsmith 24967754SmsmithCleanup: 25091116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 25167754Smsmith return_ACPI_STATUS (Status); 25267754Smsmith} 25367754Smsmith 254167802SjkimACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler) 25567754Smsmith 256167802Sjkim 25777424Smsmith/******************************************************************************* 25867754Smsmith * 25967754Smsmith * FUNCTION: AcpiRemoveFixedEventHandler 26067754Smsmith * 26167754Smsmith * PARAMETERS: Event - Event type to disable. 26267754Smsmith * Handler - Address of the handler 26367754Smsmith * 26467754Smsmith * RETURN: Status 26567754Smsmith * 26667754Smsmith * DESCRIPTION: Disables the event and unregisters the event handler. 26767754Smsmith * 26867754Smsmith ******************************************************************************/ 26967754Smsmith 27067754SmsmithACPI_STATUS 27167754SmsmithAcpiRemoveFixedEventHandler ( 27267754Smsmith UINT32 Event, 27377424Smsmith ACPI_EVENT_HANDLER Handler) 27467754Smsmith{ 27567754Smsmith ACPI_STATUS Status = AE_OK; 27667754Smsmith 27767754Smsmith 278167802Sjkim ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler); 27967754Smsmith 28067754Smsmith 28177424Smsmith /* Parameter validation */ 28277424Smsmith 28377424Smsmith if (Event > ACPI_EVENT_MAX) 28477424Smsmith { 28567754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 28667754Smsmith } 28767754Smsmith 28891116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 28991116Smsmith if (ACPI_FAILURE (Status)) 29091116Smsmith { 29191116Smsmith return_ACPI_STATUS (Status); 29291116Smsmith } 29367754Smsmith 29485756Smsmith /* Disable the event before removing the handler */ 29567754Smsmith 296117521Snjl Status = AcpiDisableEvent (Event, 0); 29769450Smsmith 29877424Smsmith /* Always Remove the handler */ 29977424Smsmith 30077424Smsmith AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 30177424Smsmith AcpiGbl_FixedEventHandlers[Event].Context = NULL; 30277424Smsmith 30391116Smsmith if (ACPI_FAILURE (Status)) 30467754Smsmith { 305167802Sjkim ACPI_WARNING ((AE_INFO, 306167802Sjkim "Could not write to fixed event enable register %X", Event)); 30777424Smsmith } 30877424Smsmith else 30977424Smsmith { 310167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X\n", Event)); 31167754Smsmith } 31267754Smsmith 31391116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 31467754Smsmith return_ACPI_STATUS (Status); 31567754Smsmith} 31667754Smsmith 317167802SjkimACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler) 31867754Smsmith 319167802Sjkim 32077424Smsmith/******************************************************************************* 32167754Smsmith * 32267754Smsmith * FUNCTION: AcpiInstallNotifyHandler 32367754Smsmith * 32467754Smsmith * PARAMETERS: Device - The device for which notifies will be handled 32567754Smsmith * HandlerType - The type of handler: 32667754Smsmith * ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f) 32767754Smsmith * ACPI_DEVICE_NOTIFY: DriverHandler (80-ff) 328129684Snjl * ACPI_ALL_NOTIFY: both system and device 32967754Smsmith * Handler - Address of the handler 33067754Smsmith * Context - Value passed to the handler on each GPE 33167754Smsmith * 33267754Smsmith * RETURN: Status 33367754Smsmith * 33467754Smsmith * DESCRIPTION: Install a handler for notifies on an ACPI device 33567754Smsmith * 33667754Smsmith ******************************************************************************/ 33767754Smsmith 33867754SmsmithACPI_STATUS 33967754SmsmithAcpiInstallNotifyHandler ( 34067754Smsmith ACPI_HANDLE Device, 34167754Smsmith UINT32 HandlerType, 34277424Smsmith ACPI_NOTIFY_HANDLER Handler, 34367754Smsmith void *Context) 34467754Smsmith{ 34567754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 34667754Smsmith ACPI_OPERAND_OBJECT *NotifyObj; 34799146Siwasaki ACPI_NAMESPACE_NODE *Node; 34891116Smsmith ACPI_STATUS Status; 34967754Smsmith 35067754Smsmith 351167802Sjkim ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler); 35267754Smsmith 35367754Smsmith 35467754Smsmith /* Parameter validation */ 35567754Smsmith 35699146Siwasaki if ((!Device) || 35799146Siwasaki (!Handler) || 35867754Smsmith (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 35967754Smsmith { 36067754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 36167754Smsmith } 36267754Smsmith 36391116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 36491116Smsmith if (ACPI_FAILURE (Status)) 36591116Smsmith { 36691116Smsmith return_ACPI_STATUS (Status); 36791116Smsmith } 36871867Smsmith 36967754Smsmith /* Convert and validate the device handle */ 37067754Smsmith 37199146Siwasaki Node = AcpiNsMapHandleToNode (Device); 37299146Siwasaki if (!Node) 37367754Smsmith { 37467754Smsmith Status = AE_BAD_PARAMETER; 37567754Smsmith goto UnlockAndExit; 37667754Smsmith } 37767754Smsmith 37867754Smsmith /* 37971867Smsmith * Root Object: 38071867Smsmith * Registering a notify handler on the root object indicates that the 381193267Sjkim * caller wishes to receive notifications for all objects. Note that 38271867Smsmith * only one <external> global handler can be regsitered (per notify type). 38367754Smsmith */ 38467754Smsmith if (Device == ACPI_ROOT_OBJECT) 38567754Smsmith { 38671867Smsmith /* Make sure the handler is not already installed */ 38767754Smsmith 388129684Snjl if (((HandlerType & ACPI_SYSTEM_NOTIFY) && 389129684Snjl AcpiGbl_SystemNotify.Handler) || 390129684Snjl ((HandlerType & ACPI_DEVICE_NOTIFY) && 391117521Snjl AcpiGbl_DeviceNotify.Handler)) 39267754Smsmith { 39387031Smsmith Status = AE_ALREADY_EXISTS; 39467754Smsmith goto UnlockAndExit; 39567754Smsmith } 39667754Smsmith 397129684Snjl if (HandlerType & ACPI_SYSTEM_NOTIFY) 39867754Smsmith { 399117521Snjl AcpiGbl_SystemNotify.Node = Node; 400117521Snjl AcpiGbl_SystemNotify.Handler = Handler; 401117521Snjl AcpiGbl_SystemNotify.Context = Context; 40267754Smsmith } 403129684Snjl 404129684Snjl if (HandlerType & ACPI_DEVICE_NOTIFY) 40567754Smsmith { 406117521Snjl AcpiGbl_DeviceNotify.Node = Node; 407117521Snjl AcpiGbl_DeviceNotify.Handler = Handler; 408117521Snjl AcpiGbl_DeviceNotify.Context = Context; 40967754Smsmith } 41067754Smsmith 41167754Smsmith /* Global notify handler installed */ 41267754Smsmith } 41367754Smsmith 41467754Smsmith /* 41585756Smsmith * All Other Objects: 41671867Smsmith * Caller will only receive notifications specific to the target object. 41771867Smsmith * Note that only certain object types can receive notifications. 41867754Smsmith */ 41987031Smsmith else 42085756Smsmith { 42199146Siwasaki /* Notifies allowed on this object? */ 42299146Siwasaki 42399146Siwasaki if (!AcpiEvIsNotifyObject (Node)) 42467754Smsmith { 42599146Siwasaki Status = AE_TYPE; 42667754Smsmith goto UnlockAndExit; 42767754Smsmith } 42867754Smsmith 42971867Smsmith /* Check for an existing internal object */ 43067754Smsmith 43199146Siwasaki ObjDesc = AcpiNsGetAttachedObject (Node); 43271867Smsmith if (ObjDesc) 43367754Smsmith { 43471867Smsmith /* Object exists - make sure there's no handler */ 43571867Smsmith 436129684Snjl if (((HandlerType & ACPI_SYSTEM_NOTIFY) && 437117521Snjl ObjDesc->CommonNotify.SystemNotify) || 438129684Snjl ((HandlerType & ACPI_DEVICE_NOTIFY) && 439117521Snjl ObjDesc->CommonNotify.DeviceNotify)) 44071867Smsmith { 44187031Smsmith Status = AE_ALREADY_EXISTS; 44271867Smsmith goto UnlockAndExit; 44371867Smsmith } 44467754Smsmith } 44571867Smsmith else 44671867Smsmith { 44771867Smsmith /* Create a new object */ 44867754Smsmith 44999146Siwasaki ObjDesc = AcpiUtCreateInternalObject (Node->Type); 45071867Smsmith if (!ObjDesc) 45171867Smsmith { 45271867Smsmith Status = AE_NO_MEMORY; 45371867Smsmith goto UnlockAndExit; 45471867Smsmith } 45567754Smsmith 45671867Smsmith /* Attach new object to the Node */ 45771867Smsmith 45899146Siwasaki Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type); 459117521Snjl 460117521Snjl /* Remove local reference to the object */ 461117521Snjl 462117521Snjl AcpiUtRemoveReference (ObjDesc); 46371867Smsmith if (ACPI_FAILURE (Status)) 46471867Smsmith { 46571867Smsmith goto UnlockAndExit; 46671867Smsmith } 46771867Smsmith } 46871867Smsmith 46971867Smsmith /* Install the handler */ 47071867Smsmith 471107325Siwasaki NotifyObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY); 47271867Smsmith if (!NotifyObj) 47367754Smsmith { 47471867Smsmith Status = AE_NO_MEMORY; 47567754Smsmith goto UnlockAndExit; 47667754Smsmith } 47767754Smsmith 478117521Snjl NotifyObj->Notify.Node = Node; 479117521Snjl NotifyObj->Notify.Handler = Handler; 480117521Snjl NotifyObj->Notify.Context = Context; 48167754Smsmith 482129684Snjl if (HandlerType & ACPI_SYSTEM_NOTIFY) 48371867Smsmith { 484117521Snjl ObjDesc->CommonNotify.SystemNotify = NotifyObj; 48571867Smsmith } 486129684Snjl 487129684Snjl if (HandlerType & ACPI_DEVICE_NOTIFY) 48871867Smsmith { 489117521Snjl ObjDesc->CommonNotify.DeviceNotify = NotifyObj; 49071867Smsmith } 491129684Snjl 492129684Snjl if (HandlerType == ACPI_ALL_NOTIFY) 493129684Snjl { 494129684Snjl /* Extra ref if installed in both */ 495129684Snjl 496129684Snjl AcpiUtAddReference (NotifyObj); 497129684Snjl } 49867754Smsmith } 49967754Smsmith 50085756Smsmith 50167754SmsmithUnlockAndExit: 50291116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 50367754Smsmith return_ACPI_STATUS (Status); 50467754Smsmith} 50567754Smsmith 506167802SjkimACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler) 50767754Smsmith 508167802Sjkim 50977424Smsmith/******************************************************************************* 51067754Smsmith * 51167754Smsmith * FUNCTION: AcpiRemoveNotifyHandler 51267754Smsmith * 51367754Smsmith * PARAMETERS: Device - The device for which notifies will be handled 51467754Smsmith * HandlerType - The type of handler: 51567754Smsmith * ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f) 51667754Smsmith * ACPI_DEVICE_NOTIFY: DriverHandler (80-ff) 517129684Snjl * ACPI_ALL_NOTIFY: both system and device 51867754Smsmith * Handler - Address of the handler 519138287Smarks * 52067754Smsmith * RETURN: Status 52167754Smsmith * 52267754Smsmith * DESCRIPTION: Remove a handler for notifies on an ACPI device 52367754Smsmith * 52467754Smsmith ******************************************************************************/ 52567754Smsmith 52667754SmsmithACPI_STATUS 52767754SmsmithAcpiRemoveNotifyHandler ( 52867754Smsmith ACPI_HANDLE Device, 52967754Smsmith UINT32 HandlerType, 53077424Smsmith ACPI_NOTIFY_HANDLER Handler) 53167754Smsmith{ 53267754Smsmith ACPI_OPERAND_OBJECT *NotifyObj; 53367754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 53499146Siwasaki ACPI_NAMESPACE_NODE *Node; 53591116Smsmith ACPI_STATUS Status; 53667754Smsmith 53777424Smsmith 538167802Sjkim ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler); 53967754Smsmith 54077424Smsmith 54167754Smsmith /* Parameter validation */ 54267754Smsmith 54399146Siwasaki if ((!Device) || 54499146Siwasaki (!Handler) || 54567754Smsmith (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 54667754Smsmith { 54767754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 54867754Smsmith } 54967754Smsmith 55091116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 55191116Smsmith if (ACPI_FAILURE (Status)) 55291116Smsmith { 55391116Smsmith return_ACPI_STATUS (Status); 55491116Smsmith } 55567754Smsmith 55667754Smsmith /* Convert and validate the device handle */ 55767754Smsmith 55899146Siwasaki Node = AcpiNsMapHandleToNode (Device); 55999146Siwasaki if (!Node) 56067754Smsmith { 56167754Smsmith Status = AE_BAD_PARAMETER; 56267754Smsmith goto UnlockAndExit; 56367754Smsmith } 56467754Smsmith 565138287Smarks /* Root Object */ 566138287Smarks 56787031Smsmith if (Device == ACPI_ROOT_OBJECT) 56885756Smsmith { 569151937Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 570167802Sjkim "Removing notify handler for namespace root object\n")); 57167754Smsmith 572129684Snjl if (((HandlerType & ACPI_SYSTEM_NOTIFY) && 573129684Snjl !AcpiGbl_SystemNotify.Handler) || 574129684Snjl ((HandlerType & ACPI_DEVICE_NOTIFY) && 575117521Snjl !AcpiGbl_DeviceNotify.Handler)) 57671867Smsmith { 57771867Smsmith Status = AE_NOT_EXIST; 57871867Smsmith goto UnlockAndExit; 57971867Smsmith } 58067754Smsmith 581129684Snjl if (HandlerType & ACPI_SYSTEM_NOTIFY) 58285756Smsmith { 583117521Snjl AcpiGbl_SystemNotify.Node = NULL; 584117521Snjl AcpiGbl_SystemNotify.Handler = NULL; 585117521Snjl AcpiGbl_SystemNotify.Context = NULL; 58671867Smsmith } 587129684Snjl 588129684Snjl if (HandlerType & ACPI_DEVICE_NOTIFY) 58985756Smsmith { 590117521Snjl AcpiGbl_DeviceNotify.Node = NULL; 591117521Snjl AcpiGbl_DeviceNotify.Handler = NULL; 592117521Snjl AcpiGbl_DeviceNotify.Context = NULL; 59371867Smsmith } 59467754Smsmith } 59567754Smsmith 596138287Smarks /* All Other Objects */ 597138287Smarks 59887031Smsmith else 59985756Smsmith { 60099146Siwasaki /* Notifies allowed on this object? */ 60199146Siwasaki 60299146Siwasaki if (!AcpiEvIsNotifyObject (Node)) 60371867Smsmith { 60499146Siwasaki Status = AE_TYPE; 60571867Smsmith goto UnlockAndExit; 60671867Smsmith } 60767754Smsmith 60871867Smsmith /* Check for an existing internal object */ 60967754Smsmith 61099146Siwasaki ObjDesc = AcpiNsGetAttachedObject (Node); 61171867Smsmith if (!ObjDesc) 61271867Smsmith { 61371867Smsmith Status = AE_NOT_EXIST; 61471867Smsmith goto UnlockAndExit; 61571867Smsmith } 61667754Smsmith 61771867Smsmith /* Object exists - make sure there's an existing handler */ 61871867Smsmith 619129684Snjl if (HandlerType & ACPI_SYSTEM_NOTIFY) 62071867Smsmith { 621117521Snjl NotifyObj = ObjDesc->CommonNotify.SystemNotify; 622167802Sjkim if (!NotifyObj) 623129684Snjl { 624167802Sjkim Status = AE_NOT_EXIST; 625167802Sjkim goto UnlockAndExit; 626167802Sjkim } 627167802Sjkim 628167802Sjkim if (NotifyObj->Notify.Handler != Handler) 629167802Sjkim { 630129684Snjl Status = AE_BAD_PARAMETER; 631129684Snjl goto UnlockAndExit; 632129684Snjl } 633129684Snjl 634129684Snjl /* Remove the handler */ 635129684Snjl 636129684Snjl ObjDesc->CommonNotify.SystemNotify = NULL; 637129684Snjl AcpiUtRemoveReference (NotifyObj); 63871867Smsmith } 639129684Snjl 640129684Snjl if (HandlerType & ACPI_DEVICE_NOTIFY) 64171867Smsmith { 642117521Snjl NotifyObj = ObjDesc->CommonNotify.DeviceNotify; 643167802Sjkim if (!NotifyObj) 644129684Snjl { 645167802Sjkim Status = AE_NOT_EXIST; 646167802Sjkim goto UnlockAndExit; 647167802Sjkim } 648167802Sjkim 649167802Sjkim if (NotifyObj->Notify.Handler != Handler) 650167802Sjkim { 651129684Snjl Status = AE_BAD_PARAMETER; 652129684Snjl goto UnlockAndExit; 653129684Snjl } 65471867Smsmith 655129684Snjl /* Remove the handler */ 65671867Smsmith 657117521Snjl ObjDesc->CommonNotify.DeviceNotify = NULL; 658129684Snjl AcpiUtRemoveReference (NotifyObj); 65971867Smsmith } 66067754Smsmith } 66167754Smsmith 66267754Smsmith 66367754SmsmithUnlockAndExit: 66491116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 66567754Smsmith return_ACPI_STATUS (Status); 66667754Smsmith} 66767754Smsmith 668167802SjkimACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler) 66971867Smsmith 670167802Sjkim 67177424Smsmith/******************************************************************************* 67267754Smsmith * 67367754Smsmith * FUNCTION: AcpiInstallGpeHandler 67467754Smsmith * 675151937Sjkim * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 676151937Sjkim * defined GPEs) 677151937Sjkim * GpeNumber - The GPE number within the GPE block 67867754Smsmith * Type - Whether this GPE should be treated as an 67967754Smsmith * edge- or level-triggered interrupt. 680129684Snjl * Address - Address of the handler 68167754Smsmith * Context - Value passed to the handler on each GPE 68267754Smsmith * 68367754Smsmith * RETURN: Status 68467754Smsmith * 68567754Smsmith * DESCRIPTION: Install a handler for a General Purpose Event. 68667754Smsmith * 68767754Smsmith ******************************************************************************/ 68867754Smsmith 68967754SmsmithACPI_STATUS 69067754SmsmithAcpiInstallGpeHandler ( 691117521Snjl ACPI_HANDLE GpeDevice, 69267754Smsmith UINT32 GpeNumber, 69367754Smsmith UINT32 Type, 694129684Snjl ACPI_EVENT_HANDLER Address, 69567754Smsmith void *Context) 69667754Smsmith{ 697129684Snjl ACPI_GPE_EVENT_INFO *GpeEventInfo; 698129684Snjl ACPI_HANDLER_INFO *Handler; 69991116Smsmith ACPI_STATUS Status; 700167802Sjkim ACPI_CPU_FLAGS Flags; 70167754Smsmith 70277424Smsmith 703167802Sjkim ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler); 70467754Smsmith 70577424Smsmith 70667754Smsmith /* Parameter validation */ 70767754Smsmith 708129684Snjl if ((!Address) || (Type > ACPI_GPE_XRUPT_TYPE_MASK)) 70967754Smsmith { 71067754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 71167754Smsmith } 71267754Smsmith 713117521Snjl Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 714117521Snjl if (ACPI_FAILURE (Status)) 715117521Snjl { 716117521Snjl return_ACPI_STATUS (Status); 717117521Snjl } 718117521Snjl 71967754Smsmith /* Ensure that we have a valid GPE number */ 72067754Smsmith 721117521Snjl GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 722114237Snjl if (!GpeEventInfo) 72367754Smsmith { 724117521Snjl Status = AE_BAD_PARAMETER; 725117521Snjl goto UnlockAndExit; 72667754Smsmith } 72767754Smsmith 72867754Smsmith /* Make sure that there isn't a handler there already */ 72967754Smsmith 730193267Sjkim if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 731193267Sjkim ACPI_GPE_DISPATCH_HANDLER) 73267754Smsmith { 73387031Smsmith Status = AE_ALREADY_EXISTS; 734117521Snjl goto UnlockAndExit; 73567754Smsmith } 73667754Smsmith 737129684Snjl /* Allocate and init handler object */ 73867754Smsmith 739167802Sjkim Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_HANDLER_INFO)); 740129684Snjl if (!Handler) 741129684Snjl { 742129684Snjl Status = AE_NO_MEMORY; 743129684Snjl goto UnlockAndExit; 744129684Snjl } 74567754Smsmith 746129684Snjl Handler->Address = Address; 747129684Snjl Handler->Context = Context; 748129684Snjl Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode; 74967754Smsmith 750129684Snjl /* Disable the GPE before installing the handler */ 751129684Snjl 752129684Snjl Status = AcpiEvDisableGpe (GpeEventInfo); 75399679Siwasaki if (ACPI_FAILURE (Status)) 75499679Siwasaki { 755117521Snjl goto UnlockAndExit; 75699679Siwasaki } 75767754Smsmith 758129684Snjl /* Install the handler */ 75985756Smsmith 760151937Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 761129684Snjl GpeEventInfo->Dispatch.Handler = Handler; 76299679Siwasaki 763129684Snjl /* Setup up dispatch flags to indicate handler (vs. method) */ 764129684Snjl 765193267Sjkim GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 766129684Snjl GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER); 767129684Snjl 768151937Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 769129684Snjl 770129684Snjl 771117521SnjlUnlockAndExit: 77291116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 77367754Smsmith return_ACPI_STATUS (Status); 77467754Smsmith} 77567754Smsmith 776167802SjkimACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler) 77767754Smsmith 778167802Sjkim 77977424Smsmith/******************************************************************************* 78067754Smsmith * 78167754Smsmith * FUNCTION: AcpiRemoveGpeHandler 78267754Smsmith * 783151937Sjkim * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 784151937Sjkim * defined GPEs) 785151937Sjkim * GpeNumber - The event to remove a handler 786129684Snjl * Address - Address of the handler 78767754Smsmith * 78867754Smsmith * RETURN: Status 78967754Smsmith * 79067754Smsmith * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent. 79167754Smsmith * 79267754Smsmith ******************************************************************************/ 79367754Smsmith 79467754SmsmithACPI_STATUS 79567754SmsmithAcpiRemoveGpeHandler ( 796117521Snjl ACPI_HANDLE GpeDevice, 79767754Smsmith UINT32 GpeNumber, 798129684Snjl ACPI_EVENT_HANDLER Address) 79967754Smsmith{ 800129684Snjl ACPI_GPE_EVENT_INFO *GpeEventInfo; 801129684Snjl ACPI_HANDLER_INFO *Handler; 80291116Smsmith ACPI_STATUS Status; 803167802Sjkim ACPI_CPU_FLAGS Flags; 80467754Smsmith 80567754Smsmith 806167802Sjkim ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler); 80767754Smsmith 80867754Smsmith 80967754Smsmith /* Parameter validation */ 81067754Smsmith 811129684Snjl if (!Address) 81267754Smsmith { 81367754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 81467754Smsmith } 81567754Smsmith 816117521Snjl Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 817117521Snjl if (ACPI_FAILURE (Status)) 818117521Snjl { 819117521Snjl return_ACPI_STATUS (Status); 820117521Snjl } 821117521Snjl 82267754Smsmith /* Ensure that we have a valid GPE number */ 82367754Smsmith 824117521Snjl GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 825114237Snjl if (!GpeEventInfo) 82667754Smsmith { 827117521Snjl Status = AE_BAD_PARAMETER; 828117521Snjl goto UnlockAndExit; 82967754Smsmith } 83067754Smsmith 831129684Snjl /* Make sure that a handler is indeed installed */ 83267754Smsmith 833193267Sjkim if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) != 834193267Sjkim ACPI_GPE_DISPATCH_HANDLER) 83599679Siwasaki { 836129684Snjl Status = AE_NOT_EXIST; 837117521Snjl goto UnlockAndExit; 83899679Siwasaki } 83967754Smsmith 84067754Smsmith /* Make sure that the installed handler is the same */ 84167754Smsmith 842129684Snjl if (GpeEventInfo->Dispatch.Handler->Address != Address) 84367754Smsmith { 84467754Smsmith Status = AE_BAD_PARAMETER; 845117521Snjl goto UnlockAndExit; 84667754Smsmith } 84767754Smsmith 848129684Snjl /* Disable the GPE before removing the handler */ 849129684Snjl 850129684Snjl Status = AcpiEvDisableGpe (GpeEventInfo); 851129684Snjl if (ACPI_FAILURE (Status)) 852129684Snjl { 853129684Snjl goto UnlockAndExit; 854129684Snjl } 855129684Snjl 85667754Smsmith /* Remove the handler */ 85767754Smsmith 858151937Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 859129684Snjl Handler = GpeEventInfo->Dispatch.Handler; 860129684Snjl 861129684Snjl /* Restore Method node (if any), set dispatch flags */ 862129684Snjl 863129684Snjl GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode; 864129684Snjl GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */ 865129684Snjl if (Handler->MethodNode) 866129684Snjl { 867129684Snjl GpeEventInfo->Flags |= ACPI_GPE_DISPATCH_METHOD; 868129684Snjl } 869151937Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 87067754Smsmith 871129684Snjl /* Now we can free the handler object */ 87285756Smsmith 873167802Sjkim ACPI_FREE (Handler); 874129684Snjl 875129684Snjl 876117521SnjlUnlockAndExit: 87791116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 87867754Smsmith return_ACPI_STATUS (Status); 87967754Smsmith} 88067754Smsmith 881167802SjkimACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler) 88267754Smsmith 883167802Sjkim 88477424Smsmith/******************************************************************************* 88567754Smsmith * 88667754Smsmith * FUNCTION: AcpiAcquireGlobalLock 88767754Smsmith * 88867754Smsmith * PARAMETERS: Timeout - How long the caller is willing to wait 889151937Sjkim * Handle - Where the handle to the lock is returned 890151937Sjkim * (if acquired) 89167754Smsmith * 89267754Smsmith * RETURN: Status 89367754Smsmith * 89467754Smsmith * DESCRIPTION: Acquire the ACPI Global Lock 89567754Smsmith * 896167802Sjkim * Note: Allows callers with the same thread ID to acquire the global lock 897167802Sjkim * multiple times. In other words, externally, the behavior of the global lock 898167802Sjkim * is identical to an AML mutex. On the first acquire, a new handle is 899167802Sjkim * returned. On any subsequent calls to acquire by the same thread, the same 900167802Sjkim * handle is returned. 901167802Sjkim * 90267754Smsmith ******************************************************************************/ 90385756Smsmith 90467754SmsmithACPI_STATUS 90567754SmsmithAcpiAcquireGlobalLock ( 906107325Siwasaki UINT16 Timeout, 90791116Smsmith UINT32 *Handle) 90867754Smsmith{ 90967754Smsmith ACPI_STATUS Status; 91067754Smsmith 91167754Smsmith 91291116Smsmith if (!Handle) 91391116Smsmith { 91491116Smsmith return (AE_BAD_PARAMETER); 91591116Smsmith } 91691116Smsmith 917167802Sjkim /* Must lock interpreter to prevent race conditions */ 91877424Smsmith 919167802Sjkim AcpiExEnterInterpreter (); 92067754Smsmith 921167802Sjkim Status = AcpiExAcquireMutexObject (Timeout, 922167802Sjkim AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ()); 923167802Sjkim 92491116Smsmith if (ACPI_SUCCESS (Status)) 92591116Smsmith { 926172314Sjkim /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */ 927167802Sjkim 92891116Smsmith *Handle = AcpiGbl_GlobalLockHandle; 92991116Smsmith } 93091116Smsmith 931167802Sjkim AcpiExExitInterpreter (); 93267754Smsmith return (Status); 93367754Smsmith} 93467754Smsmith 935167802SjkimACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock) 93667754Smsmith 937167802Sjkim 93877424Smsmith/******************************************************************************* 93967754Smsmith * 94067754Smsmith * FUNCTION: AcpiReleaseGlobalLock 94167754Smsmith * 94267754Smsmith * PARAMETERS: Handle - Returned from AcpiAcquireGlobalLock 94367754Smsmith * 94467754Smsmith * RETURN: Status 94567754Smsmith * 946151937Sjkim * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid. 94767754Smsmith * 94867754Smsmith ******************************************************************************/ 94967754Smsmith 95067754SmsmithACPI_STATUS 95167754SmsmithAcpiReleaseGlobalLock ( 95291116Smsmith UINT32 Handle) 95367754Smsmith{ 95499679Siwasaki ACPI_STATUS Status; 95585756Smsmith 95699679Siwasaki 957167802Sjkim if (!Handle || (Handle != AcpiGbl_GlobalLockHandle)) 95891116Smsmith { 95991116Smsmith return (AE_NOT_ACQUIRED); 96091116Smsmith } 96191116Smsmith 962167802Sjkim Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex); 96399679Siwasaki return (Status); 96467754Smsmith} 96567754Smsmith 966167802SjkimACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock) 96767754Smsmith 968