Subversion Repositories Kolibri OS

Rev

Rev 1498 | 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 - 2011, 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:    AcpiInstallGlobalEventHandler
  181.  *
  182.  * PARAMETERS:  Handler         - Pointer to the global event handler function
  183.  *              Context         - Value passed to the handler on each event
  184.  *
  185.  * RETURN:      Status
  186.  *
  187.  * DESCRIPTION: Saves the pointer to the handler function. The global handler
  188.  *              is invoked upon each incoming GPE and Fixed Event. It is
  189.  *              invoked at interrupt level at the time of the event dispatch.
  190.  *              Can be used to update event counters, etc.
  191.  *
  192.  ******************************************************************************/
  193.  
  194. ACPI_STATUS
  195. AcpiInstallGlobalEventHandler (
  196.     ACPI_GBL_EVENT_HANDLER  Handler,
  197.     void                    *Context)
  198. {
  199.     ACPI_STATUS             Status;
  200.  
  201.  
  202.     ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler);
  203.  
  204.  
  205.     /* Parameter validation */
  206.  
  207.     if (!Handler)
  208.     {
  209.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  210.     }
  211.  
  212.     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
  213.     if (ACPI_FAILURE (Status))
  214.     {
  215.         return_ACPI_STATUS (Status);
  216.     }
  217.  
  218.     /* Don't allow two handlers. */
  219.  
  220.     if (AcpiGbl_GlobalEventHandler)
  221.     {
  222.         Status = AE_ALREADY_EXISTS;
  223.         goto Cleanup;
  224.     }
  225.  
  226.     AcpiGbl_GlobalEventHandler = Handler;
  227.     AcpiGbl_GlobalEventHandlerContext = Context;
  228.  
  229.  
  230. Cleanup:
  231.     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
  232.     return_ACPI_STATUS (Status);
  233. }
  234.  
  235. ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler)
  236.  
  237.  
  238. /*******************************************************************************
  239.  *
  240.  * FUNCTION:    AcpiInstallFixedEventHandler
  241.  *
  242.  * PARAMETERS:  Event           - Event type to enable.
  243.  *              Handler         - Pointer to the handler function for the
  244.  *                                event
  245.  *              Context         - Value passed to the handler on each GPE
  246.  *
  247.  * RETURN:      Status
  248.  *
  249.  * DESCRIPTION: Saves the pointer to the handler function and then enables the
  250.  *              event.
  251.  *
  252.  ******************************************************************************/
  253.  
  254. ACPI_STATUS
  255. AcpiInstallFixedEventHandler (
  256.     UINT32                  Event,
  257.     ACPI_EVENT_HANDLER      Handler,
  258.     void                    *Context)
  259. {
  260.     ACPI_STATUS             Status;
  261.  
  262.  
  263.     ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler);
  264.  
  265.  
  266.     /* Parameter validation */
  267.  
  268.     if (Event > ACPI_EVENT_MAX)
  269.     {
  270.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  271.     }
  272.  
  273.     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
  274.     if (ACPI_FAILURE (Status))
  275.     {
  276.         return_ACPI_STATUS (Status);
  277.     }
  278.  
  279.     /* Don't allow two handlers. */
  280.  
  281.     if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler)
  282.     {
  283.         Status = AE_ALREADY_EXISTS;
  284.         goto Cleanup;
  285.     }
  286.  
  287.     /* Install the handler before enabling the event */
  288.  
  289.     AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
  290.     AcpiGbl_FixedEventHandlers[Event].Context = Context;
  291.  
  292.     Status = AcpiEnableEvent (Event, 0);
  293.     if (ACPI_FAILURE (Status))
  294.     {
  295.         ACPI_WARNING ((AE_INFO, "Could not enable fixed event 0x%X", Event));
  296.  
  297.         /* Remove the handler */
  298.  
  299.         AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
  300.         AcpiGbl_FixedEventHandlers[Event].Context = NULL;
  301.     }
  302.     else
  303.     {
  304.         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  305.             "Enabled fixed event %X, Handler=%p\n", Event, Handler));
  306.     }
  307.  
  308.  
  309. Cleanup:
  310.     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
  311.     return_ACPI_STATUS (Status);
  312. }
  313.  
  314. ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler)
  315.  
  316.  
  317. /*******************************************************************************
  318.  *
  319.  * FUNCTION:    AcpiRemoveFixedEventHandler
  320.  *
  321.  * PARAMETERS:  Event           - Event type to disable.
  322.  *              Handler         - Address of the handler
  323.  *
  324.  * RETURN:      Status
  325.  *
  326.  * DESCRIPTION: Disables the event and unregisters the event handler.
  327.  *
  328.  ******************************************************************************/
  329.  
  330. ACPI_STATUS
  331. AcpiRemoveFixedEventHandler (
  332.     UINT32                  Event,
  333.     ACPI_EVENT_HANDLER      Handler)
  334. {
  335.     ACPI_STATUS             Status = AE_OK;
  336.  
  337.  
  338.     ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler);
  339.  
  340.  
  341.     /* Parameter validation */
  342.  
  343.     if (Event > ACPI_EVENT_MAX)
  344.     {
  345.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  346.     }
  347.  
  348.     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
  349.     if (ACPI_FAILURE (Status))
  350.     {
  351.         return_ACPI_STATUS (Status);
  352.     }
  353.  
  354.     /* Disable the event before removing the handler */
  355.  
  356.     Status = AcpiDisableEvent (Event, 0);
  357.  
  358.     /* Always Remove the handler */
  359.  
  360.     AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
  361.     AcpiGbl_FixedEventHandlers[Event].Context = NULL;
  362.  
  363.     if (ACPI_FAILURE (Status))
  364.     {
  365.         ACPI_WARNING ((AE_INFO,
  366.             "Could not write to fixed event enable register 0x%X", Event));
  367.     }
  368.     else
  369.     {
  370.         ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X\n", Event));
  371.     }
  372.  
  373.     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
  374.     return_ACPI_STATUS (Status);
  375. }
  376.  
  377. ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler)
  378.  
  379.  
  380. /*******************************************************************************
  381.  *
  382.  * FUNCTION:    AcpiInstallNotifyHandler
  383.  *
  384.  * PARAMETERS:  Device          - The device for which notifies will be handled
  385.  *              HandlerType     - The type of handler:
  386.  *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
  387.  *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
  388.  *                                  ACPI_ALL_NOTIFY:  both system and device
  389.  *              Handler         - Address of the handler
  390.  *              Context         - Value passed to the handler on each GPE
  391.  *
  392.  * RETURN:      Status
  393.  *
  394.  * DESCRIPTION: Install a handler for notifies on an ACPI device
  395.  *
  396.  ******************************************************************************/
  397.  
  398. ACPI_STATUS
  399. AcpiInstallNotifyHandler (
  400.     ACPI_HANDLE             Device,
  401.     UINT32                  HandlerType,
  402.     ACPI_NOTIFY_HANDLER     Handler,
  403.     void                    *Context)
  404. {
  405.     ACPI_OPERAND_OBJECT     *ObjDesc;
  406.     ACPI_OPERAND_OBJECT     *NotifyObj;
  407.     ACPI_NAMESPACE_NODE     *Node;
  408.     ACPI_STATUS             Status;
  409.  
  410.  
  411.     ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler);
  412.  
  413.  
  414.     /* Parameter validation */
  415.  
  416.     if ((!Device)  ||
  417.         (!Handler) ||
  418.         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
  419.     {
  420.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  421.     }
  422.  
  423.     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  424.     if (ACPI_FAILURE (Status))
  425.     {
  426.         return_ACPI_STATUS (Status);
  427.     }
  428.  
  429.     /* Convert and validate the device handle */
  430.  
  431.     Node = AcpiNsValidateHandle (Device);
  432.     if (!Node)
  433.     {
  434.         Status = AE_BAD_PARAMETER;
  435.         goto UnlockAndExit;
  436.     }
  437.  
  438.     /*
  439.      * Root Object:
  440.      * Registering a notify handler on the root object indicates that the
  441.      * caller wishes to receive notifications for all objects. Note that
  442.      * only one <external> global handler can be regsitered (per notify type).
  443.      */
  444.     if (Device == ACPI_ROOT_OBJECT)
  445.     {
  446.         /* Make sure the handler is not already installed */
  447.  
  448.         if (((HandlerType & ACPI_SYSTEM_NOTIFY) &&
  449.                 AcpiGbl_SystemNotify.Handler)       ||
  450.             ((HandlerType & ACPI_DEVICE_NOTIFY) &&
  451.                 AcpiGbl_DeviceNotify.Handler))
  452.         {
  453.             Status = AE_ALREADY_EXISTS;
  454.             goto UnlockAndExit;
  455.         }
  456.  
  457.         if (HandlerType & ACPI_SYSTEM_NOTIFY)
  458.         {
  459.             AcpiGbl_SystemNotify.Node    = Node;
  460.             AcpiGbl_SystemNotify.Handler = Handler;
  461.             AcpiGbl_SystemNotify.Context = Context;
  462.         }
  463.  
  464.         if (HandlerType & ACPI_DEVICE_NOTIFY)
  465.         {
  466.             AcpiGbl_DeviceNotify.Node    = Node;
  467.             AcpiGbl_DeviceNotify.Handler = Handler;
  468.             AcpiGbl_DeviceNotify.Context = Context;
  469.         }
  470.  
  471.         /* Global notify handler installed */
  472.     }
  473.  
  474.     /*
  475.      * All Other Objects:
  476.      * Caller will only receive notifications specific to the target object.
  477.      * Note that only certain object types can receive notifications.
  478.      */
  479.     else
  480.     {
  481.         /* Notifies allowed on this object? */
  482.  
  483.         if (!AcpiEvIsNotifyObject (Node))
  484.         {
  485.             Status = AE_TYPE;
  486.             goto UnlockAndExit;
  487.         }
  488.  
  489.         /* Check for an existing internal object */
  490.  
  491.         ObjDesc = AcpiNsGetAttachedObject (Node);
  492.         if (ObjDesc)
  493.         {
  494.             /* Object exists - make sure there's no handler */
  495.  
  496.             if (((HandlerType & ACPI_SYSTEM_NOTIFY) &&
  497.                     ObjDesc->CommonNotify.SystemNotify)   ||
  498.                 ((HandlerType & ACPI_DEVICE_NOTIFY) &&
  499.                     ObjDesc->CommonNotify.DeviceNotify))
  500.             {
  501.                 Status = AE_ALREADY_EXISTS;
  502.                 goto UnlockAndExit;
  503.             }
  504.         }
  505.         else
  506.         {
  507.             /* Create a new object */
  508.  
  509.             ObjDesc = AcpiUtCreateInternalObject (Node->Type);
  510.             if (!ObjDesc)
  511.             {
  512.                 Status = AE_NO_MEMORY;
  513.                 goto UnlockAndExit;
  514.             }
  515.  
  516.             /* Attach new object to the Node */
  517.  
  518.             Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
  519.  
  520.             /* Remove local reference to the object */
  521.  
  522.             AcpiUtRemoveReference (ObjDesc);
  523.             if (ACPI_FAILURE (Status))
  524.             {
  525.                 goto UnlockAndExit;
  526.             }
  527.         }
  528.  
  529.         /* Install the handler */
  530.  
  531.         NotifyObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
  532.         if (!NotifyObj)
  533.         {
  534.             Status = AE_NO_MEMORY;
  535.             goto UnlockAndExit;
  536.         }
  537.  
  538.         NotifyObj->Notify.Node    = Node;
  539.         NotifyObj->Notify.Handler = Handler;
  540.         NotifyObj->Notify.Context = Context;
  541.  
  542.         if (HandlerType & ACPI_SYSTEM_NOTIFY)
  543.         {
  544.             ObjDesc->CommonNotify.SystemNotify = NotifyObj;
  545.         }
  546.  
  547.         if (HandlerType & ACPI_DEVICE_NOTIFY)
  548.         {
  549.             ObjDesc->CommonNotify.DeviceNotify = NotifyObj;
  550.         }
  551.  
  552.         if (HandlerType == ACPI_ALL_NOTIFY)
  553.         {
  554.             /* Extra ref if installed in both */
  555.  
  556.             AcpiUtAddReference (NotifyObj);
  557.         }
  558.     }
  559.  
  560.  
  561. UnlockAndExit:
  562.     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  563.     return_ACPI_STATUS (Status);
  564. }
  565.  
  566. ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler)
  567.  
  568.  
  569. /*******************************************************************************
  570.  *
  571.  * FUNCTION:    AcpiRemoveNotifyHandler
  572.  *
  573.  * PARAMETERS:  Device          - The device for which notifies will be handled
  574.  *              HandlerType     - The type of handler:
  575.  *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
  576.  *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
  577.  *                                  ACPI_ALL_NOTIFY:  both system and device
  578.  *              Handler         - Address of the handler
  579.  *
  580.  * RETURN:      Status
  581.  *
  582.  * DESCRIPTION: Remove a handler for notifies on an ACPI device
  583.  *
  584.  ******************************************************************************/
  585.  
  586. ACPI_STATUS
  587. AcpiRemoveNotifyHandler (
  588.     ACPI_HANDLE             Device,
  589.     UINT32                  HandlerType,
  590.     ACPI_NOTIFY_HANDLER     Handler)
  591. {
  592.     ACPI_OPERAND_OBJECT     *NotifyObj;
  593.     ACPI_OPERAND_OBJECT     *ObjDesc;
  594.     ACPI_NAMESPACE_NODE     *Node;
  595.     ACPI_STATUS             Status;
  596.  
  597.  
  598.     ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler);
  599.  
  600.  
  601.     /* Parameter validation */
  602.  
  603.     if ((!Device)  ||
  604.         (!Handler) ||
  605.         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
  606.     {
  607.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  608.     }
  609.  
  610.     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  611.     if (ACPI_FAILURE (Status))
  612.     {
  613.         return_ACPI_STATUS (Status);
  614.     }
  615.  
  616.     /* Convert and validate the device handle */
  617.  
  618.     Node = AcpiNsValidateHandle (Device);
  619.     if (!Node)
  620.     {
  621.         Status = AE_BAD_PARAMETER;
  622.         goto UnlockAndExit;
  623.     }
  624.  
  625.     /* Root Object */
  626.  
  627.     if (Device == ACPI_ROOT_OBJECT)
  628.     {
  629.         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  630.             "Removing notify handler for namespace root object\n"));
  631.  
  632.         if (((HandlerType & ACPI_SYSTEM_NOTIFY) &&
  633.               !AcpiGbl_SystemNotify.Handler)        ||
  634.             ((HandlerType & ACPI_DEVICE_NOTIFY) &&
  635.               !AcpiGbl_DeviceNotify.Handler))
  636.         {
  637.             Status = AE_NOT_EXIST;
  638.             goto UnlockAndExit;
  639.         }
  640.  
  641.         if (HandlerType & ACPI_SYSTEM_NOTIFY)
  642.         {
  643.             AcpiGbl_SystemNotify.Node    = NULL;
  644.             AcpiGbl_SystemNotify.Handler = NULL;
  645.             AcpiGbl_SystemNotify.Context = NULL;
  646.         }
  647.  
  648.         if (HandlerType & ACPI_DEVICE_NOTIFY)
  649.         {
  650.             AcpiGbl_DeviceNotify.Node    = NULL;
  651.             AcpiGbl_DeviceNotify.Handler = NULL;
  652.             AcpiGbl_DeviceNotify.Context = NULL;
  653.         }
  654.     }
  655.  
  656.     /* All Other Objects */
  657.  
  658.     else
  659.     {
  660.         /* Notifies allowed on this object? */
  661.  
  662.         if (!AcpiEvIsNotifyObject (Node))
  663.         {
  664.             Status = AE_TYPE;
  665.             goto UnlockAndExit;
  666.         }
  667.  
  668.         /* Check for an existing internal object */
  669.  
  670.         ObjDesc = AcpiNsGetAttachedObject (Node);
  671.         if (!ObjDesc)
  672.         {
  673.             Status = AE_NOT_EXIST;
  674.             goto UnlockAndExit;
  675.         }
  676.  
  677.         /* Object exists - make sure there's an existing handler */
  678.  
  679.         if (HandlerType & ACPI_SYSTEM_NOTIFY)
  680.         {
  681.             NotifyObj = ObjDesc->CommonNotify.SystemNotify;
  682.             if (!NotifyObj)
  683.             {
  684.                 Status = AE_NOT_EXIST;
  685.                 goto UnlockAndExit;
  686.             }
  687.  
  688.             if (NotifyObj->Notify.Handler != Handler)
  689.             {
  690.                 Status = AE_BAD_PARAMETER;
  691.                 goto UnlockAndExit;
  692.             }
  693.  
  694.             /* Remove the handler */
  695.  
  696.             ObjDesc->CommonNotify.SystemNotify = NULL;
  697.             AcpiUtRemoveReference (NotifyObj);
  698.         }
  699.  
  700.         if (HandlerType & ACPI_DEVICE_NOTIFY)
  701.         {
  702.             NotifyObj = ObjDesc->CommonNotify.DeviceNotify;
  703.             if (!NotifyObj)
  704.             {
  705.                 Status = AE_NOT_EXIST;
  706.                 goto UnlockAndExit;
  707.             }
  708.  
  709.             if (NotifyObj->Notify.Handler != Handler)
  710.             {
  711.                 Status = AE_BAD_PARAMETER;
  712.                 goto UnlockAndExit;
  713.             }
  714.  
  715.             /* Remove the handler */
  716.  
  717.             ObjDesc->CommonNotify.DeviceNotify = NULL;
  718.             AcpiUtRemoveReference (NotifyObj);
  719.         }
  720.     }
  721.  
  722.  
  723. UnlockAndExit:
  724.     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  725.     return_ACPI_STATUS (Status);
  726. }
  727.  
  728. ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler)
  729.  
  730.  
  731. /*******************************************************************************
  732.  *
  733.  * FUNCTION:    AcpiInstallGpeHandler
  734.  *
  735.  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
  736.  *                                defined GPEs)
  737.  *              GpeNumber       - The GPE number within the GPE block
  738.  *              Type            - Whether this GPE should be treated as an
  739.  *                                edge- or level-triggered interrupt.
  740.  *              Address         - Address of the handler
  741.  *              Context         - Value passed to the handler on each GPE
  742.  *
  743.  * RETURN:      Status
  744.  *
  745.  * DESCRIPTION: Install a handler for a General Purpose Event.
  746.  *
  747.  ******************************************************************************/
  748.  
  749. ACPI_STATUS
  750. AcpiInstallGpeHandler (
  751.     ACPI_HANDLE             GpeDevice,
  752.     UINT32                  GpeNumber,
  753.     UINT32                  Type,
  754.     ACPI_GPE_HANDLER        Address,
  755.     void                    *Context)
  756. {
  757.     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
  758.     ACPI_GPE_HANDLER_INFO   *Handler;
  759.     ACPI_STATUS             Status;
  760.     ACPI_CPU_FLAGS          Flags;
  761.  
  762.  
  763.     ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler);
  764.  
  765.  
  766.     /* Parameter validation */
  767.  
  768.     if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK))
  769.     {
  770.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  771.     }
  772.  
  773.     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
  774.     if (ACPI_FAILURE (Status))
  775.     {
  776.         return_ACPI_STATUS (Status);
  777.     }
  778.  
  779.     /* Allocate and init handler object (before lock) */
  780.  
  781.     Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO));
  782.     if (!Handler)
  783.     {
  784.         Status = AE_NO_MEMORY;
  785.         goto UnlockAndExit;
  786.     }
  787.  
  788.     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
  789.  
  790.     /* Ensure that we have a valid GPE number */
  791.  
  792.     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
  793.     if (!GpeEventInfo)
  794.     {
  795.         Status = AE_BAD_PARAMETER;
  796.         goto FreeAndExit;
  797.     }
  798.  
  799.     /* Make sure that there isn't a handler there already */
  800.  
  801.     if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
  802.             ACPI_GPE_DISPATCH_HANDLER)
  803.     {
  804.         Status = AE_ALREADY_EXISTS;
  805.         goto FreeAndExit;
  806.     }
  807.  
  808.     Handler->Address = Address;
  809.     Handler->Context = Context;
  810.     Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;
  811.     Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags &
  812.         (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK));
  813.  
  814.     /*
  815.      * If the GPE is associated with a method, it may have been enabled
  816.      * automatically during initialization, in which case it has to be
  817.      * disabled now to avoid spurious execution of the handler.
  818.      */
  819.     if (((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) ||
  820.          (Handler->OriginalFlags & ACPI_GPE_DISPATCH_NOTIFY)) &&
  821.         GpeEventInfo->RuntimeCount)
  822.     {
  823.         Handler->OriginallyEnabled = TRUE;
  824.         (void) AcpiEvRemoveGpeReference (GpeEventInfo);
  825.  
  826.         /* Sanity check of original type against new type */
  827.  
  828.         if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK))
  829.         {
  830.             ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)"));
  831.         }
  832.     }
  833.  
  834.     /* Install the handler */
  835.  
  836.     GpeEventInfo->Dispatch.Handler = Handler;
  837.  
  838.     /* Setup up dispatch flags to indicate handler (vs. method/notify) */
  839.  
  840.     GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
  841.     GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER);
  842.  
  843.     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  844.  
  845.  
  846. UnlockAndExit:
  847.     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
  848.     return_ACPI_STATUS (Status);
  849.  
  850. FreeAndExit:
  851.     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  852.     ACPI_FREE (Handler);
  853.     goto UnlockAndExit;
  854. }
  855.  
  856. ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler)
  857.  
  858.  
  859. /*******************************************************************************
  860.  *
  861.  * FUNCTION:    AcpiRemoveGpeHandler
  862.  *
  863.  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
  864.  *                                defined GPEs)
  865.  *              GpeNumber       - The event to remove a handler
  866.  *              Address         - Address of the handler
  867.  *
  868.  * RETURN:      Status
  869.  *
  870.  * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
  871.  *
  872.  ******************************************************************************/
  873.  
  874. ACPI_STATUS
  875. AcpiRemoveGpeHandler (
  876.     ACPI_HANDLE             GpeDevice,
  877.     UINT32                  GpeNumber,
  878.     ACPI_GPE_HANDLER        Address)
  879. {
  880.     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
  881.     ACPI_GPE_HANDLER_INFO   *Handler;
  882.     ACPI_STATUS             Status;
  883.     ACPI_CPU_FLAGS          Flags;
  884.  
  885.  
  886.     ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler);
  887.  
  888.  
  889.     /* Parameter validation */
  890.  
  891.     if (!Address)
  892.     {
  893.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  894.     }
  895.  
  896.     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
  897.     if (ACPI_FAILURE (Status))
  898.     {
  899.         return_ACPI_STATUS (Status);
  900.     }
  901.  
  902.     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
  903.  
  904.     /* Ensure that we have a valid GPE number */
  905.  
  906.     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
  907.     if (!GpeEventInfo)
  908.     {
  909.         Status = AE_BAD_PARAMETER;
  910.         goto UnlockAndExit;
  911.     }
  912.  
  913.     /* Make sure that a handler is indeed installed */
  914.  
  915.     if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) !=
  916.             ACPI_GPE_DISPATCH_HANDLER)
  917.     {
  918.         Status = AE_NOT_EXIST;
  919.         goto UnlockAndExit;
  920.     }
  921.  
  922.     /* Make sure that the installed handler is the same */
  923.  
  924.     if (GpeEventInfo->Dispatch.Handler->Address != Address)
  925.     {
  926.         Status = AE_BAD_PARAMETER;
  927.         goto UnlockAndExit;
  928.     }
  929.  
  930.     /* Remove the handler */
  931.  
  932.     Handler = GpeEventInfo->Dispatch.Handler;
  933.  
  934.     /* Restore Method node (if any), set dispatch flags */
  935.  
  936.     GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode;
  937.     GpeEventInfo->Flags &=
  938.         ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
  939.     GpeEventInfo->Flags |= Handler->OriginalFlags;
  940.  
  941.     /*
  942.      * If the GPE was previously associated with a method and it was
  943.      * enabled, it should be enabled at this point to restore the
  944.      * post-initialization configuration.
  945.      */
  946.     if ((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) &&
  947.         Handler->OriginallyEnabled)
  948.     {
  949.         (void) AcpiEvAddGpeReference (GpeEventInfo);
  950.     }
  951.  
  952.     /* Now we can free the handler object */
  953.  
  954.     ACPI_FREE (Handler);
  955.  
  956.  
  957. UnlockAndExit:
  958.     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  959.     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
  960.     return_ACPI_STATUS (Status);
  961. }
  962.  
  963. ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler)
  964.  
  965.  
  966. /*******************************************************************************
  967.  *
  968.  * FUNCTION:    AcpiAcquireGlobalLock
  969.  *
  970.  * PARAMETERS:  Timeout         - How long the caller is willing to wait
  971.  *              Handle          - Where the handle to the lock is returned
  972.  *                                (if acquired)
  973.  *
  974.  * RETURN:      Status
  975.  *
  976.  * DESCRIPTION: Acquire the ACPI Global Lock
  977.  *
  978.  * Note: Allows callers with the same thread ID to acquire the global lock
  979.  * multiple times. In other words, externally, the behavior of the global lock
  980.  * is identical to an AML mutex. On the first acquire, a new handle is
  981.  * returned. On any subsequent calls to acquire by the same thread, the same
  982.  * handle is returned.
  983.  *
  984.  ******************************************************************************/
  985.  
  986. ACPI_STATUS
  987. AcpiAcquireGlobalLock (
  988.     UINT16                  Timeout,
  989.     UINT32                  *Handle)
  990. {
  991.     ACPI_STATUS             Status;
  992.  
  993.  
  994.     if (!Handle)
  995.     {
  996.         return (AE_BAD_PARAMETER);
  997.     }
  998.  
  999.     /* Must lock interpreter to prevent race conditions */
  1000.  
  1001.     AcpiExEnterInterpreter ();
  1002.  
  1003.     Status = AcpiExAcquireMutexObject (Timeout,
  1004.                 AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ());
  1005.  
  1006.     if (ACPI_SUCCESS (Status))
  1007.     {
  1008.         /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */
  1009.  
  1010.         *Handle = AcpiGbl_GlobalLockHandle;
  1011.     }
  1012.  
  1013.     AcpiExExitInterpreter ();
  1014.     return (Status);
  1015. }
  1016.  
  1017. ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock)
  1018.  
  1019.  
  1020. /*******************************************************************************
  1021.  *
  1022.  * FUNCTION:    AcpiReleaseGlobalLock
  1023.  *
  1024.  * PARAMETERS:  Handle      - Returned from AcpiAcquireGlobalLock
  1025.  *
  1026.  * RETURN:      Status
  1027.  *
  1028.  * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
  1029.  *
  1030.  ******************************************************************************/
  1031.  
  1032. ACPI_STATUS
  1033. AcpiReleaseGlobalLock (
  1034.     UINT32                  Handle)
  1035. {
  1036.     ACPI_STATUS             Status;
  1037.  
  1038.  
  1039.     if (!Handle || (Handle != AcpiGbl_GlobalLockHandle))
  1040.     {
  1041.         return (AE_NOT_ACQUIRED);
  1042.     }
  1043.  
  1044.     Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex);
  1045.     return (Status);
  1046. }
  1047.  
  1048. ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock)
  1049.  
  1050.