Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/drivers/acpica/evxface.c need to be fixed.

0001 /******************************************************************************
0002  *
0003  * Module Name: evxface - External interfaces for ACPI events
0004  *
0005  *****************************************************************************/
0006 
0007 /******************************************************************************
0008  *
0009  * 1. Copyright Notice
0010  *
0011  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
0012  * All rights reserved.
0013  *
0014  * 2. License
0015  *
0016  * 2.1. This is your license from Intel Corp. under its intellectual property
0017  * rights.  You may have additional license terms from the party that provided
0018  * you this software, covering your right to use that party's intellectual
0019  * property rights.
0020  *
0021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0022  * copy of the source code appearing in this file ("Covered Code") an
0023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0024  * base code distributed originally by Intel ("Original Intel Code") to copy,
0025  * make derivatives, distribute, use and display any portion of the Covered
0026  * Code in any form, with the right to sublicense such rights; and
0027  *
0028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0029  * license (with the right to sublicense), under only those claims of Intel
0030  * patents that are infringed by the Original Intel Code, to make, use, sell,
0031  * offer to sell, and import the Covered Code and derivative works thereof
0032  * solely to the minimum extent necessary to exercise the above copyright
0033  * license, and in no event shall the patent license extend to any additions
0034  * to or modifications of the Original Intel Code.  No other license or right
0035  * is granted directly or by implication, estoppel or otherwise;
0036  *
0037  * The above copyright and patent license is granted only if the following
0038  * conditions are met:
0039  *
0040  * 3. Conditions
0041  *
0042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0043  * Redistribution of source code of any substantial portion of the Covered
0044  * Code or modification with rights to further distribute source must include
0045  * the above Copyright Notice, the above License, this list of Conditions,
0046  * and the following Disclaimer and Export Compliance provision.  In addition,
0047  * Licensee must cause all Covered Code to which Licensee contributes to
0048  * contain a file documenting the changes Licensee made to create that Covered
0049  * Code and the date of any change.  Licensee must include in that file the
0050  * documentation of any changes made by any predecessor Licensee.  Licensee
0051  * must include a prominent statement that the modification is derived,
0052  * directly or indirectly, from Original Intel Code.
0053  *
0054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0055  * Redistribution of source code of any substantial portion of the Covered
0056  * Code or modification without rights to further distribute source must
0057  * include the following Disclaimer and Export Compliance provision in the
0058  * documentation and/or other materials provided with distribution.  In
0059  * addition, Licensee may not authorize further sublicense of source of any
0060  * portion of the Covered Code, and must include terms to the effect that the
0061  * license from Licensee to its licensee is limited to the intellectual
0062  * property embodied in the software Licensee provides to its licensee, and
0063  * not to intellectual property embodied in modifications its licensee may
0064  * make.
0065  *
0066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0067  * substantial portion of the Covered Code or modification must reproduce the
0068  * above Copyright Notice, and the following Disclaimer and Export Compliance
0069  * provision in the documentation and/or other materials provided with the
0070  * distribution.
0071  *
0072  * 3.4. Intel retains all right, title, and interest in and to the Original
0073  * Intel Code.
0074  *
0075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0076  * Intel shall be used in advertising or otherwise to promote the sale, use or
0077  * other dealings in products derived from or relating to the Covered Code
0078  * without prior written authorization from Intel.
0079  *
0080  * 4. Disclaimer and Export Compliance
0081  *
0082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0083  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
0085  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
0086  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
0087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0088  * PARTICULAR PURPOSE.
0089  *
0090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
0096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0097  * LIMITED REMEDY.
0098  *
0099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0100  * software or system incorporating such software without first obtaining any
0101  * required license or other approval from the U. S. Department of Commerce or
0102  * any other agency or department of the United States Government.  In the
0103  * event Licensee exports any such software from the United States or
0104  * re-exports any such software from a foreign destination, Licensee shall
0105  * ensure that the distribution and export/re-export of the software is in
0106  * compliance with all laws, regulations, orders, or other restrictions of the
0107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0108  * any of its subsidiaries will export/re-export any technical data, process,
0109  * software, or service, directly or indirectly, to any country for which the
0110  * United States government or any agency thereof requires an export license,
0111  * other governmental approval, or letter of assurance, without first obtaining
0112  * such license, approval or letter.
0113  *
0114  *****************************************************************************/
0115 
0116 
0117 #define __EVXFACE_C__
0118 
0119 #include "acpi.h"
0120 #include "accommon.h"
0121 #include "acnamesp.h"
0122 #include "acevents.h"
0123 #include "acinterp.h"
0124 
0125 #define _COMPONENT          ACPI_EVENTS
0126         ACPI_MODULE_NAME    ("evxface")
0127 
0128 
0129 /*******************************************************************************
0130  *
0131  * FUNCTION:    AcpiInstallExceptionHandler
0132  *
0133  * PARAMETERS:  Handler         - Pointer to the handler function for the
0134  *                                event
0135  *
0136  * RETURN:      Status
0137  *
0138  * DESCRIPTION: Saves the pointer to the handler function
0139  *
0140  ******************************************************************************/
0141 
0142 ACPI_STATUS
0143 AcpiInstallExceptionHandler (
0144     ACPI_EXCEPTION_HANDLER  Handler)
0145 {
0146     ACPI_STATUS             Status;
0147 
0148 
0149     ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler);
0150 
0151 
0152     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0153     if (ACPI_FAILURE (Status))
0154     {
0155         return_ACPI_STATUS (Status);
0156     }
0157 
0158     /* Don't allow two handlers. */
0159 
0160     if (AcpiGbl_ExceptionHandler)
0161     {
0162         Status = AE_ALREADY_EXISTS;
0163         goto Cleanup;
0164     }
0165 
0166     /* Install the handler */
0167 
0168     AcpiGbl_ExceptionHandler = Handler;
0169 
0170 Cleanup:
0171     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
0172     return_ACPI_STATUS (Status);
0173 }
0174 
0175 ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler)
0176 
0177 
0178 /*******************************************************************************
0179  *
0180  * FUNCTION:    AcpiInstallFixedEventHandler
0181  *
0182  * PARAMETERS:  Event           - Event type to enable.
0183  *              Handler         - Pointer to the handler function for the
0184  *                                event
0185  *              Context         - Value passed to the handler on each GPE
0186  *
0187  * RETURN:      Status
0188  *
0189  * DESCRIPTION: Saves the pointer to the handler function and then enables the
0190  *              event.
0191  *
0192  ******************************************************************************/
0193 
0194 ACPI_STATUS
0195 AcpiInstallFixedEventHandler (
0196     UINT32                  Event,
0197     ACPI_EVENT_HANDLER      Handler,
0198     void                    *Context)
0199 {
0200     ACPI_STATUS             Status;
0201 
0202 
0203     ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler);
0204 
0205 
0206     /* Parameter validation */
0207 
0208     if (Event > ACPI_EVENT_MAX)
0209     {
0210         return_ACPI_STATUS (AE_BAD_PARAMETER);
0211     }
0212 
0213     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0214     if (ACPI_FAILURE (Status))
0215     {
0216         return_ACPI_STATUS (Status);
0217     }
0218 
0219     /* Don't allow two handlers. */
0220 
0221     if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler)
0222     {
0223         Status = AE_ALREADY_EXISTS;
0224         goto Cleanup;
0225     }
0226 
0227     /* Install the handler before enabling the event */
0228 
0229     AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
0230     AcpiGbl_FixedEventHandlers[Event].Context = Context;
0231 
0232     Status = AcpiEnableEvent (Event, 0);
0233     if (ACPI_FAILURE (Status))
0234     {
0235         ACPI_WARNING ((AE_INFO, "Could not enable fixed event %X", Event));
0236 
0237         /* Remove the handler */
0238 
0239         AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
0240         AcpiGbl_FixedEventHandlers[Event].Context = NULL;
0241     }
0242     else
0243     {
0244         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
0245             "Enabled fixed event %X, Handler=%p\n", Event, Handler));
0246     }
0247 
0248 
0249 Cleanup:
0250     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
0251     return_ACPI_STATUS (Status);
0252 }
0253 
0254 ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler)
0255 
0256 
0257 /*******************************************************************************
0258  *
0259  * FUNCTION:    AcpiRemoveFixedEventHandler
0260  *
0261  * PARAMETERS:  Event           - Event type to disable.
0262  *              Handler         - Address of the handler
0263  *
0264  * RETURN:      Status
0265  *
0266  * DESCRIPTION: Disables the event and unregisters the event handler.
0267  *
0268  ******************************************************************************/
0269 
0270 ACPI_STATUS
0271 AcpiRemoveFixedEventHandler (
0272     UINT32                  Event,
0273     ACPI_EVENT_HANDLER      Handler)
0274 {
0275     ACPI_STATUS             Status = AE_OK;
0276 
0277 
0278     ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler);
0279 
0280 
0281     /* Parameter validation */
0282 
0283     if (Event > ACPI_EVENT_MAX)
0284     {
0285         return_ACPI_STATUS (AE_BAD_PARAMETER);
0286     }
0287 
0288     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0289     if (ACPI_FAILURE (Status))
0290     {
0291         return_ACPI_STATUS (Status);
0292     }
0293 
0294     /* Disable the event before removing the handler */
0295 
0296     Status = AcpiDisableEvent (Event, 0);
0297 
0298     /* Always Remove the handler */
0299 
0300     AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
0301     AcpiGbl_FixedEventHandlers[Event].Context = NULL;
0302 
0303     if (ACPI_FAILURE (Status))
0304     {
0305         ACPI_WARNING ((AE_INFO,
0306             "Could not write to fixed event enable register %X", Event));
0307     }
0308     else
0309     {
0310         ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X\n", Event));
0311     }
0312 
0313     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
0314     return_ACPI_STATUS (Status);
0315 }
0316 
0317 ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler)
0318 
0319 
0320 /*******************************************************************************
0321  *
0322  * FUNCTION:    AcpiInstallNotifyHandler
0323  *
0324  * PARAMETERS:  Device          - The device for which notifies will be handled
0325  *              HandlerType     - The type of handler:
0326  *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
0327  *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
0328  *                                  ACPI_ALL_NOTIFY:  both system and device
0329  *              Handler         - Address of the handler
0330  *              Context         - Value passed to the handler on each GPE
0331  *
0332  * RETURN:      Status
0333  *
0334  * DESCRIPTION: Install a handler for notifies on an ACPI device
0335  *
0336  ******************************************************************************/
0337 
0338 ACPI_STATUS
0339 AcpiInstallNotifyHandler (
0340     ACPI_HANDLE             Device,
0341     UINT32                  HandlerType,
0342     ACPI_NOTIFY_HANDLER     Handler,
0343     void                    *Context)
0344 {
0345     ACPI_OPERAND_OBJECT     *ObjDesc;
0346     ACPI_OPERAND_OBJECT     *NotifyObj;
0347     ACPI_NAMESPACE_NODE     *Node;
0348     ACPI_STATUS             Status;
0349 
0350 
0351     ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler);
0352 
0353 
0354     /* Parameter validation */
0355 
0356     if ((!Device)  ||
0357         (!Handler) ||
0358         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
0359     {
0360         return_ACPI_STATUS (AE_BAD_PARAMETER);
0361     }
0362 
0363     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0364     if (ACPI_FAILURE (Status))
0365     {
0366         return_ACPI_STATUS (Status);
0367     }
0368 
0369     /* Convert and validate the device handle */
0370 
0371     Node = AcpiNsMapHandleToNode (Device);
0372     if (!Node)
0373     {
0374         Status = AE_BAD_PARAMETER;
0375         goto UnlockAndExit;
0376     }
0377 
0378     /*
0379      * Root Object:
0380      * Registering a notify handler on the root object indicates that the
0381      * caller wishes to receive notifications for all objects. Note that
0382      * only one <external> global handler can be regsitered (per notify type).
0383      */
0384     if (Device == ACPI_ROOT_OBJECT)
0385     {
0386         /* Make sure the handler is not already installed */
0387 
0388         if (((HandlerType & ACPI_SYSTEM_NOTIFY) &&
0389                 AcpiGbl_SystemNotify.Handler)       ||
0390             ((HandlerType & ACPI_DEVICE_NOTIFY) &&
0391                 AcpiGbl_DeviceNotify.Handler))
0392         {
0393             Status = AE_ALREADY_EXISTS;
0394             goto UnlockAndExit;
0395         }
0396 
0397         if (HandlerType & ACPI_SYSTEM_NOTIFY)
0398         {
0399             AcpiGbl_SystemNotify.Node    = Node;
0400             AcpiGbl_SystemNotify.Handler = Handler;
0401             AcpiGbl_SystemNotify.Context = Context;
0402         }
0403 
0404         if (HandlerType & ACPI_DEVICE_NOTIFY)
0405         {
0406             AcpiGbl_DeviceNotify.Node    = Node;
0407             AcpiGbl_DeviceNotify.Handler = Handler;
0408             AcpiGbl_DeviceNotify.Context = Context;
0409         }
0410 
0411         /* Global notify handler installed */
0412     }
0413 
0414     /*
0415      * All Other Objects:
0416      * Caller will only receive notifications specific to the target object.
0417      * Note that only certain object types can receive notifications.
0418      */
0419     else
0420     {
0421         /* Notifies allowed on this object? */
0422 
0423         if (!AcpiEvIsNotifyObject (Node))
0424         {
0425             Status = AE_TYPE;
0426             goto UnlockAndExit;
0427         }
0428 
0429         /* Check for an existing internal object */
0430 
0431         ObjDesc = AcpiNsGetAttachedObject (Node);
0432         if (ObjDesc)
0433         {
0434             /* Object exists - make sure there's no handler */
0435 
0436             if (((HandlerType & ACPI_SYSTEM_NOTIFY) &&
0437                     ObjDesc->CommonNotify.SystemNotify)   ||
0438                 ((HandlerType & ACPI_DEVICE_NOTIFY) &&
0439                     ObjDesc->CommonNotify.DeviceNotify))
0440             {
0441                 Status = AE_ALREADY_EXISTS;
0442                 goto UnlockAndExit;
0443             }
0444         }
0445         else
0446         {
0447             /* Create a new object */
0448 
0449             ObjDesc = AcpiUtCreateInternalObject (Node->Type);
0450             if (!ObjDesc)
0451             {
0452                 Status = AE_NO_MEMORY;
0453                 goto UnlockAndExit;
0454             }
0455 
0456             /* Attach new object to the Node */
0457 
0458             Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
0459 
0460             /* Remove local reference to the object */
0461 
0462             AcpiUtRemoveReference (ObjDesc);
0463             if (ACPI_FAILURE (Status))
0464             {
0465                 goto UnlockAndExit;
0466             }
0467         }
0468 
0469         /* Install the handler */
0470 
0471         NotifyObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
0472         if (!NotifyObj)
0473         {
0474             Status = AE_NO_MEMORY;
0475             goto UnlockAndExit;
0476         }
0477 
0478         NotifyObj->Notify.Node    = Node;
0479         NotifyObj->Notify.Handler = Handler;
0480         NotifyObj->Notify.Context = Context;
0481 
0482         if (HandlerType & ACPI_SYSTEM_NOTIFY)
0483         {
0484             ObjDesc->CommonNotify.SystemNotify = NotifyObj;
0485         }
0486 
0487         if (HandlerType & ACPI_DEVICE_NOTIFY)
0488         {
0489             ObjDesc->CommonNotify.DeviceNotify = NotifyObj;
0490         }
0491 
0492         if (HandlerType == ACPI_ALL_NOTIFY)
0493         {
0494             /* Extra ref if installed in both */
0495 
0496             AcpiUtAddReference (NotifyObj);
0497         }
0498     }
0499 
0500 
0501 UnlockAndExit:
0502     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0503     return_ACPI_STATUS (Status);
0504 }
0505 
0506 ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler)
0507 
0508 
0509 /*******************************************************************************
0510  *
0511  * FUNCTION:    AcpiRemoveNotifyHandler
0512  *
0513  * PARAMETERS:  Device          - The device for which notifies will be handled
0514  *              HandlerType     - The type of handler:
0515  *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
0516  *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
0517  *                                  ACPI_ALL_NOTIFY:  both system and device
0518  *              Handler         - Address of the handler
0519  *
0520  * RETURN:      Status
0521  *
0522  * DESCRIPTION: Remove a handler for notifies on an ACPI device
0523  *
0524  ******************************************************************************/
0525 
0526 ACPI_STATUS
0527 AcpiRemoveNotifyHandler (
0528     ACPI_HANDLE             Device,
0529     UINT32                  HandlerType,
0530     ACPI_NOTIFY_HANDLER     Handler)
0531 {
0532     ACPI_OPERAND_OBJECT     *NotifyObj;
0533     ACPI_OPERAND_OBJECT     *ObjDesc;
0534     ACPI_NAMESPACE_NODE     *Node;
0535     ACPI_STATUS             Status;
0536 
0537 
0538     ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler);
0539 
0540 
0541     /* Parameter validation */
0542 
0543     if ((!Device)  ||
0544         (!Handler) ||
0545         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
0546     {
0547         return_ACPI_STATUS (AE_BAD_PARAMETER);
0548     }
0549 
0550     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0551     if (ACPI_FAILURE (Status))
0552     {
0553         return_ACPI_STATUS (Status);
0554     }
0555 
0556     /* Convert and validate the device handle */
0557 
0558     Node = AcpiNsMapHandleToNode (Device);
0559     if (!Node)
0560     {
0561         Status = AE_BAD_PARAMETER;
0562         goto UnlockAndExit;
0563     }
0564 
0565     /* Root Object */
0566 
0567     if (Device == ACPI_ROOT_OBJECT)
0568     {
0569         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
0570             "Removing notify handler for namespace root object\n"));
0571 
0572         if (((HandlerType & ACPI_SYSTEM_NOTIFY) &&
0573               !AcpiGbl_SystemNotify.Handler)        ||
0574             ((HandlerType & ACPI_DEVICE_NOTIFY) &&
0575               !AcpiGbl_DeviceNotify.Handler))
0576         {
0577             Status = AE_NOT_EXIST;
0578             goto UnlockAndExit;
0579         }
0580 
0581         if (HandlerType & ACPI_SYSTEM_NOTIFY)
0582         {
0583             AcpiGbl_SystemNotify.Node    = NULL;
0584             AcpiGbl_SystemNotify.Handler = NULL;
0585             AcpiGbl_SystemNotify.Context = NULL;
0586         }
0587 
0588         if (HandlerType & ACPI_DEVICE_NOTIFY)
0589         {
0590             AcpiGbl_DeviceNotify.Node    = NULL;
0591             AcpiGbl_DeviceNotify.Handler = NULL;
0592             AcpiGbl_DeviceNotify.Context = NULL;
0593         }
0594     }
0595 
0596     /* All Other Objects */
0597 
0598     else
0599     {
0600         /* Notifies allowed on this object? */
0601 
0602         if (!AcpiEvIsNotifyObject (Node))
0603         {
0604             Status = AE_TYPE;
0605             goto UnlockAndExit;
0606         }
0607 
0608         /* Check for an existing internal object */
0609 
0610         ObjDesc = AcpiNsGetAttachedObject (Node);
0611         if (!ObjDesc)
0612         {
0613             Status = AE_NOT_EXIST;
0614             goto UnlockAndExit;
0615         }
0616 
0617         /* Object exists - make sure there's an existing handler */
0618 
0619         if (HandlerType & ACPI_SYSTEM_NOTIFY)
0620         {
0621             NotifyObj = ObjDesc->CommonNotify.SystemNotify;
0622             if (!NotifyObj)
0623             {
0624                 Status = AE_NOT_EXIST;
0625                 goto UnlockAndExit;
0626             }
0627 
0628             if (NotifyObj->Notify.Handler != Handler)
0629             {
0630                 Status = AE_BAD_PARAMETER;
0631                 goto UnlockAndExit;
0632             }
0633 
0634             /* Remove the handler */
0635 
0636             ObjDesc->CommonNotify.SystemNotify = NULL;
0637             AcpiUtRemoveReference (NotifyObj);
0638         }
0639 
0640         if (HandlerType & ACPI_DEVICE_NOTIFY)
0641         {
0642             NotifyObj = ObjDesc->CommonNotify.DeviceNotify;
0643             if (!NotifyObj)
0644             {
0645                 Status = AE_NOT_EXIST;
0646                 goto UnlockAndExit;
0647             }
0648 
0649             if (NotifyObj->Notify.Handler != Handler)
0650             {
0651                 Status = AE_BAD_PARAMETER;
0652                 goto UnlockAndExit;
0653             }
0654 
0655             /* Remove the handler */
0656 
0657             ObjDesc->CommonNotify.DeviceNotify = NULL;
0658             AcpiUtRemoveReference (NotifyObj);
0659         }
0660     }
0661 
0662 
0663 UnlockAndExit:
0664     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0665     return_ACPI_STATUS (Status);
0666 }
0667 
0668 ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler)
0669 
0670 
0671 /*******************************************************************************
0672  *
0673  * FUNCTION:    AcpiInstallGpeHandler
0674  *
0675  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
0676  *                                defined GPEs)
0677  *              GpeNumber       - The GPE number within the GPE block
0678  *              Type            - Whether this GPE should be treated as an
0679  *                                edge- or level-triggered interrupt.
0680  *              Address         - Address of the handler
0681  *              Context         - Value passed to the handler on each GPE
0682  *
0683  * RETURN:      Status
0684  *
0685  * DESCRIPTION: Install a handler for a General Purpose Event.
0686  *
0687  ******************************************************************************/
0688 
0689 ACPI_STATUS
0690 AcpiInstallGpeHandler (
0691     ACPI_HANDLE             GpeDevice,
0692     UINT32                  GpeNumber,
0693     UINT32                  Type,
0694     ACPI_EVENT_HANDLER      Address,
0695     void                    *Context)
0696 {
0697     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
0698     ACPI_HANDLER_INFO       *Handler;
0699     ACPI_STATUS             Status;
0700     ACPI_CPU_FLAGS          Flags;
0701 
0702 
0703     ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler);
0704 
0705 
0706     /* Parameter validation */
0707 
0708     if ((!Address) || (Type > ACPI_GPE_XRUPT_TYPE_MASK))
0709     {
0710         return_ACPI_STATUS (AE_BAD_PARAMETER);
0711     }
0712 
0713     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0714     if (ACPI_FAILURE (Status))
0715     {
0716         return_ACPI_STATUS (Status);
0717     }
0718 
0719     /* Ensure that we have a valid GPE number */
0720 
0721     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
0722     if (!GpeEventInfo)
0723     {
0724         Status = AE_BAD_PARAMETER;
0725         goto UnlockAndExit;
0726     }
0727 
0728     /* Make sure that there isn't a handler there already */
0729 
0730     if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
0731             ACPI_GPE_DISPATCH_HANDLER)
0732     {
0733         Status = AE_ALREADY_EXISTS;
0734         goto UnlockAndExit;
0735     }
0736 
0737     /* Allocate and init handler object */
0738 
0739     Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_HANDLER_INFO));
0740     if (!Handler)
0741     {
0742         Status = AE_NO_MEMORY;
0743         goto UnlockAndExit;
0744     }
0745 
0746     Handler->Address    = Address;
0747     Handler->Context    = Context;
0748     Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;
0749 
0750     /* Disable the GPE before installing the handler */
0751 
0752     Status = AcpiEvDisableGpe (GpeEventInfo);
0753     if (ACPI_FAILURE (Status))
0754     {
0755         goto UnlockAndExit;
0756     }
0757 
0758     /* Install the handler */
0759 
0760     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0761     GpeEventInfo->Dispatch.Handler = Handler;
0762 
0763     /* Setup up dispatch flags to indicate handler (vs. method) */
0764 
0765     GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
0766     GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER);
0767 
0768     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0769 
0770 
0771 UnlockAndExit:
0772     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
0773     return_ACPI_STATUS (Status);
0774 }
0775 
0776 ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler)
0777 
0778 
0779 /*******************************************************************************
0780  *
0781  * FUNCTION:    AcpiRemoveGpeHandler
0782  *
0783  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
0784  *                                defined GPEs)
0785  *              GpeNumber       - The event to remove a handler
0786  *              Address         - Address of the handler
0787  *
0788  * RETURN:      Status
0789  *
0790  * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
0791  *
0792  ******************************************************************************/
0793 
0794 ACPI_STATUS
0795 AcpiRemoveGpeHandler (
0796     ACPI_HANDLE             GpeDevice,
0797     UINT32                  GpeNumber,
0798     ACPI_EVENT_HANDLER      Address)
0799 {
0800     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
0801     ACPI_HANDLER_INFO       *Handler;
0802     ACPI_STATUS             Status;
0803     ACPI_CPU_FLAGS          Flags;
0804 
0805 
0806     ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler);
0807 
0808 
0809     /* Parameter validation */
0810 
0811     if (!Address)
0812     {
0813         return_ACPI_STATUS (AE_BAD_PARAMETER);
0814     }
0815 
0816     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0817     if (ACPI_FAILURE (Status))
0818     {
0819         return_ACPI_STATUS (Status);
0820     }
0821 
0822     /* Ensure that we have a valid GPE number */
0823 
0824     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
0825     if (!GpeEventInfo)
0826     {
0827         Status = AE_BAD_PARAMETER;
0828         goto UnlockAndExit;
0829     }
0830 
0831     /* Make sure that a handler is indeed installed */
0832 
0833     if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) !=
0834             ACPI_GPE_DISPATCH_HANDLER)
0835     {
0836         Status = AE_NOT_EXIST;
0837         goto UnlockAndExit;
0838     }
0839 
0840     /* Make sure that the installed handler is the same */
0841 
0842     if (GpeEventInfo->Dispatch.Handler->Address != Address)
0843     {
0844         Status = AE_BAD_PARAMETER;
0845         goto UnlockAndExit;
0846     }
0847 
0848     /* Disable the GPE before removing the handler */
0849 
0850     Status = AcpiEvDisableGpe (GpeEventInfo);
0851     if (ACPI_FAILURE (Status))
0852     {
0853         goto UnlockAndExit;
0854     }
0855 
0856     /* Remove the handler */
0857 
0858     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0859     Handler = GpeEventInfo->Dispatch.Handler;
0860 
0861     /* Restore Method node (if any), set dispatch flags */
0862 
0863     GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode;
0864     GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;  /* Clear bits */
0865     if (Handler->MethodNode)
0866     {
0867         GpeEventInfo->Flags |= ACPI_GPE_DISPATCH_METHOD;
0868     }
0869     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0870 
0871     /* Now we can free the handler object */
0872 
0873     ACPI_FREE (Handler);
0874 
0875 
0876 UnlockAndExit:
0877     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
0878     return_ACPI_STATUS (Status);
0879 }
0880 
0881 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler)
0882 
0883 
0884 /*******************************************************************************
0885  *
0886  * FUNCTION:    AcpiAcquireGlobalLock
0887  *
0888  * PARAMETERS:  Timeout         - How long the caller is willing to wait
0889  *              Handle          - Where the handle to the lock is returned
0890  *                                (if acquired)
0891  *
0892  * RETURN:      Status
0893  *
0894  * DESCRIPTION: Acquire the ACPI Global Lock
0895  *
0896  * Note: Allows callers with the same thread ID to acquire the global lock
0897  * multiple times. In other words, externally, the behavior of the global lock
0898  * is identical to an AML mutex. On the first acquire, a new handle is
0899  * returned. On any subsequent calls to acquire by the same thread, the same
0900  * handle is returned.
0901  *
0902  ******************************************************************************/
0903 
0904 ACPI_STATUS
0905 AcpiAcquireGlobalLock (
0906     UINT16                  Timeout,
0907     UINT32                  *Handle)
0908 {
0909     ACPI_STATUS             Status;
0910 
0911 
0912     if (!Handle)
0913     {
0914         return (AE_BAD_PARAMETER);
0915     }
0916 
0917     /* Must lock interpreter to prevent race conditions */
0918 
0919     AcpiExEnterInterpreter ();
0920 
0921     Status = AcpiExAcquireMutexObject (Timeout,
0922                 AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ());
0923 
0924     if (ACPI_SUCCESS (Status))
0925     {
0926         /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */
0927 
0928         *Handle = AcpiGbl_GlobalLockHandle;
0929     }
0930 
0931     AcpiExExitInterpreter ();
0932     return (Status);
0933 }
0934 
0935 ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock)
0936 
0937 
0938 /*******************************************************************************
0939  *
0940  * FUNCTION:    AcpiReleaseGlobalLock
0941  *
0942  * PARAMETERS:  Handle      - Returned from AcpiAcquireGlobalLock
0943  *
0944  * RETURN:      Status
0945  *
0946  * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
0947  *
0948  ******************************************************************************/
0949 
0950 ACPI_STATUS
0951 AcpiReleaseGlobalLock (
0952     UINT32                  Handle)
0953 {
0954     ACPI_STATUS             Status;
0955 
0956 
0957     if (!Handle || (Handle != AcpiGbl_GlobalLockHandle))
0958     {
0959         return (AE_NOT_ACQUIRED);
0960     }
0961 
0962     Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex);
0963     return (Status);
0964 }
0965 
0966 ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock)
0967