Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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.