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: evmisc - Miscellaneous event manager support functions
  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. #include "acpi.h"
  117. #include "accommon.h"
  118. #include "acevents.h"
  119. #include "acnamesp.h"
  120. #include "acinterp.h"
  121.  
  122. #define _COMPONENT          ACPI_EVENTS
  123.         ACPI_MODULE_NAME    ("evmisc")
  124.  
  125.  
  126. /* Local prototypes */
  127.  
  128. static void ACPI_SYSTEM_XFACE
  129. AcpiEvNotifyDispatch (
  130.     void                    *Context);
  131.  
  132. static UINT32
  133. AcpiEvGlobalLockHandler (
  134.     void                    *Context);
  135.  
  136. static ACPI_STATUS
  137. AcpiEvRemoveGlobalLockHandler (
  138.     void);
  139.  
  140.  
  141. /*******************************************************************************
  142.  *
  143.  * FUNCTION:    AcpiEvIsNotifyObject
  144.  *
  145.  * PARAMETERS:  Node            - Node to check
  146.  *
  147.  * RETURN:      TRUE if notifies allowed on this object
  148.  *
  149.  * DESCRIPTION: Check type of node for a object that supports notifies.
  150.  *
  151.  *              TBD: This could be replaced by a flag bit in the node.
  152.  *
  153.  ******************************************************************************/
  154.  
  155. BOOLEAN
  156. AcpiEvIsNotifyObject (
  157.     ACPI_NAMESPACE_NODE     *Node)
  158. {
  159.     switch (Node->Type)
  160.     {
  161.     case ACPI_TYPE_DEVICE:
  162.     case ACPI_TYPE_PROCESSOR:
  163.     case ACPI_TYPE_THERMAL:
  164.         /*
  165.          * These are the ONLY objects that can receive ACPI notifications
  166.          */
  167.         return (TRUE);
  168.  
  169.     default:
  170.         return (FALSE);
  171.     }
  172. }
  173.  
  174.  
  175. /*******************************************************************************
  176.  *
  177.  * FUNCTION:    AcpiEvQueueNotifyRequest
  178.  *
  179.  * PARAMETERS:  Node            - NS node for the notified object
  180.  *              NotifyValue     - Value from the Notify() request
  181.  *
  182.  * RETURN:      Status
  183.  *
  184.  * DESCRIPTION: Dispatch a device notification event to a previously
  185.  *              installed handler.
  186.  *
  187.  ******************************************************************************/
  188.  
  189. ACPI_STATUS
  190. AcpiEvQueueNotifyRequest (
  191.     ACPI_NAMESPACE_NODE     *Node,
  192.     UINT32                  NotifyValue)
  193. {
  194.     ACPI_OPERAND_OBJECT     *ObjDesc;
  195.     ACPI_OPERAND_OBJECT     *HandlerObj = NULL;
  196.     ACPI_GENERIC_STATE      *NotifyInfo;
  197.     ACPI_STATUS             Status = AE_OK;
  198.  
  199.  
  200.     ACPI_FUNCTION_NAME (EvQueueNotifyRequest);
  201.  
  202.  
  203.     /*
  204.      * For value 3 (Ejection Request), some device method may need to be run.
  205.      * For value 2 (Device Wake) if _PRW exists, the _PS0 method may need
  206.      *   to be run.
  207.      * For value 0x80 (Status Change) on the power button or sleep button,
  208.      *   initiate soft-off or sleep operation?
  209.      */
  210.     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  211.         "Dispatching Notify on [%4.4s] Node %p Value 0x%2.2X (%s)\n",
  212.         AcpiUtGetNodeName (Node), Node, NotifyValue,
  213.         AcpiUtGetNotifyName (NotifyValue)));
  214.  
  215.     /* Get the notify object attached to the NS Node */
  216.  
  217.     ObjDesc = AcpiNsGetAttachedObject (Node);
  218.     if (ObjDesc)
  219.     {
  220.         /* We have the notify object, Get the right handler */
  221.  
  222.         switch (Node->Type)
  223.         {
  224.         /* Notify allowed only on these types */
  225.  
  226.         case ACPI_TYPE_DEVICE:
  227.         case ACPI_TYPE_THERMAL:
  228.         case ACPI_TYPE_PROCESSOR:
  229.  
  230.             if (NotifyValue <= ACPI_MAX_SYS_NOTIFY)
  231.             {
  232.                 HandlerObj = ObjDesc->CommonNotify.SystemNotify;
  233.             }
  234.             else
  235.             {
  236.                 HandlerObj = ObjDesc->CommonNotify.DeviceNotify;
  237.             }
  238.             break;
  239.  
  240.         default:
  241.  
  242.             /* All other types are not supported */
  243.  
  244.             return (AE_TYPE);
  245.         }
  246.     }
  247.  
  248.     /*
  249.      * If there is any handler to run, schedule the dispatcher.
  250.      * Check for:
  251.      * 1) Global system notify handler
  252.      * 2) Global device notify handler
  253.      * 3) Per-device notify handler
  254.      */
  255.     if ((AcpiGbl_SystemNotify.Handler &&
  256.             (NotifyValue <= ACPI_MAX_SYS_NOTIFY)) ||
  257.         (AcpiGbl_DeviceNotify.Handler &&
  258.             (NotifyValue > ACPI_MAX_SYS_NOTIFY))  ||
  259.         HandlerObj)
  260.     {
  261.         NotifyInfo = AcpiUtCreateGenericState ();
  262.         if (!NotifyInfo)
  263.         {
  264.             return (AE_NO_MEMORY);
  265.         }
  266.  
  267.         if (!HandlerObj)
  268.         {
  269.             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  270.                 "Executing system notify handler for Notify (%4.4s, %X) "
  271.                 "node %p\n",
  272.                 AcpiUtGetNodeName (Node), NotifyValue, Node));
  273.         }
  274.  
  275.         NotifyInfo->Common.DescriptorType = ACPI_DESC_TYPE_STATE_NOTIFY;
  276.         NotifyInfo->Notify.Node = Node;
  277.         NotifyInfo->Notify.Value = (UINT16) NotifyValue;
  278.         NotifyInfo->Notify.HandlerObj = HandlerObj;
  279.  
  280.         Status = AcpiOsExecute (
  281.                     OSL_NOTIFY_HANDLER, AcpiEvNotifyDispatch, NotifyInfo);
  282.         if (ACPI_FAILURE (Status))
  283.         {
  284.             AcpiUtDeleteGenericState (NotifyInfo);
  285.         }
  286.     }
  287.     else
  288.     {
  289.         /* There is no notify handler (per-device or system) for this device */
  290.  
  291.         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  292.             "No notify handler for Notify (%4.4s, %X) node %p\n",
  293.             AcpiUtGetNodeName (Node), NotifyValue, Node));
  294.     }
  295.  
  296.     return (Status);
  297. }
  298.  
  299.  
  300. /*******************************************************************************
  301.  *
  302.  * FUNCTION:    AcpiEvNotifyDispatch
  303.  *
  304.  * PARAMETERS:  Context         - To be passed to the notify handler
  305.  *
  306.  * RETURN:      None.
  307.  *
  308.  * DESCRIPTION: Dispatch a device notification event to a previously
  309.  *              installed handler.
  310.  *
  311.  ******************************************************************************/
  312.  
  313. static void ACPI_SYSTEM_XFACE
  314. AcpiEvNotifyDispatch (
  315.     void                    *Context)
  316. {
  317.     ACPI_GENERIC_STATE      *NotifyInfo = (ACPI_GENERIC_STATE *) Context;
  318.     ACPI_NOTIFY_HANDLER     GlobalHandler = NULL;
  319.     void                    *GlobalContext = NULL;
  320.     ACPI_OPERAND_OBJECT     *HandlerObj;
  321.  
  322.  
  323.     ACPI_FUNCTION_ENTRY ();
  324.  
  325.  
  326.     /*
  327.      * We will invoke a global notify handler if installed. This is done
  328.      * _before_ we invoke the per-device handler attached to the device.
  329.      */
  330.     if (NotifyInfo->Notify.Value <= ACPI_MAX_SYS_NOTIFY)
  331.     {
  332.         /* Global system notification handler */
  333.  
  334.         if (AcpiGbl_SystemNotify.Handler)
  335.         {
  336.             GlobalHandler = AcpiGbl_SystemNotify.Handler;
  337.             GlobalContext = AcpiGbl_SystemNotify.Context;
  338.         }
  339.     }
  340.     else
  341.     {
  342.         /* Global driver notification handler */
  343.  
  344.         if (AcpiGbl_DeviceNotify.Handler)
  345.         {
  346.             GlobalHandler = AcpiGbl_DeviceNotify.Handler;
  347.             GlobalContext = AcpiGbl_DeviceNotify.Context;
  348.         }
  349.     }
  350.  
  351.     /* Invoke the system handler first, if present */
  352.  
  353.     if (GlobalHandler)
  354.     {
  355.         GlobalHandler (NotifyInfo->Notify.Node, NotifyInfo->Notify.Value,
  356.             GlobalContext);
  357.     }
  358.  
  359.     /* Now invoke the per-device handler, if present */
  360.  
  361.     HandlerObj = NotifyInfo->Notify.HandlerObj;
  362.     if (HandlerObj)
  363.     {
  364.         HandlerObj->Notify.Handler (NotifyInfo->Notify.Node,
  365.             NotifyInfo->Notify.Value,
  366.             HandlerObj->Notify.Context);
  367.     }
  368.  
  369.     /* All done with the info object */
  370.  
  371.     AcpiUtDeleteGenericState (NotifyInfo);
  372. }
  373.  
  374.  
  375. /*******************************************************************************
  376.  *
  377.  * FUNCTION:    AcpiEvGlobalLockHandler
  378.  *
  379.  * PARAMETERS:  Context         - From thread interface, not used
  380.  *
  381.  * RETURN:      ACPI_INTERRUPT_HANDLED
  382.  *
  383.  * DESCRIPTION: Invoked directly from the SCI handler when a global lock
  384.  *              release interrupt occurs. Attempt to acquire the global lock,
  385.  *              if successful, signal the thread waiting for the lock.
  386.  *
  387.  * NOTE: Assumes that the semaphore can be signaled from interrupt level. If
  388.  * this is not possible for some reason, a separate thread will have to be
  389.  * scheduled to do this.
  390.  *
  391.  ******************************************************************************/
  392.  
  393. static UINT32
  394. AcpiEvGlobalLockHandler (
  395.     void                    *Context)
  396. {
  397.     BOOLEAN                 Acquired = FALSE;
  398.     ACPI_STATUS             Status;
  399.  
  400.  
  401.     /*
  402.      * Attempt to get the lock.
  403.      *
  404.      * If we don't get it now, it will be marked pending and we will
  405.      * take another interrupt when it becomes free.
  406.      */
  407.     ACPI_ACQUIRE_GLOBAL_LOCK (AcpiGbl_FACS, Acquired);
  408.     if (Acquired)
  409.     {
  410.         /* Got the lock, now wake the thread waiting for it */
  411.  
  412.         AcpiGbl_GlobalLockAcquired = TRUE;
  413.  
  414.         /* Send a unit to the semaphore */
  415.  
  416.         Status = AcpiOsSignalSemaphore (AcpiGbl_GlobalLockSemaphore, 1);
  417.         if (ACPI_FAILURE (Status))
  418.         {
  419.             ACPI_ERROR ((AE_INFO, "Could not signal Global Lock semaphore"));
  420.         }
  421.     }
  422.  
  423.     return (ACPI_INTERRUPT_HANDLED);
  424. }
  425.  
  426.  
  427. /*******************************************************************************
  428.  *
  429.  * FUNCTION:    AcpiEvInitGlobalLockHandler
  430.  *
  431.  * PARAMETERS:  None
  432.  *
  433.  * RETURN:      Status
  434.  *
  435.  * DESCRIPTION: Install a handler for the global lock release event
  436.  *
  437.  ******************************************************************************/
  438.  
  439. ACPI_STATUS
  440. AcpiEvInitGlobalLockHandler (
  441.     void)
  442. {
  443.     ACPI_STATUS             Status;
  444.  
  445.  
  446.     ACPI_FUNCTION_TRACE (EvInitGlobalLockHandler);
  447.  
  448.  
  449.     /* Attempt installation of the global lock handler */
  450.  
  451.     Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL,
  452.                 AcpiEvGlobalLockHandler, NULL);
  453.  
  454.     /*
  455.      * If the global lock does not exist on this platform, the attempt to
  456.      * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick).
  457.      * Map to AE_OK, but mark global lock as not present. Any attempt to
  458.      * actually use the global lock will be flagged with an error.
  459.      */
  460.     if (Status == AE_NO_HARDWARE_RESPONSE)
  461.     {
  462.         ACPI_ERROR ((AE_INFO,
  463.             "No response from Global Lock hardware, disabling lock"));
  464.  
  465.         AcpiGbl_GlobalLockPresent = FALSE;
  466.         return_ACPI_STATUS (AE_OK);
  467.     }
  468.  
  469.     AcpiGbl_GlobalLockPresent = TRUE;
  470.     return_ACPI_STATUS (Status);
  471. }
  472.  
  473.  
  474. /*******************************************************************************
  475.  *
  476.  * FUNCTION:    AcpiEvRemoveGlobalLockHandler
  477.  *
  478.  * PARAMETERS:  None
  479.  *
  480.  * RETURN:      Status
  481.  *
  482.  * DESCRIPTION: Remove the handler for the Global Lock
  483.  *
  484.  ******************************************************************************/
  485.  
  486. static ACPI_STATUS
  487. AcpiEvRemoveGlobalLockHandler (
  488.     void)
  489. {
  490.     ACPI_STATUS             Status;
  491.  
  492.  
  493.     ACPI_FUNCTION_TRACE (EvRemoveGlobalLockHandler);
  494.  
  495.     AcpiGbl_GlobalLockPresent = FALSE;
  496.     Status = AcpiRemoveFixedEventHandler (ACPI_EVENT_GLOBAL,
  497.                 AcpiEvGlobalLockHandler);
  498.  
  499.     return_ACPI_STATUS (Status);
  500. }
  501.  
  502.  
  503. /******************************************************************************
  504.  *
  505.  * FUNCTION:    AcpiEvAcquireGlobalLock
  506.  *
  507.  * PARAMETERS:  Timeout         - Max time to wait for the lock, in millisec.
  508.  *
  509.  * RETURN:      Status
  510.  *
  511.  * DESCRIPTION: Attempt to gain ownership of the Global Lock.
  512.  *
  513.  * MUTEX:       Interpreter must be locked
  514.  *
  515.  * Note: The original implementation allowed multiple threads to "acquire" the
  516.  * Global Lock, and the OS would hold the lock until the last thread had
  517.  * released it. However, this could potentially starve the BIOS out of the
  518.  * lock, especially in the case where there is a tight handshake between the
  519.  * Embedded Controller driver and the BIOS. Therefore, this implementation
  520.  * allows only one thread to acquire the HW Global Lock at a time, and makes
  521.  * the global lock appear as a standard mutex on the OS side.
  522.  *
  523.  *****************************************************************************/
  524.  
  525. ACPI_STATUS
  526. AcpiEvAcquireGlobalLock (
  527.     UINT16                  Timeout)
  528. {
  529.     ACPI_STATUS             Status = AE_OK;
  530.     BOOLEAN                 Acquired = FALSE;
  531.  
  532.  
  533.     ACPI_FUNCTION_TRACE (EvAcquireGlobalLock);
  534.  
  535.  
  536.     /*
  537.      * Only one thread can acquire the GL at a time, the GlobalLockMutex
  538.      * enforces this. This interface releases the interpreter if we must wait.
  539.      */
  540.     Status = AcpiExSystemWaitMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex,
  541.                 Timeout);
  542.     if (ACPI_FAILURE (Status))
  543.     {
  544.         return_ACPI_STATUS (Status);
  545.     }
  546.  
  547.     /*
  548.      * Update the global lock handle and check for wraparound. The handle is
  549.      * only used for the external global lock interfaces, but it is updated
  550.      * here to properly handle the case where a single thread may acquire the
  551.      * lock via both the AML and the AcpiAcquireGlobalLock interfaces. The
  552.      * handle is therefore updated on the first acquire from a given thread
  553.      * regardless of where the acquisition request originated.
  554.      */
  555.     AcpiGbl_GlobalLockHandle++;
  556.     if (AcpiGbl_GlobalLockHandle == 0)
  557.     {
  558.         AcpiGbl_GlobalLockHandle = 1;
  559.     }
  560.  
  561.     /*
  562.      * Make sure that a global lock actually exists. If not, just treat the
  563.      * lock as a standard mutex.
  564.      */
  565.     if (!AcpiGbl_GlobalLockPresent)
  566.     {
  567.         AcpiGbl_GlobalLockAcquired = TRUE;
  568.         return_ACPI_STATUS (AE_OK);
  569.     }
  570.  
  571.     /* Attempt to acquire the actual hardware lock */
  572.  
  573.     ACPI_ACQUIRE_GLOBAL_LOCK (AcpiGbl_FACS, Acquired);
  574.     if (Acquired)
  575.     {
  576.        /* We got the lock */
  577.  
  578.         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Acquired hardware Global Lock\n"));
  579.  
  580.         AcpiGbl_GlobalLockAcquired = TRUE;
  581.         return_ACPI_STATUS (AE_OK);
  582.     }
  583.  
  584.     /*
  585.      * Did not get the lock. The pending bit was set above, and we must now
  586.      * wait until we get the global lock released interrupt.
  587.      */
  588.     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n"));
  589.  
  590.     /*
  591.      * Wait for handshake with the global lock interrupt handler.
  592.      * This interface releases the interpreter if we must wait.
  593.      */
  594.     Status = AcpiExSystemWaitSemaphore (AcpiGbl_GlobalLockSemaphore,
  595.                 ACPI_WAIT_FOREVER);
  596.  
  597.     return_ACPI_STATUS (Status);
  598. }
  599.  
  600.  
  601. /*******************************************************************************
  602.  *
  603.  * FUNCTION:    AcpiEvReleaseGlobalLock
  604.  *
  605.  * PARAMETERS:  None
  606.  *
  607.  * RETURN:      Status
  608.  *
  609.  * DESCRIPTION: Releases ownership of the Global Lock.
  610.  *
  611.  ******************************************************************************/
  612.  
  613. ACPI_STATUS
  614. AcpiEvReleaseGlobalLock (
  615.     void)
  616. {
  617.     BOOLEAN                 Pending = FALSE;
  618.     ACPI_STATUS             Status = AE_OK;
  619.  
  620.  
  621.     ACPI_FUNCTION_TRACE (EvReleaseGlobalLock);
  622.  
  623.  
  624.     /* Lock must be already acquired */
  625.  
  626.     if (!AcpiGbl_GlobalLockAcquired)
  627.     {
  628.         ACPI_WARNING ((AE_INFO,
  629.             "Cannot release the ACPI Global Lock, it has not been acquired"));
  630.         return_ACPI_STATUS (AE_NOT_ACQUIRED);
  631.     }
  632.  
  633.     if (AcpiGbl_GlobalLockPresent)
  634.     {
  635.         /* Allow any thread to release the lock */
  636.  
  637.         ACPI_RELEASE_GLOBAL_LOCK (AcpiGbl_FACS, Pending);
  638.  
  639.         /*
  640.          * If the pending bit was set, we must write GBL_RLS to the control
  641.          * register
  642.          */
  643.         if (Pending)
  644.         {
  645.             Status = AcpiWriteBitRegister (
  646.                         ACPI_BITREG_GLOBAL_LOCK_RELEASE, ACPI_ENABLE_EVENT);
  647.         }
  648.  
  649.         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Released hardware Global Lock\n"));
  650.     }
  651.  
  652.     AcpiGbl_GlobalLockAcquired = FALSE;
  653.  
  654.     /* Release the local GL mutex */
  655.  
  656.     AcpiOsReleaseMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex);
  657.     return_ACPI_STATUS (Status);
  658. }
  659.  
  660.  
  661. /******************************************************************************
  662.  *
  663.  * FUNCTION:    AcpiEvTerminate
  664.  *
  665.  * PARAMETERS:  none
  666.  *
  667.  * RETURN:      none
  668.  *
  669.  * DESCRIPTION: Disable events and free memory allocated for table storage.
  670.  *
  671.  ******************************************************************************/
  672.  
  673. void
  674. AcpiEvTerminate (
  675.     void)
  676. {
  677.     UINT32                  i;
  678.     ACPI_STATUS             Status;
  679.  
  680.  
  681.     ACPI_FUNCTION_TRACE (EvTerminate);
  682.  
  683.  
  684.     if (AcpiGbl_EventsInitialized)
  685.     {
  686.         /*
  687.          * Disable all event-related functionality. In all cases, on error,
  688.          * print a message but obviously we don't abort.
  689.          */
  690.  
  691.         /* Disable all fixed events */
  692.  
  693.         for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++)
  694.         {
  695.             Status = AcpiDisableEvent (i, 0);
  696.             if (ACPI_FAILURE (Status))
  697.             {
  698.                 ACPI_ERROR ((AE_INFO,
  699.                     "Could not disable fixed event %u", (UINT32) i));
  700.             }
  701.         }
  702.  
  703.         /* Disable all GPEs in all GPE blocks */
  704.  
  705.         Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock, NULL);
  706.  
  707.         /* Remove SCI handler */
  708.  
  709.         Status = AcpiEvRemoveSciHandler ();
  710.         if (ACPI_FAILURE(Status))
  711.         {
  712.             ACPI_ERROR ((AE_INFO,
  713.                 "Could not remove SCI handler"));
  714.         }
  715.  
  716.         Status = AcpiEvRemoveGlobalLockHandler ();
  717.         if (ACPI_FAILURE(Status))
  718.         {
  719.             ACPI_ERROR ((AE_INFO,
  720.                 "Could not remove Global Lock handler"));
  721.         }
  722.     }
  723.  
  724.     /* Deallocate all handler objects installed within GPE info structs */
  725.  
  726.     Status = AcpiEvWalkGpeList (AcpiEvDeleteGpeHandlers, NULL);
  727.  
  728.     /* Return to original mode if necessary */
  729.  
  730.     if (AcpiGbl_OriginalMode == ACPI_SYS_MODE_LEGACY)
  731.     {
  732.         Status = AcpiDisable ();
  733.         if (ACPI_FAILURE (Status))
  734.         {
  735.             ACPI_WARNING ((AE_INFO, "AcpiDisable failed"));
  736.         }
  737.     }
  738.     return_VOID;
  739. }
  740.  
  741.