Home | History | Annotate | Line # | Download | only in events
evxface.c revision 1.1
      1 /******************************************************************************
      2  *
      3  * Module Name: evxface - External interfaces for ACPI events
      4  *
      5  *****************************************************************************/
      6 
      7 /******************************************************************************
      8  *
      9  * 1. Copyright Notice
     10  *
     11  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
     12  * All rights reserved.
     13  *
     14  * 2. License
     15  *
     16  * 2.1. This is your license from Intel Corp. under its intellectual property
     17  * rights.  You may have additional license terms from the party that provided
     18  * you this software, covering your right to use that party's intellectual
     19  * property rights.
     20  *
     21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     22  * copy of the source code appearing in this file ("Covered Code") an
     23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     24  * base code distributed originally by Intel ("Original Intel Code") to copy,
     25  * make derivatives, distribute, use and display any portion of the Covered
     26  * Code in any form, with the right to sublicense such rights; and
     27  *
     28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     29  * license (with the right to sublicense), under only those claims of Intel
     30  * patents that are infringed by the Original Intel Code, to make, use, sell,
     31  * offer to sell, and import the Covered Code and derivative works thereof
     32  * solely to the minimum extent necessary to exercise the above copyright
     33  * license, and in no event shall the patent license extend to any additions
     34  * to or modifications of the Original Intel Code.  No other license or right
     35  * is granted directly or by implication, estoppel or otherwise;
     36  *
     37  * The above copyright and patent license is granted only if the following
     38  * conditions are met:
     39  *
     40  * 3. Conditions
     41  *
     42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     43  * Redistribution of source code of any substantial portion of the Covered
     44  * Code or modification with rights to further distribute source must include
     45  * the above Copyright Notice, the above License, this list of Conditions,
     46  * and the following Disclaimer and Export Compliance provision.  In addition,
     47  * Licensee must cause all Covered Code to which Licensee contributes to
     48  * contain a file documenting the changes Licensee made to create that Covered
     49  * Code and the date of any change.  Licensee must include in that file the
     50  * documentation of any changes made by any predecessor Licensee.  Licensee
     51  * must include a prominent statement that the modification is derived,
     52  * directly or indirectly, from Original Intel Code.
     53  *
     54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     55  * Redistribution of source code of any substantial portion of the Covered
     56  * Code or modification without rights to further distribute source must
     57  * include the following Disclaimer and Export Compliance provision in the
     58  * documentation and/or other materials provided with distribution.  In
     59  * addition, Licensee may not authorize further sublicense of source of any
     60  * portion of the Covered Code, and must include terms to the effect that the
     61  * license from Licensee to its licensee is limited to the intellectual
     62  * property embodied in the software Licensee provides to its licensee, and
     63  * not to intellectual property embodied in modifications its licensee may
     64  * make.
     65  *
     66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     67  * substantial portion of the Covered Code or modification must reproduce the
     68  * above Copyright Notice, and the following Disclaimer and Export Compliance
     69  * provision in the documentation and/or other materials provided with the
     70  * distribution.
     71  *
     72  * 3.4. Intel retains all right, title, and interest in and to the Original
     73  * Intel Code.
     74  *
     75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     76  * Intel shall be used in advertising or otherwise to promote the sale, use or
     77  * other dealings in products derived from or relating to the Covered Code
     78  * without prior written authorization from Intel.
     79  *
     80  * 4. Disclaimer and Export Compliance
     81  *
     82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     83  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
     85  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
     86  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
     87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     88  * PARTICULAR PURPOSE.
     89  *
     90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
     96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     97  * LIMITED REMEDY.
     98  *
     99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    100  * software or system incorporating such software without first obtaining any
    101  * required license or other approval from the U. S. Department of Commerce or
    102  * any other agency or department of the United States Government.  In the
    103  * event Licensee exports any such software from the United States or
    104  * re-exports any such software from a foreign destination, Licensee shall
    105  * ensure that the distribution and export/re-export of the software is in
    106  * compliance with all laws, regulations, orders, or other restrictions of the
    107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    108  * any of its subsidiaries will export/re-export any technical data, process,
    109  * software, or service, directly or indirectly, to any country for which the
    110  * United States government or any agency thereof requires an export license,
    111  * other governmental approval, or letter of assurance, without first obtaining
    112  * such license, approval or letter.
    113  *
    114  *****************************************************************************/
    115 
    116 
    117 #define __EVXFACE_C__
    118 
    119 #include "acpi.h"
    120 #include "accommon.h"
    121 #include "acnamesp.h"
    122 #include "acevents.h"
    123 #include "acinterp.h"
    124 
    125 #define _COMPONENT          ACPI_EVENTS
    126         ACPI_MODULE_NAME    ("evxface")
    127 
    128 
    129 /*******************************************************************************
    130  *
    131  * FUNCTION:    AcpiInstallExceptionHandler
    132  *
    133  * PARAMETERS:  Handler         - Pointer to the handler function for the
    134  *                                event
    135  *
    136  * RETURN:      Status
    137  *
    138  * DESCRIPTION: Saves the pointer to the handler function
    139  *
    140  ******************************************************************************/
    141 
    142 ACPI_STATUS
    143 AcpiInstallExceptionHandler (
    144     ACPI_EXCEPTION_HANDLER  Handler)
    145 {
    146     ACPI_STATUS             Status;
    147 
    148 
    149     ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler);
    150 
    151 
    152     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    153     if (ACPI_FAILURE (Status))
    154     {
    155         return_ACPI_STATUS (Status);
    156     }
    157 
    158     /* Don't allow two handlers. */
    159 
    160     if (AcpiGbl_ExceptionHandler)
    161     {
    162         Status = AE_ALREADY_EXISTS;
    163         goto Cleanup;
    164     }
    165 
    166     /* Install the handler */
    167 
    168     AcpiGbl_ExceptionHandler = Handler;
    169 
    170 Cleanup:
    171     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    172     return_ACPI_STATUS (Status);
    173 }
    174 
    175 ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler)
    176 
    177 
    178 /*******************************************************************************
    179  *
    180  * FUNCTION:    AcpiInstallFixedEventHandler
    181  *
    182  * PARAMETERS:  Event           - Event type to enable.
    183  *              Handler         - Pointer to the handler function for the
    184  *                                event
    185  *              Context         - Value passed to the handler on each GPE
    186  *
    187  * RETURN:      Status
    188  *
    189  * DESCRIPTION: Saves the pointer to the handler function and then enables the
    190  *              event.
    191  *
    192  ******************************************************************************/
    193 
    194 ACPI_STATUS
    195 AcpiInstallFixedEventHandler (
    196     UINT32                  Event,
    197     ACPI_EVENT_HANDLER      Handler,
    198     void                    *Context)
    199 {
    200     ACPI_STATUS             Status;
    201 
    202 
    203     ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler);
    204 
    205 
    206     /* Parameter validation */
    207 
    208     if (Event > ACPI_EVENT_MAX)
    209     {
    210         return_ACPI_STATUS (AE_BAD_PARAMETER);
    211     }
    212 
    213     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    214     if (ACPI_FAILURE (Status))
    215     {
    216         return_ACPI_STATUS (Status);
    217     }
    218 
    219     /* Don't allow two handlers. */
    220 
    221     if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler)
    222     {
    223         Status = AE_ALREADY_EXISTS;
    224         goto Cleanup;
    225     }
    226 
    227     /* Install the handler before enabling the event */
    228 
    229     AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
    230     AcpiGbl_FixedEventHandlers[Event].Context = Context;
    231 
    232     Status = AcpiEnableEvent (Event, 0);
    233     if (ACPI_FAILURE (Status))
    234     {
    235         ACPI_WARNING ((AE_INFO, "Could not enable fixed event 0x%X", Event));
    236 
    237         /* Remove the handler */
    238 
    239         AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
    240         AcpiGbl_FixedEventHandlers[Event].Context = NULL;
    241     }
    242     else
    243     {
    244         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    245             "Enabled fixed event %X, Handler=%p\n", Event, Handler));
    246     }
    247 
    248 
    249 Cleanup:
    250     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    251     return_ACPI_STATUS (Status);
    252 }
    253 
    254 ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler)
    255 
    256 
    257 /*******************************************************************************
    258  *
    259  * FUNCTION:    AcpiRemoveFixedEventHandler
    260  *
    261  * PARAMETERS:  Event           - Event type to disable.
    262  *              Handler         - Address of the handler
    263  *
    264  * RETURN:      Status
    265  *
    266  * DESCRIPTION: Disables the event and unregisters the event handler.
    267  *
    268  ******************************************************************************/
    269 
    270 ACPI_STATUS
    271 AcpiRemoveFixedEventHandler (
    272     UINT32                  Event,
    273     ACPI_EVENT_HANDLER      Handler)
    274 {
    275     ACPI_STATUS             Status = AE_OK;
    276 
    277 
    278     ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler);
    279 
    280 
    281     /* Parameter validation */
    282 
    283     if (Event > ACPI_EVENT_MAX)
    284     {
    285         return_ACPI_STATUS (AE_BAD_PARAMETER);
    286     }
    287 
    288     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    289     if (ACPI_FAILURE (Status))
    290     {
    291         return_ACPI_STATUS (Status);
    292     }
    293 
    294     /* Disable the event before removing the handler */
    295 
    296     Status = AcpiDisableEvent (Event, 0);
    297 
    298     /* Always Remove the handler */
    299 
    300     AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
    301     AcpiGbl_FixedEventHandlers[Event].Context = NULL;
    302 
    303     if (ACPI_FAILURE (Status))
    304     {
    305         ACPI_WARNING ((AE_INFO,
    306             "Could not write to fixed event enable register 0x%X", Event));
    307     }
    308     else
    309     {
    310         ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X\n", Event));
    311     }
    312 
    313     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    314     return_ACPI_STATUS (Status);
    315 }
    316 
    317 ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler)
    318 
    319 
    320 /*******************************************************************************
    321  *
    322  * FUNCTION:    AcpiInstallNotifyHandler
    323  *
    324  * PARAMETERS:  Device          - The device for which notifies will be handled
    325  *              HandlerType     - The type of handler:
    326  *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
    327  *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
    328  *                                  ACPI_ALL_NOTIFY:  both system and device
    329  *              Handler         - Address of the handler
    330  *              Context         - Value passed to the handler on each GPE
    331  *
    332  * RETURN:      Status
    333  *
    334  * DESCRIPTION: Install a handler for notifies on an ACPI device
    335  *
    336  ******************************************************************************/
    337 
    338 ACPI_STATUS
    339 AcpiInstallNotifyHandler (
    340     ACPI_HANDLE             Device,
    341     UINT32                  HandlerType,
    342     ACPI_NOTIFY_HANDLER     Handler,
    343     void                    *Context)
    344 {
    345     ACPI_OPERAND_OBJECT     *ObjDesc;
    346     ACPI_OPERAND_OBJECT     *NotifyObj;
    347     ACPI_NAMESPACE_NODE     *Node;
    348     ACPI_STATUS             Status;
    349 
    350 
    351     ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler);
    352 
    353 
    354     /* Parameter validation */
    355 
    356     if ((!Device)  ||
    357         (!Handler) ||
    358         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
    359     {
    360         return_ACPI_STATUS (AE_BAD_PARAMETER);
    361     }
    362 
    363     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    364     if (ACPI_FAILURE (Status))
    365     {
    366         return_ACPI_STATUS (Status);
    367     }
    368 
    369     /* Convert and validate the device handle */
    370 
    371     Node = AcpiNsValidateHandle (Device);
    372     if (!Node)
    373     {
    374         Status = AE_BAD_PARAMETER;
    375         goto UnlockAndExit;
    376     }
    377 
    378     /*
    379      * Root Object:
    380      * Registering a notify handler on the root object indicates that the
    381      * caller wishes to receive notifications for all objects. Note that
    382      * only one <external> global handler can be regsitered (per notify type).
    383      */
    384     if (Device == ACPI_ROOT_OBJECT)
    385     {
    386         /* Make sure the handler is not already installed */
    387 
    388         if (((HandlerType & ACPI_SYSTEM_NOTIFY) &&
    389                 AcpiGbl_SystemNotify.Handler)       ||
    390             ((HandlerType & ACPI_DEVICE_NOTIFY) &&
    391                 AcpiGbl_DeviceNotify.Handler))
    392         {
    393             Status = AE_ALREADY_EXISTS;
    394             goto UnlockAndExit;
    395         }
    396 
    397         if (HandlerType & ACPI_SYSTEM_NOTIFY)
    398         {
    399             AcpiGbl_SystemNotify.Node    = Node;
    400             AcpiGbl_SystemNotify.Handler = Handler;
    401             AcpiGbl_SystemNotify.Context = Context;
    402         }
    403 
    404         if (HandlerType & ACPI_DEVICE_NOTIFY)
    405         {
    406             AcpiGbl_DeviceNotify.Node    = Node;
    407             AcpiGbl_DeviceNotify.Handler = Handler;
    408             AcpiGbl_DeviceNotify.Context = Context;
    409         }
    410 
    411         /* Global notify handler installed */
    412     }
    413 
    414     /*
    415      * All Other Objects:
    416      * Caller will only receive notifications specific to the target object.
    417      * Note that only certain object types can receive notifications.
    418      */
    419     else
    420     {
    421         /* Notifies allowed on this object? */
    422 
    423         if (!AcpiEvIsNotifyObject (Node))
    424         {
    425             Status = AE_TYPE;
    426             goto UnlockAndExit;
    427         }
    428 
    429         /* Check for an existing internal object */
    430 
    431         ObjDesc = AcpiNsGetAttachedObject (Node);
    432         if (ObjDesc)
    433         {
    434             /* Object exists - make sure there's no handler */
    435 
    436             if (((HandlerType & ACPI_SYSTEM_NOTIFY) &&
    437                     ObjDesc->CommonNotify.SystemNotify)   ||
    438                 ((HandlerType & ACPI_DEVICE_NOTIFY) &&
    439                     ObjDesc->CommonNotify.DeviceNotify))
    440             {
    441                 Status = AE_ALREADY_EXISTS;
    442                 goto UnlockAndExit;
    443             }
    444         }
    445         else
    446         {
    447             /* Create a new object */
    448 
    449             ObjDesc = AcpiUtCreateInternalObject (Node->Type);
    450             if (!ObjDesc)
    451             {
    452                 Status = AE_NO_MEMORY;
    453                 goto UnlockAndExit;
    454             }
    455 
    456             /* Attach new object to the Node */
    457 
    458             Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
    459 
    460             /* Remove local reference to the object */
    461 
    462             AcpiUtRemoveReference (ObjDesc);
    463             if (ACPI_FAILURE (Status))
    464             {
    465                 goto UnlockAndExit;
    466             }
    467         }
    468 
    469         /* Install the handler */
    470 
    471         NotifyObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
    472         if (!NotifyObj)
    473         {
    474             Status = AE_NO_MEMORY;
    475             goto UnlockAndExit;
    476         }
    477 
    478         NotifyObj->Notify.Node    = Node;
    479         NotifyObj->Notify.Handler = Handler;
    480         NotifyObj->Notify.Context = Context;
    481 
    482         if (HandlerType & ACPI_SYSTEM_NOTIFY)
    483         {
    484             ObjDesc->CommonNotify.SystemNotify = NotifyObj;
    485         }
    486 
    487         if (HandlerType & ACPI_DEVICE_NOTIFY)
    488         {
    489             ObjDesc->CommonNotify.DeviceNotify = NotifyObj;
    490         }
    491 
    492         if (HandlerType == ACPI_ALL_NOTIFY)
    493         {
    494             /* Extra ref if installed in both */
    495 
    496             AcpiUtAddReference (NotifyObj);
    497         }
    498     }
    499 
    500 
    501 UnlockAndExit:
    502     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    503     return_ACPI_STATUS (Status);
    504 }
    505 
    506 ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler)
    507 
    508 
    509 /*******************************************************************************
    510  *
    511  * FUNCTION:    AcpiRemoveNotifyHandler
    512  *
    513  * PARAMETERS:  Device          - The device for which notifies will be handled
    514  *              HandlerType     - The type of handler:
    515  *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
    516  *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
    517  *                                  ACPI_ALL_NOTIFY:  both system and device
    518  *              Handler         - Address of the handler
    519  *
    520  * RETURN:      Status
    521  *
    522  * DESCRIPTION: Remove a handler for notifies on an ACPI device
    523  *
    524  ******************************************************************************/
    525 
    526 ACPI_STATUS
    527 AcpiRemoveNotifyHandler (
    528     ACPI_HANDLE             Device,
    529     UINT32                  HandlerType,
    530     ACPI_NOTIFY_HANDLER     Handler)
    531 {
    532     ACPI_OPERAND_OBJECT     *NotifyObj;
    533     ACPI_OPERAND_OBJECT     *ObjDesc;
    534     ACPI_NAMESPACE_NODE     *Node;
    535     ACPI_STATUS             Status;
    536 
    537 
    538     ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler);
    539 
    540 
    541     /* Parameter validation */
    542 
    543     if ((!Device)  ||
    544         (!Handler) ||
    545         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
    546     {
    547         return_ACPI_STATUS (AE_BAD_PARAMETER);
    548     }
    549 
    550     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    551     if (ACPI_FAILURE (Status))
    552     {
    553         return_ACPI_STATUS (Status);
    554     }
    555 
    556     /* Convert and validate the device handle */
    557 
    558     Node = AcpiNsValidateHandle (Device);
    559     if (!Node)
    560     {
    561         Status = AE_BAD_PARAMETER;
    562         goto UnlockAndExit;
    563     }
    564 
    565     /* Root Object */
    566 
    567     if (Device == ACPI_ROOT_OBJECT)
    568     {
    569         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    570             "Removing notify handler for namespace root object\n"));
    571 
    572         if (((HandlerType & ACPI_SYSTEM_NOTIFY) &&
    573               !AcpiGbl_SystemNotify.Handler)        ||
    574             ((HandlerType & ACPI_DEVICE_NOTIFY) &&
    575               !AcpiGbl_DeviceNotify.Handler))
    576         {
    577             Status = AE_NOT_EXIST;
    578             goto UnlockAndExit;
    579         }
    580 
    581         if (HandlerType & ACPI_SYSTEM_NOTIFY)
    582         {
    583             AcpiGbl_SystemNotify.Node    = NULL;
    584             AcpiGbl_SystemNotify.Handler = NULL;
    585             AcpiGbl_SystemNotify.Context = NULL;
    586         }
    587 
    588         if (HandlerType & ACPI_DEVICE_NOTIFY)
    589         {
    590             AcpiGbl_DeviceNotify.Node    = NULL;
    591             AcpiGbl_DeviceNotify.Handler = NULL;
    592             AcpiGbl_DeviceNotify.Context = NULL;
    593         }
    594     }
    595 
    596     /* All Other Objects */
    597 
    598     else
    599     {
    600         /* Notifies allowed on this object? */
    601 
    602         if (!AcpiEvIsNotifyObject (Node))
    603         {
    604             Status = AE_TYPE;
    605             goto UnlockAndExit;
    606         }
    607 
    608         /* Check for an existing internal object */
    609 
    610         ObjDesc = AcpiNsGetAttachedObject (Node);
    611         if (!ObjDesc)
    612         {
    613             Status = AE_NOT_EXIST;
    614             goto UnlockAndExit;
    615         }
    616 
    617         /* Object exists - make sure there's an existing handler */
    618 
    619         if (HandlerType & ACPI_SYSTEM_NOTIFY)
    620         {
    621             NotifyObj = ObjDesc->CommonNotify.SystemNotify;
    622             if (!NotifyObj)
    623             {
    624                 Status = AE_NOT_EXIST;
    625                 goto UnlockAndExit;
    626             }
    627 
    628             if (NotifyObj->Notify.Handler != Handler)
    629             {
    630                 Status = AE_BAD_PARAMETER;
    631                 goto UnlockAndExit;
    632             }
    633 
    634             /* Remove the handler */
    635 
    636             ObjDesc->CommonNotify.SystemNotify = NULL;
    637             AcpiUtRemoveReference (NotifyObj);
    638         }
    639 
    640         if (HandlerType & ACPI_DEVICE_NOTIFY)
    641         {
    642             NotifyObj = ObjDesc->CommonNotify.DeviceNotify;
    643             if (!NotifyObj)
    644             {
    645                 Status = AE_NOT_EXIST;
    646                 goto UnlockAndExit;
    647             }
    648 
    649             if (NotifyObj->Notify.Handler != Handler)
    650             {
    651                 Status = AE_BAD_PARAMETER;
    652                 goto UnlockAndExit;
    653             }
    654 
    655             /* Remove the handler */
    656 
    657             ObjDesc->CommonNotify.DeviceNotify = NULL;
    658             AcpiUtRemoveReference (NotifyObj);
    659         }
    660     }
    661 
    662 
    663 UnlockAndExit:
    664     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    665     return_ACPI_STATUS (Status);
    666 }
    667 
    668 ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler)
    669 
    670 
    671 /*******************************************************************************
    672  *
    673  * FUNCTION:    AcpiInstallGpeHandler
    674  *
    675  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
    676  *                                defined GPEs)
    677  *              GpeNumber       - The GPE number within the GPE block
    678  *              Type            - Whether this GPE should be treated as an
    679  *                                edge- or level-triggered interrupt.
    680  *              Address         - Address of the handler
    681  *              Context         - Value passed to the handler on each GPE
    682  *
    683  * RETURN:      Status
    684  *
    685  * DESCRIPTION: Install a handler for a General Purpose Event.
    686  *
    687  ******************************************************************************/
    688 
    689 ACPI_STATUS
    690 AcpiInstallGpeHandler (
    691     ACPI_HANDLE             GpeDevice,
    692     UINT32                  GpeNumber,
    693     UINT32                  Type,
    694     ACPI_EVENT_HANDLER      Address,
    695     void                    *Context)
    696 {
    697     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    698     ACPI_HANDLER_INFO       *Handler;
    699     ACPI_STATUS             Status;
    700     ACPI_CPU_FLAGS          Flags;
    701 
    702 
    703     ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler);
    704 
    705 
    706     /* Parameter validation */
    707 
    708     if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK))
    709     {
    710         return_ACPI_STATUS (AE_BAD_PARAMETER);
    711     }
    712 
    713     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    714     if (ACPI_FAILURE (Status))
    715     {
    716         return_ACPI_STATUS (Status);
    717     }
    718 
    719     /* Ensure that we have a valid GPE number */
    720 
    721     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    722     if (!GpeEventInfo)
    723     {
    724         Status = AE_BAD_PARAMETER;
    725         goto UnlockAndExit;
    726     }
    727 
    728     /* Make sure that there isn't a handler there already */
    729 
    730     if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
    731             ACPI_GPE_DISPATCH_HANDLER)
    732     {
    733         Status = AE_ALREADY_EXISTS;
    734         goto UnlockAndExit;
    735     }
    736 
    737     /* Allocate and init handler object */
    738 
    739     Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_HANDLER_INFO));
    740     if (!Handler)
    741     {
    742         Status = AE_NO_MEMORY;
    743         goto UnlockAndExit;
    744     }
    745 
    746     Handler->Address    = Address;
    747     Handler->Context    = Context;
    748     Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;
    749 
    750     /* Disable the GPE before installing the handler */
    751 
    752     Status = AcpiEvDisableGpe (GpeEventInfo);
    753     if (ACPI_FAILURE (Status))
    754     {
    755         goto UnlockAndExit;
    756     }
    757 
    758     /* Install the handler */
    759 
    760     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    761     GpeEventInfo->Dispatch.Handler = Handler;
    762 
    763     /* Setup up dispatch flags to indicate handler (vs. method) */
    764 
    765     GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
    766     GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER);
    767 
    768     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    769 
    770 
    771 UnlockAndExit:
    772     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    773     return_ACPI_STATUS (Status);
    774 }
    775 
    776 ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler)
    777 
    778 
    779 /*******************************************************************************
    780  *
    781  * FUNCTION:    AcpiRemoveGpeHandler
    782  *
    783  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
    784  *                                defined GPEs)
    785  *              GpeNumber       - The event to remove a handler
    786  *              Address         - Address of the handler
    787  *
    788  * RETURN:      Status
    789  *
    790  * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
    791  *
    792  ******************************************************************************/
    793 
    794 ACPI_STATUS
    795 AcpiRemoveGpeHandler (
    796     ACPI_HANDLE             GpeDevice,
    797     UINT32                  GpeNumber,
    798     ACPI_EVENT_HANDLER      Address)
    799 {
    800     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    801     ACPI_HANDLER_INFO       *Handler;
    802     ACPI_STATUS             Status;
    803     ACPI_CPU_FLAGS          Flags;
    804 
    805 
    806     ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler);
    807 
    808 
    809     /* Parameter validation */
    810 
    811     if (!Address)
    812     {
    813         return_ACPI_STATUS (AE_BAD_PARAMETER);
    814     }
    815 
    816     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    817     if (ACPI_FAILURE (Status))
    818     {
    819         return_ACPI_STATUS (Status);
    820     }
    821 
    822     /* Ensure that we have a valid GPE number */
    823 
    824     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    825     if (!GpeEventInfo)
    826     {
    827         Status = AE_BAD_PARAMETER;
    828         goto UnlockAndExit;
    829     }
    830 
    831     /* Make sure that a handler is indeed installed */
    832 
    833     if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) !=
    834             ACPI_GPE_DISPATCH_HANDLER)
    835     {
    836         Status = AE_NOT_EXIST;
    837         goto UnlockAndExit;
    838     }
    839 
    840     /* Make sure that the installed handler is the same */
    841 
    842     if (GpeEventInfo->Dispatch.Handler->Address != Address)
    843     {
    844         Status = AE_BAD_PARAMETER;
    845         goto UnlockAndExit;
    846     }
    847 
    848     /* Disable the GPE before removing the handler */
    849 
    850     Status = AcpiEvDisableGpe (GpeEventInfo);
    851     if (ACPI_FAILURE (Status))
    852     {
    853         goto UnlockAndExit;
    854     }
    855 
    856     /* Remove the handler */
    857 
    858     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    859     Handler = GpeEventInfo->Dispatch.Handler;
    860 
    861     /* Restore Method node (if any), set dispatch flags */
    862 
    863     GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode;
    864     GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;  /* Clear bits */
    865     if (Handler->MethodNode)
    866     {
    867         GpeEventInfo->Flags |= ACPI_GPE_DISPATCH_METHOD;
    868     }
    869     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    870 
    871     /* Now we can free the handler object */
    872 
    873     ACPI_FREE (Handler);
    874 
    875 
    876 UnlockAndExit:
    877     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    878     return_ACPI_STATUS (Status);
    879 }
    880 
    881 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler)
    882 
    883 
    884 /*******************************************************************************
    885  *
    886  * FUNCTION:    AcpiAcquireGlobalLock
    887  *
    888  * PARAMETERS:  Timeout         - How long the caller is willing to wait
    889  *              Handle          - Where the handle to the lock is returned
    890  *                                (if acquired)
    891  *
    892  * RETURN:      Status
    893  *
    894  * DESCRIPTION: Acquire the ACPI Global Lock
    895  *
    896  * Note: Allows callers with the same thread ID to acquire the global lock
    897  * multiple times. In other words, externally, the behavior of the global lock
    898  * is identical to an AML mutex. On the first acquire, a new handle is
    899  * returned. On any subsequent calls to acquire by the same thread, the same
    900  * handle is returned.
    901  *
    902  ******************************************************************************/
    903 
    904 ACPI_STATUS
    905 AcpiAcquireGlobalLock (
    906     UINT16                  Timeout,
    907     UINT32                  *Handle)
    908 {
    909     ACPI_STATUS             Status;
    910 
    911 
    912     if (!Handle)
    913     {
    914         return (AE_BAD_PARAMETER);
    915     }
    916 
    917     /* Must lock interpreter to prevent race conditions */
    918 
    919     AcpiExEnterInterpreter ();
    920 
    921     Status = AcpiExAcquireMutexObject (Timeout,
    922                 AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ());
    923 
    924     if (ACPI_SUCCESS (Status))
    925     {
    926         /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */
    927 
    928         *Handle = AcpiGbl_GlobalLockHandle;
    929     }
    930 
    931     AcpiExExitInterpreter ();
    932     return (Status);
    933 }
    934 
    935 ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock)
    936 
    937 
    938 /*******************************************************************************
    939  *
    940  * FUNCTION:    AcpiReleaseGlobalLock
    941  *
    942  * PARAMETERS:  Handle      - Returned from AcpiAcquireGlobalLock
    943  *
    944  * RETURN:      Status
    945  *
    946  * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
    947  *
    948  ******************************************************************************/
    949 
    950 ACPI_STATUS
    951 AcpiReleaseGlobalLock (
    952     UINT32                  Handle)
    953 {
    954     ACPI_STATUS             Status;
    955 
    956 
    957     if (!Handle || (Handle != AcpiGbl_GlobalLockHandle))
    958     {
    959         return (AE_NOT_ACQUIRED);
    960     }
    961 
    962     Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex);
    963     return (Status);
    964 }
    965 
    966 ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock)
    967 
    968