evxface.c revision 117521
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: evxface - External interfaces for ACPI events 4117521Snjl * $Revision: 141 $ 567754Smsmith * 667754Smsmith *****************************************************************************/ 767754Smsmith 867754Smsmith/****************************************************************************** 967754Smsmith * 1067754Smsmith * 1. Copyright Notice 1167754Smsmith * 12114237Snjl * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp. 1370243Smsmith * All rights reserved. 1467754Smsmith * 1567754Smsmith * 2. License 1667754Smsmith * 1767754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1867754Smsmith * rights. You may have additional license terms from the party that provided 1967754Smsmith * you this software, covering your right to use that party's intellectual 2067754Smsmith * property rights. 2167754Smsmith * 2267754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2367754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2467754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2567754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2667754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2767754Smsmith * Code in any form, with the right to sublicense such rights; and 2867754Smsmith * 2967754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3067754Smsmith * license (with the right to sublicense), under only those claims of Intel 3167754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3267754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3367754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3467754Smsmith * license, and in no event shall the patent license extend to any additions 3567754Smsmith * to or modifications of the Original Intel Code. No other license or right 3667754Smsmith * is granted directly or by implication, estoppel or otherwise; 3767754Smsmith * 3867754Smsmith * The above copyright and patent license is granted only if the following 3967754Smsmith * conditions are met: 4067754Smsmith * 4167754Smsmith * 3. Conditions 4267754Smsmith * 4367754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4467754Smsmith * Redistribution of source code of any substantial prton of the Covered 4567754Smsmith * Code or modification with rights to further distribute source must include 4667754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4767754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4867754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 4967754Smsmith * contain a file documenting the changes Licensee made to create that Covered 5067754Smsmith * Code and the date of any change. Licensee must include in that file the 5167754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5267754Smsmith * must include a prominent statement that the modification is derived, 5367754Smsmith * directly or indirectly, from Original Intel Code. 5467754Smsmith * 5567754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5667754Smsmith * Redistribution of source code of any substantial portion of the Covered 5767754Smsmith * Code or modification without rights to further distribute source must 5867754Smsmith * include the following Disclaimer and Export Compliance provision in the 5967754Smsmith * documentation and/or other materials provided with distribution. In 6067754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6167754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6267754Smsmith * license from Licensee to its licensee is limited to the intellectual 6367754Smsmith * property embodied in the software Licensee provides to its licensee, and 6467754Smsmith * not to intellectual property embodied in modifications its licensee may 6567754Smsmith * make. 6667754Smsmith * 6767754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 6867754Smsmith * substantial portion of the Covered Code or modification must reproduce the 6967754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 7067754Smsmith * provision in the documentation and/or other materials provided with the 7167754Smsmith * distribution. 7267754Smsmith * 7367754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7467754Smsmith * Intel Code. 7567754Smsmith * 7667754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7767754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7867754Smsmith * other dealings in products derived from or relating to the Covered Code 7967754Smsmith * without prior written authorization from Intel. 8067754Smsmith * 8167754Smsmith * 4. Disclaimer and Export Compliance 8267754Smsmith * 8367754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8467754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8567754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8667754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8767754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8867754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8967754Smsmith * PARTICULAR PURPOSE. 9067754Smsmith * 9167754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9267754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9367754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9467754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9567754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9667754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9767754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9867754Smsmith * LIMITED REMEDY. 9967754Smsmith * 10067754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10167754Smsmith * software or system incorporating such software without first obtaining any 10267754Smsmith * required license or other approval from the U. S. Department of Commerce or 10367754Smsmith * any other agency or department of the United States Government. In the 10467754Smsmith * event Licensee exports any such software from the United States or 10567754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10667754Smsmith * ensure that the distribution and export/re-export of the software is in 10767754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 10867754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10967754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 11067754Smsmith * software, or service, directly or indirectly, to any country for which the 11167754Smsmith * United States government or any agency thereof requires an export license, 11267754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11367754Smsmith * such license, approval or letter. 11467754Smsmith * 11567754Smsmith *****************************************************************************/ 11667754Smsmith 11767754Smsmith 11867754Smsmith#define __EVXFACE_C__ 11967754Smsmith 12067754Smsmith#include "acpi.h" 12167754Smsmith#include "acnamesp.h" 12267754Smsmith#include "acevents.h" 12367754Smsmith#include "acinterp.h" 12467754Smsmith 12577424Smsmith#define _COMPONENT ACPI_EVENTS 12691116Smsmith ACPI_MODULE_NAME ("evxface") 12767754Smsmith 12867754Smsmith 12977424Smsmith/******************************************************************************* 13067754Smsmith * 13167754Smsmith * FUNCTION: AcpiInstallFixedEventHandler 13267754Smsmith * 13367754Smsmith * PARAMETERS: Event - Event type to enable. 13467754Smsmith * Handler - Pointer to the handler function for the 13567754Smsmith * event 13667754Smsmith * Context - Value passed to the handler on each GPE 13767754Smsmith * 13867754Smsmith * RETURN: Status 13967754Smsmith * 14067754Smsmith * DESCRIPTION: Saves the pointer to the handler function and then enables the 14167754Smsmith * event. 14267754Smsmith * 14367754Smsmith ******************************************************************************/ 14467754Smsmith 14567754SmsmithACPI_STATUS 14667754SmsmithAcpiInstallFixedEventHandler ( 14767754Smsmith UINT32 Event, 14877424Smsmith ACPI_EVENT_HANDLER Handler, 14967754Smsmith void *Context) 15067754Smsmith{ 15177424Smsmith ACPI_STATUS Status; 15267754Smsmith 15367754Smsmith 15491116Smsmith ACPI_FUNCTION_TRACE ("AcpiInstallFixedEventHandler"); 15567754Smsmith 15667754Smsmith 15777424Smsmith /* Parameter validation */ 15877424Smsmith 15977424Smsmith if (Event > ACPI_EVENT_MAX) 16077424Smsmith { 16167754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 16267754Smsmith } 16367754Smsmith 16491116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 16591116Smsmith if (ACPI_FAILURE (Status)) 16691116Smsmith { 16791116Smsmith return_ACPI_STATUS (Status); 16891116Smsmith } 16967754Smsmith 17067754Smsmith /* Don't allow two handlers. */ 17167754Smsmith 17267754Smsmith if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler) 17367754Smsmith { 17487031Smsmith Status = AE_ALREADY_EXISTS; 17567754Smsmith goto Cleanup; 17667754Smsmith } 17767754Smsmith 17885756Smsmith /* Install the handler before enabling the event */ 17967754Smsmith 18067754Smsmith AcpiGbl_FixedEventHandlers[Event].Handler = Handler; 18167754Smsmith AcpiGbl_FixedEventHandlers[Event].Context = Context; 18267754Smsmith 183117521Snjl Status = AcpiEnableEvent (Event, 0); 18491116Smsmith if (ACPI_FAILURE (Status)) 18567754Smsmith { 18682367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n")); 18767754Smsmith 18867754Smsmith /* Remove the handler */ 18967754Smsmith 19067754Smsmith AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 19167754Smsmith AcpiGbl_FixedEventHandlers[Event].Context = NULL; 19277424Smsmith } 19377424Smsmith else 19477424Smsmith { 19582367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 19682367Smsmith "Enabled fixed event %X, Handler=%p\n", Event, Handler)); 19767754Smsmith } 19867754Smsmith 19967754Smsmith 20067754SmsmithCleanup: 20191116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 20267754Smsmith return_ACPI_STATUS (Status); 20367754Smsmith} 20467754Smsmith 20567754Smsmith 20677424Smsmith/******************************************************************************* 20767754Smsmith * 20867754Smsmith * FUNCTION: AcpiRemoveFixedEventHandler 20967754Smsmith * 21067754Smsmith * PARAMETERS: Event - Event type to disable. 21167754Smsmith * Handler - Address of the handler 21267754Smsmith * 21367754Smsmith * RETURN: Status 21467754Smsmith * 21567754Smsmith * DESCRIPTION: Disables the event and unregisters the event handler. 21667754Smsmith * 21767754Smsmith ******************************************************************************/ 21867754Smsmith 21967754SmsmithACPI_STATUS 22067754SmsmithAcpiRemoveFixedEventHandler ( 22167754Smsmith UINT32 Event, 22277424Smsmith ACPI_EVENT_HANDLER Handler) 22367754Smsmith{ 22467754Smsmith ACPI_STATUS Status = AE_OK; 22567754Smsmith 22667754Smsmith 22791116Smsmith ACPI_FUNCTION_TRACE ("AcpiRemoveFixedEventHandler"); 22867754Smsmith 22967754Smsmith 23077424Smsmith /* Parameter validation */ 23177424Smsmith 23277424Smsmith if (Event > ACPI_EVENT_MAX) 23377424Smsmith { 23467754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 23567754Smsmith } 23667754Smsmith 23791116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 23891116Smsmith if (ACPI_FAILURE (Status)) 23991116Smsmith { 24091116Smsmith return_ACPI_STATUS (Status); 24191116Smsmith } 24267754Smsmith 24385756Smsmith /* Disable the event before removing the handler */ 24467754Smsmith 245117521Snjl Status = AcpiDisableEvent (Event, 0); 24669450Smsmith 24777424Smsmith /* Always Remove the handler */ 24877424Smsmith 24977424Smsmith AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 25077424Smsmith AcpiGbl_FixedEventHandlers[Event].Context = NULL; 25177424Smsmith 25291116Smsmith if (ACPI_FAILURE (Status)) 25367754Smsmith { 25482367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_WARN, 25582367Smsmith "Could not write to fixed event enable register.\n")); 25677424Smsmith } 25777424Smsmith else 25877424Smsmith { 25982367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X.\n", Event)); 26067754Smsmith } 26167754Smsmith 26291116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 26367754Smsmith return_ACPI_STATUS (Status); 26467754Smsmith} 26567754Smsmith 26667754Smsmith 26777424Smsmith/******************************************************************************* 26867754Smsmith * 26967754Smsmith * FUNCTION: AcpiInstallNotifyHandler 27067754Smsmith * 27167754Smsmith * PARAMETERS: Device - The device for which notifies will be handled 27267754Smsmith * HandlerType - The type of handler: 27367754Smsmith * ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f) 27467754Smsmith * ACPI_DEVICE_NOTIFY: DriverHandler (80-ff) 27567754Smsmith * Handler - Address of the handler 27667754Smsmith * Context - Value passed to the handler on each GPE 27767754Smsmith * 27867754Smsmith * RETURN: Status 27967754Smsmith * 28067754Smsmith * DESCRIPTION: Install a handler for notifies on an ACPI device 28167754Smsmith * 28267754Smsmith ******************************************************************************/ 28367754Smsmith 28467754SmsmithACPI_STATUS 28567754SmsmithAcpiInstallNotifyHandler ( 28667754Smsmith ACPI_HANDLE Device, 28767754Smsmith UINT32 HandlerType, 28877424Smsmith ACPI_NOTIFY_HANDLER Handler, 28967754Smsmith void *Context) 29067754Smsmith{ 29167754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 29267754Smsmith ACPI_OPERAND_OBJECT *NotifyObj; 29399146Siwasaki ACPI_NAMESPACE_NODE *Node; 29491116Smsmith ACPI_STATUS Status; 29567754Smsmith 29667754Smsmith 29791116Smsmith ACPI_FUNCTION_TRACE ("AcpiInstallNotifyHandler"); 29867754Smsmith 29967754Smsmith 30067754Smsmith /* Parameter validation */ 30167754Smsmith 30299146Siwasaki if ((!Device) || 30399146Siwasaki (!Handler) || 30467754Smsmith (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 30567754Smsmith { 30667754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 30767754Smsmith } 30867754Smsmith 30991116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 31091116Smsmith if (ACPI_FAILURE (Status)) 31191116Smsmith { 31291116Smsmith return_ACPI_STATUS (Status); 31391116Smsmith } 31471867Smsmith 31567754Smsmith /* Convert and validate the device handle */ 31667754Smsmith 31799146Siwasaki Node = AcpiNsMapHandleToNode (Device); 31899146Siwasaki if (!Node) 31967754Smsmith { 32067754Smsmith Status = AE_BAD_PARAMETER; 32167754Smsmith goto UnlockAndExit; 32267754Smsmith } 32367754Smsmith 32467754Smsmith /* 32571867Smsmith * Root Object: 32671867Smsmith * Registering a notify handler on the root object indicates that the 32771867Smsmith * caller wishes to receive notifications for all objects. Note that 32871867Smsmith * only one <external> global handler can be regsitered (per notify type). 32967754Smsmith */ 33067754Smsmith if (Device == ACPI_ROOT_OBJECT) 33167754Smsmith { 33271867Smsmith /* Make sure the handler is not already installed */ 33367754Smsmith 33467754Smsmith if (((HandlerType == ACPI_SYSTEM_NOTIFY) && 335117521Snjl AcpiGbl_SystemNotify.Handler) || 33667754Smsmith ((HandlerType == ACPI_DEVICE_NOTIFY) && 337117521Snjl AcpiGbl_DeviceNotify.Handler)) 33867754Smsmith { 33987031Smsmith Status = AE_ALREADY_EXISTS; 34067754Smsmith goto UnlockAndExit; 34167754Smsmith } 34267754Smsmith 34367754Smsmith if (HandlerType == ACPI_SYSTEM_NOTIFY) 34467754Smsmith { 345117521Snjl AcpiGbl_SystemNotify.Node = Node; 346117521Snjl AcpiGbl_SystemNotify.Handler = Handler; 347117521Snjl AcpiGbl_SystemNotify.Context = Context; 34867754Smsmith } 34971867Smsmith else /* ACPI_DEVICE_NOTIFY */ 35067754Smsmith { 351117521Snjl AcpiGbl_DeviceNotify.Node = Node; 352117521Snjl AcpiGbl_DeviceNotify.Handler = Handler; 353117521Snjl AcpiGbl_DeviceNotify.Context = Context; 35467754Smsmith } 35567754Smsmith 35667754Smsmith /* Global notify handler installed */ 35767754Smsmith } 35867754Smsmith 35967754Smsmith /* 36085756Smsmith * All Other Objects: 36171867Smsmith * Caller will only receive notifications specific to the target object. 36271867Smsmith * Note that only certain object types can receive notifications. 36367754Smsmith */ 36487031Smsmith else 36585756Smsmith { 36699146Siwasaki /* Notifies allowed on this object? */ 36799146Siwasaki 36899146Siwasaki if (!AcpiEvIsNotifyObject (Node)) 36967754Smsmith { 37099146Siwasaki Status = AE_TYPE; 37167754Smsmith goto UnlockAndExit; 37267754Smsmith } 37367754Smsmith 37471867Smsmith /* Check for an existing internal object */ 37567754Smsmith 37699146Siwasaki ObjDesc = AcpiNsGetAttachedObject (Node); 37771867Smsmith if (ObjDesc) 37867754Smsmith { 37971867Smsmith /* Object exists - make sure there's no handler */ 38071867Smsmith 38171867Smsmith if (((HandlerType == ACPI_SYSTEM_NOTIFY) && 382117521Snjl ObjDesc->CommonNotify.SystemNotify) || 38371867Smsmith ((HandlerType == ACPI_DEVICE_NOTIFY) && 384117521Snjl ObjDesc->CommonNotify.DeviceNotify)) 38571867Smsmith { 38687031Smsmith Status = AE_ALREADY_EXISTS; 38771867Smsmith goto UnlockAndExit; 38871867Smsmith } 38967754Smsmith } 39071867Smsmith else 39171867Smsmith { 39271867Smsmith /* Create a new object */ 39367754Smsmith 39499146Siwasaki ObjDesc = AcpiUtCreateInternalObject (Node->Type); 39571867Smsmith if (!ObjDesc) 39671867Smsmith { 39771867Smsmith Status = AE_NO_MEMORY; 39871867Smsmith goto UnlockAndExit; 39971867Smsmith } 40067754Smsmith 40171867Smsmith /* Attach new object to the Node */ 40271867Smsmith 40399146Siwasaki Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type); 404117521Snjl 405117521Snjl /* Remove local reference to the object */ 406117521Snjl 407117521Snjl AcpiUtRemoveReference (ObjDesc); 408117521Snjl 40971867Smsmith if (ACPI_FAILURE (Status)) 41071867Smsmith { 41171867Smsmith goto UnlockAndExit; 41271867Smsmith } 41371867Smsmith } 41471867Smsmith 41571867Smsmith /* Install the handler */ 41671867Smsmith 417107325Siwasaki NotifyObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY); 41871867Smsmith if (!NotifyObj) 41967754Smsmith { 42071867Smsmith Status = AE_NO_MEMORY; 42167754Smsmith goto UnlockAndExit; 42267754Smsmith } 42367754Smsmith 424117521Snjl NotifyObj->Notify.Node = Node; 425117521Snjl NotifyObj->Notify.Handler = Handler; 426117521Snjl NotifyObj->Notify.Context = Context; 42767754Smsmith 42871867Smsmith if (HandlerType == ACPI_SYSTEM_NOTIFY) 42971867Smsmith { 430117521Snjl ObjDesc->CommonNotify.SystemNotify = NotifyObj; 43171867Smsmith } 43271867Smsmith else /* ACPI_DEVICE_NOTIFY */ 43371867Smsmith { 434117521Snjl ObjDesc->CommonNotify.DeviceNotify = NotifyObj; 43571867Smsmith } 43667754Smsmith } 43767754Smsmith 43885756Smsmith 43967754SmsmithUnlockAndExit: 44091116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 44167754Smsmith return_ACPI_STATUS (Status); 44267754Smsmith} 44367754Smsmith 44467754Smsmith 44577424Smsmith/******************************************************************************* 44667754Smsmith * 44767754Smsmith * FUNCTION: AcpiRemoveNotifyHandler 44867754Smsmith * 44967754Smsmith * PARAMETERS: Device - The device for which notifies will be handled 45067754Smsmith * HandlerType - The type of handler: 45167754Smsmith * ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f) 45267754Smsmith * ACPI_DEVICE_NOTIFY: DriverHandler (80-ff) 45367754Smsmith * Handler - Address of the handler 45467754Smsmith * RETURN: Status 45567754Smsmith * 45667754Smsmith * DESCRIPTION: Remove a handler for notifies on an ACPI device 45767754Smsmith * 45867754Smsmith ******************************************************************************/ 45967754Smsmith 46067754SmsmithACPI_STATUS 46167754SmsmithAcpiRemoveNotifyHandler ( 46267754Smsmith ACPI_HANDLE Device, 46367754Smsmith UINT32 HandlerType, 46477424Smsmith ACPI_NOTIFY_HANDLER Handler) 46567754Smsmith{ 46667754Smsmith ACPI_OPERAND_OBJECT *NotifyObj; 46767754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 46899146Siwasaki ACPI_NAMESPACE_NODE *Node; 46991116Smsmith ACPI_STATUS Status; 47067754Smsmith 47177424Smsmith 47291116Smsmith ACPI_FUNCTION_TRACE ("AcpiRemoveNotifyHandler"); 47367754Smsmith 47477424Smsmith 47567754Smsmith /* Parameter validation */ 47667754Smsmith 47799146Siwasaki if ((!Device) || 47899146Siwasaki (!Handler) || 47967754Smsmith (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 48067754Smsmith { 48167754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 48267754Smsmith } 48367754Smsmith 48491116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 48591116Smsmith if (ACPI_FAILURE (Status)) 48691116Smsmith { 48791116Smsmith return_ACPI_STATUS (Status); 48891116Smsmith } 48967754Smsmith 49067754Smsmith /* Convert and validate the device handle */ 49167754Smsmith 49299146Siwasaki Node = AcpiNsMapHandleToNode (Device); 49399146Siwasaki if (!Node) 49467754Smsmith { 49567754Smsmith Status = AE_BAD_PARAMETER; 49667754Smsmith goto UnlockAndExit; 49767754Smsmith } 49867754Smsmith 49967754Smsmith /* 50085756Smsmith * Root Object 50167754Smsmith */ 50287031Smsmith if (Device == ACPI_ROOT_OBJECT) 50385756Smsmith { 50482367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n")); 50567754Smsmith 50671867Smsmith if (((HandlerType == ACPI_SYSTEM_NOTIFY) && 507117521Snjl !AcpiGbl_SystemNotify.Handler) || 50871867Smsmith ((HandlerType == ACPI_DEVICE_NOTIFY) && 509117521Snjl !AcpiGbl_DeviceNotify.Handler)) 51071867Smsmith { 51171867Smsmith Status = AE_NOT_EXIST; 51271867Smsmith goto UnlockAndExit; 51371867Smsmith } 51467754Smsmith 51587031Smsmith if (HandlerType == ACPI_SYSTEM_NOTIFY) 51685756Smsmith { 517117521Snjl AcpiGbl_SystemNotify.Node = NULL; 518117521Snjl AcpiGbl_SystemNotify.Handler = NULL; 519117521Snjl AcpiGbl_SystemNotify.Context = NULL; 52071867Smsmith } 52187031Smsmith else 52285756Smsmith { 523117521Snjl AcpiGbl_DeviceNotify.Node = NULL; 524117521Snjl AcpiGbl_DeviceNotify.Handler = NULL; 525117521Snjl AcpiGbl_DeviceNotify.Context = NULL; 52671867Smsmith } 52767754Smsmith } 52867754Smsmith 52967754Smsmith /* 53085756Smsmith * All Other Objects 53167754Smsmith */ 53287031Smsmith else 53385756Smsmith { 53499146Siwasaki /* Notifies allowed on this object? */ 53599146Siwasaki 53699146Siwasaki if (!AcpiEvIsNotifyObject (Node)) 53771867Smsmith { 53899146Siwasaki Status = AE_TYPE; 53971867Smsmith goto UnlockAndExit; 54071867Smsmith } 54167754Smsmith 54271867Smsmith /* Check for an existing internal object */ 54367754Smsmith 54499146Siwasaki ObjDesc = AcpiNsGetAttachedObject (Node); 54571867Smsmith if (!ObjDesc) 54671867Smsmith { 54771867Smsmith Status = AE_NOT_EXIST; 54871867Smsmith goto UnlockAndExit; 54971867Smsmith } 55067754Smsmith 55171867Smsmith /* Object exists - make sure there's an existing handler */ 55271867Smsmith 55371867Smsmith if (HandlerType == ACPI_SYSTEM_NOTIFY) 55471867Smsmith { 555117521Snjl NotifyObj = ObjDesc->CommonNotify.SystemNotify; 55671867Smsmith } 55771867Smsmith else 55871867Smsmith { 559117521Snjl NotifyObj = ObjDesc->CommonNotify.DeviceNotify; 56071867Smsmith } 56171867Smsmith 56271867Smsmith if ((!NotifyObj) || 563117521Snjl (NotifyObj->Notify.Handler != Handler)) 56471867Smsmith { 56571867Smsmith Status = AE_BAD_PARAMETER; 56671867Smsmith goto UnlockAndExit; 56771867Smsmith } 56871867Smsmith 56971867Smsmith /* Remove the handler */ 57071867Smsmith 57171867Smsmith if (HandlerType == ACPI_SYSTEM_NOTIFY) 57271867Smsmith { 573117521Snjl ObjDesc->CommonNotify.SystemNotify = NULL; 57471867Smsmith } 57571867Smsmith else 57671867Smsmith { 577117521Snjl ObjDesc->CommonNotify.DeviceNotify = NULL; 57871867Smsmith } 57971867Smsmith 58077424Smsmith AcpiUtRemoveReference (NotifyObj); 58167754Smsmith } 58267754Smsmith 58367754Smsmith 58467754SmsmithUnlockAndExit: 58591116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 58667754Smsmith return_ACPI_STATUS (Status); 58767754Smsmith} 58867754Smsmith 58971867Smsmith 59077424Smsmith/******************************************************************************* 59167754Smsmith * 59267754Smsmith * FUNCTION: AcpiInstallGpeHandler 59367754Smsmith * 594117521Snjl * PARAMETERS: GpeNumber - The GPE number within the GPE block 595117521Snjl * GpeBlock - GPE block (NULL == FADT GPEs) 59667754Smsmith * Type - Whether this GPE should be treated as an 59767754Smsmith * edge- or level-triggered interrupt. 59867754Smsmith * Handler - Address of the handler 59967754Smsmith * Context - Value passed to the handler on each GPE 60067754Smsmith * 60167754Smsmith * RETURN: Status 60267754Smsmith * 60367754Smsmith * DESCRIPTION: Install a handler for a General Purpose Event. 60467754Smsmith * 60567754Smsmith ******************************************************************************/ 60667754Smsmith 60767754SmsmithACPI_STATUS 60867754SmsmithAcpiInstallGpeHandler ( 609117521Snjl ACPI_HANDLE GpeDevice, 61067754Smsmith UINT32 GpeNumber, 61167754Smsmith UINT32 Type, 61277424Smsmith ACPI_GPE_HANDLER Handler, 61367754Smsmith void *Context) 61467754Smsmith{ 61591116Smsmith ACPI_STATUS Status; 616114237Snjl ACPI_GPE_EVENT_INFO *GpeEventInfo; 61767754Smsmith 61877424Smsmith 61991116Smsmith ACPI_FUNCTION_TRACE ("AcpiInstallGpeHandler"); 62067754Smsmith 62177424Smsmith 62267754Smsmith /* Parameter validation */ 62367754Smsmith 62491116Smsmith if (!Handler) 62567754Smsmith { 62667754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 62767754Smsmith } 62867754Smsmith 629117521Snjl Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 630117521Snjl if (ACPI_FAILURE (Status)) 631117521Snjl { 632117521Snjl return_ACPI_STATUS (Status); 633117521Snjl } 634117521Snjl 63567754Smsmith /* Ensure that we have a valid GPE number */ 63667754Smsmith 637117521Snjl GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 638114237Snjl if (!GpeEventInfo) 63967754Smsmith { 640117521Snjl Status = AE_BAD_PARAMETER; 641117521Snjl goto UnlockAndExit; 64267754Smsmith } 64367754Smsmith 64467754Smsmith /* Make sure that there isn't a handler there already */ 64567754Smsmith 646114237Snjl if (GpeEventInfo->Handler) 64767754Smsmith { 64887031Smsmith Status = AE_ALREADY_EXISTS; 649117521Snjl goto UnlockAndExit; 65067754Smsmith } 65167754Smsmith 65267754Smsmith /* Install the handler */ 65367754Smsmith 654117521Snjl AcpiOsAcquireLock (AcpiGbl_GpeLock, ACPI_NOT_ISR); 655114237Snjl GpeEventInfo->Handler = Handler; 656114237Snjl GpeEventInfo->Context = Context; 657117521Snjl GpeEventInfo->Flags = (UINT8) Type; 658117521Snjl AcpiOsReleaseLock (AcpiGbl_GpeLock, ACPI_NOT_ISR); 65967754Smsmith 66067754Smsmith /* Clear the GPE (of stale events), the enable it */ 66167754Smsmith 662114237Snjl Status = AcpiHwClearGpe (GpeEventInfo); 66399679Siwasaki if (ACPI_FAILURE (Status)) 66499679Siwasaki { 665117521Snjl goto UnlockAndExit; 66699679Siwasaki } 66767754Smsmith 668114237Snjl Status = AcpiHwEnableGpe (GpeEventInfo); 66985756Smsmith 67099679Siwasaki 671117521SnjlUnlockAndExit: 67291116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 67367754Smsmith return_ACPI_STATUS (Status); 67467754Smsmith} 67567754Smsmith 67667754Smsmith 67777424Smsmith/******************************************************************************* 67867754Smsmith * 67967754Smsmith * FUNCTION: AcpiRemoveGpeHandler 68067754Smsmith * 68167754Smsmith * PARAMETERS: GpeNumber - The event to remove a handler 682117521Snjl * GpeBlock - GPE block (NULL == FADT GPEs) 68367754Smsmith * Handler - Address of the handler 68467754Smsmith * 68567754Smsmith * RETURN: Status 68667754Smsmith * 68767754Smsmith * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent. 68867754Smsmith * 68967754Smsmith ******************************************************************************/ 69067754Smsmith 69167754SmsmithACPI_STATUS 69267754SmsmithAcpiRemoveGpeHandler ( 693117521Snjl ACPI_HANDLE GpeDevice, 69467754Smsmith UINT32 GpeNumber, 69577424Smsmith ACPI_GPE_HANDLER Handler) 69667754Smsmith{ 69791116Smsmith ACPI_STATUS Status; 698114237Snjl ACPI_GPE_EVENT_INFO *GpeEventInfo; 69967754Smsmith 70067754Smsmith 70191116Smsmith ACPI_FUNCTION_TRACE ("AcpiRemoveGpeHandler"); 70267754Smsmith 70367754Smsmith 70467754Smsmith /* Parameter validation */ 70567754Smsmith 70691116Smsmith if (!Handler) 70767754Smsmith { 70867754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 70967754Smsmith } 71067754Smsmith 711117521Snjl Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 712117521Snjl if (ACPI_FAILURE (Status)) 713117521Snjl { 714117521Snjl return_ACPI_STATUS (Status); 715117521Snjl } 716117521Snjl 71767754Smsmith /* Ensure that we have a valid GPE number */ 71867754Smsmith 719117521Snjl GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 720114237Snjl if (!GpeEventInfo) 72167754Smsmith { 722117521Snjl Status = AE_BAD_PARAMETER; 723117521Snjl goto UnlockAndExit; 72467754Smsmith } 72567754Smsmith 72667754Smsmith /* Disable the GPE before removing the handler */ 72767754Smsmith 728114237Snjl Status = AcpiHwDisableGpe (GpeEventInfo); 72999679Siwasaki if (ACPI_FAILURE (Status)) 73099679Siwasaki { 731117521Snjl goto UnlockAndExit; 73299679Siwasaki } 73367754Smsmith 73467754Smsmith /* Make sure that the installed handler is the same */ 73567754Smsmith 736114237Snjl if (GpeEventInfo->Handler != Handler) 73767754Smsmith { 738114237Snjl (void) AcpiHwEnableGpe (GpeEventInfo); 73967754Smsmith Status = AE_BAD_PARAMETER; 740117521Snjl goto UnlockAndExit; 74167754Smsmith } 74267754Smsmith 74367754Smsmith /* Remove the handler */ 74467754Smsmith 745117521Snjl AcpiOsAcquireLock (AcpiGbl_GpeLock, ACPI_NOT_ISR); 746114237Snjl GpeEventInfo->Handler = NULL; 747114237Snjl GpeEventInfo->Context = NULL; 748117521Snjl AcpiOsReleaseLock (AcpiGbl_GpeLock, ACPI_NOT_ISR); 74967754Smsmith 75085756Smsmith 751117521SnjlUnlockAndExit: 75291116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 75367754Smsmith return_ACPI_STATUS (Status); 75467754Smsmith} 75567754Smsmith 75667754Smsmith 75777424Smsmith/******************************************************************************* 75867754Smsmith * 75967754Smsmith * FUNCTION: AcpiAcquireGlobalLock 76067754Smsmith * 76167754Smsmith * PARAMETERS: Timeout - How long the caller is willing to wait 76267754Smsmith * OutHandle - A handle to the lock if acquired 76367754Smsmith * 76467754Smsmith * RETURN: Status 76567754Smsmith * 76667754Smsmith * DESCRIPTION: Acquire the ACPI Global Lock 76767754Smsmith * 76867754Smsmith ******************************************************************************/ 76985756Smsmith 77067754SmsmithACPI_STATUS 77167754SmsmithAcpiAcquireGlobalLock ( 772107325Siwasaki UINT16 Timeout, 77391116Smsmith UINT32 *Handle) 77467754Smsmith{ 77567754Smsmith ACPI_STATUS Status; 77667754Smsmith 77767754Smsmith 77891116Smsmith if (!Handle) 77991116Smsmith { 78091116Smsmith return (AE_BAD_PARAMETER); 78191116Smsmith } 78291116Smsmith 78377424Smsmith Status = AcpiExEnterInterpreter (); 78477424Smsmith if (ACPI_FAILURE (Status)) 78577424Smsmith { 78677424Smsmith return (Status); 78777424Smsmith } 78877424Smsmith 78991116Smsmith Status = AcpiEvAcquireGlobalLock (Timeout); 79077424Smsmith AcpiExExitInterpreter (); 79167754Smsmith 79291116Smsmith if (ACPI_SUCCESS (Status)) 79391116Smsmith { 79491116Smsmith AcpiGbl_GlobalLockHandle++; 79591116Smsmith *Handle = AcpiGbl_GlobalLockHandle; 79691116Smsmith } 79791116Smsmith 79867754Smsmith return (Status); 79967754Smsmith} 80067754Smsmith 80167754Smsmith 80277424Smsmith/******************************************************************************* 80367754Smsmith * 80467754Smsmith * FUNCTION: AcpiReleaseGlobalLock 80567754Smsmith * 80667754Smsmith * PARAMETERS: Handle - Returned from AcpiAcquireGlobalLock 80767754Smsmith * 80867754Smsmith * RETURN: Status 80967754Smsmith * 81067754Smsmith * DESCRIPTION: Release the ACPI Global Lock 81167754Smsmith * 81267754Smsmith ******************************************************************************/ 81367754Smsmith 81467754SmsmithACPI_STATUS 81567754SmsmithAcpiReleaseGlobalLock ( 81691116Smsmith UINT32 Handle) 81767754Smsmith{ 81899679Siwasaki ACPI_STATUS Status; 81985756Smsmith 82099679Siwasaki 82191116Smsmith if (Handle != AcpiGbl_GlobalLockHandle) 82291116Smsmith { 82391116Smsmith return (AE_NOT_ACQUIRED); 82491116Smsmith } 82591116Smsmith 82699679Siwasaki Status = AcpiEvReleaseGlobalLock (); 82799679Siwasaki return (Status); 82867754Smsmith} 82967754Smsmith 83067754Smsmith 831