The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/acpica/components/events/evxface.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 - 2022, 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  * Alternatively, you may choose to be licensed under the terms of the
  117  * following license:
  118  *
  119  * Redistribution and use in source and binary forms, with or without
  120  * modification, are permitted provided that the following conditions
  121  * are met:
  122  * 1. Redistributions of source code must retain the above copyright
  123  *    notice, this list of conditions, and the following disclaimer,
  124  *    without modification.
  125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  126  *    substantially similar to the "NO WARRANTY" disclaimer below
  127  *    ("Disclaimer") and any redistribution must be conditioned upon
  128  *    including a substantially similar Disclaimer requirement for further
  129  *    binary redistribution.
  130  * 3. Neither the names of the above-listed copyright holders nor the names
  131  *    of any contributors may be used to endorse or promote products derived
  132  *    from this software without specific prior written permission.
  133  *
  134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  145  *
  146  * Alternatively, you may choose to be licensed under the terms of the
  147  * GNU General Public License ("GPL") version 2 as published by the Free
  148  * Software Foundation.
  149  *
  150  *****************************************************************************/
  151 
  152 #define EXPORT_ACPI_INTERFACES
  153 
  154 #include <contrib/dev/acpica/include/acpi.h>
  155 #include <contrib/dev/acpica/include/accommon.h>
  156 #include <contrib/dev/acpica/include/acnamesp.h>
  157 #include <contrib/dev/acpica/include/acevents.h>
  158 #include <contrib/dev/acpica/include/acinterp.h>
  159 
  160 #define _COMPONENT          ACPI_EVENTS
  161         ACPI_MODULE_NAME    ("evxface")
  162 
  163 #if (!ACPI_REDUCED_HARDWARE)
  164 
  165 /* Local prototypes */
  166 
  167 static ACPI_STATUS
  168 AcpiEvInstallGpeHandler (
  169     ACPI_HANDLE             GpeDevice,
  170     UINT32                  GpeNumber,
  171     UINT32                  Type,
  172     BOOLEAN                 IsRawHandler,
  173     ACPI_GPE_HANDLER        Address,
  174     void                    *Context);
  175 
  176 #endif
  177 
  178 
  179 /*******************************************************************************
  180  *
  181  * FUNCTION:    AcpiInstallNotifyHandler
  182  *
  183  * PARAMETERS:  Device          - The device for which notifies will be handled
  184  *              HandlerType     - The type of handler:
  185  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
  186  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
  187  *                                  ACPI_ALL_NOTIFY:    Both System and Device
  188  *              Handler         - Address of the handler
  189  *              Context         - Value passed to the handler on each GPE
  190  *
  191  * RETURN:      Status
  192  *
  193  * DESCRIPTION: Install a handler for notifications on an ACPI Device,
  194  *              ThermalZone, or Processor object.
  195  *
  196  * NOTES:       The Root namespace object may have only one handler for each
  197  *              type of notify (System/Device). Device/Thermal/Processor objects
  198  *              may have one device notify handler, and multiple system notify
  199  *              handlers.
  200  *
  201  ******************************************************************************/
  202 
  203 ACPI_STATUS
  204 AcpiInstallNotifyHandler (
  205     ACPI_HANDLE             Device,
  206     UINT32                  HandlerType,
  207     ACPI_NOTIFY_HANDLER     Handler,
  208     void                    *Context)
  209 {
  210     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
  211     ACPI_OPERAND_OBJECT     *ObjDesc;
  212     ACPI_OPERAND_OBJECT     *HandlerObj;
  213     ACPI_STATUS             Status;
  214     UINT32                  i;
  215 
  216 
  217     ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler);
  218 
  219 
  220     /* Parameter validation */
  221 
  222     if ((!Device) || (!Handler) || (!HandlerType) ||
  223         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
  224     {
  225         return_ACPI_STATUS (AE_BAD_PARAMETER);
  226     }
  227 
  228     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  229     if (ACPI_FAILURE (Status))
  230     {
  231         return_ACPI_STATUS (Status);
  232     }
  233 
  234     /*
  235      * Root Object:
  236      * Registering a notify handler on the root object indicates that the
  237      * caller wishes to receive notifications for all objects. Note that
  238      * only one global handler can be registered per notify type.
  239      * Ensure that a handler is not already installed.
  240      */
  241     if (Device == ACPI_ROOT_OBJECT)
  242     {
  243         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
  244         {
  245             if (HandlerType & (i+1))
  246             {
  247                 if (AcpiGbl_GlobalNotify[i].Handler)
  248                 {
  249                     Status = AE_ALREADY_EXISTS;
  250                     goto UnlockAndExit;
  251                 }
  252 
  253                 AcpiGbl_GlobalNotify[i].Handler = Handler;
  254                 AcpiGbl_GlobalNotify[i].Context = Context;
  255             }
  256         }
  257 
  258         goto UnlockAndExit; /* Global notify handler installed, all done */
  259     }
  260 
  261     /*
  262      * All Other Objects:
  263      * Caller will only receive notifications specific to the target
  264      * object. Note that only certain object types are allowed to
  265      * receive notifications.
  266      */
  267 
  268     /* Are Notifies allowed on this object? */
  269 
  270     if (!AcpiEvIsNotifyObject (Node))
  271     {
  272         Status = AE_TYPE;
  273         goto UnlockAndExit;
  274     }
  275 
  276     /* Check for an existing internal object, might not exist */
  277 
  278     ObjDesc = AcpiNsGetAttachedObject (Node);
  279     if (!ObjDesc)
  280     {
  281         /* Create a new object */
  282 
  283         ObjDesc = AcpiUtCreateInternalObject (Node->Type);
  284         if (!ObjDesc)
  285         {
  286             Status = AE_NO_MEMORY;
  287             goto UnlockAndExit;
  288         }
  289 
  290         /* Attach new object to the Node, remove local reference */
  291 
  292         Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
  293         AcpiUtRemoveReference (ObjDesc);
  294         if (ACPI_FAILURE (Status))
  295         {
  296             goto UnlockAndExit;
  297         }
  298     }
  299 
  300     /* Ensure that the handler is not already installed in the lists */
  301 
  302     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
  303     {
  304         if (HandlerType & (i+1))
  305         {
  306             HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
  307             while (HandlerObj)
  308             {
  309                 if (HandlerObj->Notify.Handler == Handler)
  310                 {
  311                     Status = AE_ALREADY_EXISTS;
  312                     goto UnlockAndExit;
  313                 }
  314 
  315                 HandlerObj = HandlerObj->Notify.Next[i];
  316             }
  317         }
  318     }
  319 
  320     /* Create and populate a new notify handler object */
  321 
  322     HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
  323     if (!HandlerObj)
  324     {
  325         Status = AE_NO_MEMORY;
  326         goto UnlockAndExit;
  327     }
  328 
  329     HandlerObj->Notify.Node = Node;
  330     HandlerObj->Notify.HandlerType = HandlerType;
  331     HandlerObj->Notify.Handler = Handler;
  332     HandlerObj->Notify.Context = Context;
  333 
  334     /* Install the handler at the list head(s) */
  335 
  336     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
  337     {
  338         if (HandlerType & (i+1))
  339         {
  340             HandlerObj->Notify.Next[i] =
  341                 ObjDesc->CommonNotify.NotifyList[i];
  342 
  343             ObjDesc->CommonNotify.NotifyList[i] = HandlerObj;
  344         }
  345     }
  346 
  347     /* Add an extra reference if handler was installed in both lists */
  348 
  349     if (HandlerType == ACPI_ALL_NOTIFY)
  350     {
  351         AcpiUtAddReference (HandlerObj);
  352     }
  353 
  354 
  355 UnlockAndExit:
  356     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  357     return_ACPI_STATUS (Status);
  358 }
  359 
  360 ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler)
  361 
  362 
  363 /*******************************************************************************
  364  *
  365  * FUNCTION:    AcpiRemoveNotifyHandler
  366  *
  367  * PARAMETERS:  Device          - The device for which the handler is installed
  368  *              HandlerType     - The type of handler:
  369  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
  370  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
  371  *                                  ACPI_ALL_NOTIFY:    Both System and Device
  372  *              Handler         - Address of the handler
  373  *
  374  * RETURN:      Status
  375  *
  376  * DESCRIPTION: Remove a handler for notifies on an ACPI device
  377  *
  378  ******************************************************************************/
  379 
  380 ACPI_STATUS
  381 AcpiRemoveNotifyHandler (
  382     ACPI_HANDLE             Device,
  383     UINT32                  HandlerType,
  384     ACPI_NOTIFY_HANDLER     Handler)
  385 {
  386     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
  387     ACPI_OPERAND_OBJECT     *ObjDesc;
  388     ACPI_OPERAND_OBJECT     *HandlerObj;
  389     ACPI_OPERAND_OBJECT     *PreviousHandlerObj;
  390     ACPI_STATUS             Status = AE_OK;
  391     UINT32                  i;
  392 
  393 
  394     ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler);
  395 
  396 
  397     /* Parameter validation */
  398 
  399     if ((!Device) || (!Handler) || (!HandlerType) ||
  400         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
  401     {
  402         return_ACPI_STATUS (AE_BAD_PARAMETER);
  403     }
  404 
  405     /* Root Object. Global handlers are removed here */
  406 
  407     if (Device == ACPI_ROOT_OBJECT)
  408     {
  409         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
  410         {
  411             if (HandlerType & (i+1))
  412             {
  413                 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  414                 if (ACPI_FAILURE (Status))
  415                 {
  416                     return_ACPI_STATUS (Status);
  417                 }
  418 
  419                 if (!AcpiGbl_GlobalNotify[i].Handler ||
  420                     (AcpiGbl_GlobalNotify[i].Handler != Handler))
  421                 {
  422                     Status = AE_NOT_EXIST;
  423                     goto UnlockAndExit;
  424                 }
  425 
  426                 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  427                     "Removing global notify handler\n"));
  428 
  429                 AcpiGbl_GlobalNotify[i].Handler = NULL;
  430                 AcpiGbl_GlobalNotify[i].Context = NULL;
  431 
  432                 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  433 
  434                 /* Make sure all deferred notify tasks are completed */
  435 
  436                 AcpiOsWaitEventsComplete ();
  437             }
  438         }
  439 
  440         return_ACPI_STATUS (AE_OK);
  441     }
  442 
  443     /* All other objects: Are Notifies allowed on this object? */
  444 
  445     if (!AcpiEvIsNotifyObject (Node))
  446     {
  447         return_ACPI_STATUS (AE_TYPE);
  448     }
  449 
  450     /* Must have an existing internal object */
  451 
  452     ObjDesc = AcpiNsGetAttachedObject (Node);
  453     if (!ObjDesc)
  454     {
  455         return_ACPI_STATUS (AE_NOT_EXIST);
  456     }
  457 
  458     /* Internal object exists. Find the handler and remove it */
  459 
  460     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
  461     {
  462         if (HandlerType & (i+1))
  463         {
  464             Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  465             if (ACPI_FAILURE (Status))
  466             {
  467                 return_ACPI_STATUS (Status);
  468             }
  469 
  470             HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
  471             PreviousHandlerObj = NULL;
  472 
  473             /* Attempt to find the handler in the handler list */
  474 
  475             while (HandlerObj &&
  476                   (HandlerObj->Notify.Handler != Handler))
  477             {
  478                 PreviousHandlerObj = HandlerObj;
  479                 HandlerObj = HandlerObj->Notify.Next[i];
  480             }
  481 
  482             if (!HandlerObj)
  483             {
  484                 Status = AE_NOT_EXIST;
  485                 goto UnlockAndExit;
  486             }
  487 
  488             /* Remove the handler object from the list */
  489 
  490             if (PreviousHandlerObj) /* Handler is not at the list head */
  491             {
  492                 PreviousHandlerObj->Notify.Next[i] =
  493                     HandlerObj->Notify.Next[i];
  494             }
  495             else /* Handler is at the list head */
  496             {
  497                 ObjDesc->CommonNotify.NotifyList[i] =
  498                     HandlerObj->Notify.Next[i];
  499             }
  500 
  501             (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  502 
  503             /* Make sure all deferred notify tasks are completed */
  504 
  505             AcpiOsWaitEventsComplete ();
  506             AcpiUtRemoveReference (HandlerObj);
  507         }
  508     }
  509 
  510     return_ACPI_STATUS (Status);
  511 
  512 
  513 UnlockAndExit:
  514     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  515     return_ACPI_STATUS (Status);
  516 }
  517 
  518 ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler)
  519 
  520 
  521 /*******************************************************************************
  522  *
  523  * FUNCTION:    AcpiInstallExceptionHandler
  524  *
  525  * PARAMETERS:  Handler         - Pointer to the handler function for the
  526  *                                event
  527  *
  528  * RETURN:      Status
  529  *
  530  * DESCRIPTION: Saves the pointer to the handler function
  531  *
  532  ******************************************************************************/
  533 
  534 ACPI_STATUS
  535 AcpiInstallExceptionHandler (
  536     ACPI_EXCEPTION_HANDLER  Handler)
  537 {
  538     ACPI_STATUS             Status;
  539 
  540 
  541     ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler);
  542 
  543 
  544     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
  545     if (ACPI_FAILURE (Status))
  546     {
  547         return_ACPI_STATUS (Status);
  548     }
  549 
  550     /* Don't allow two handlers. */
  551 
  552     if (AcpiGbl_ExceptionHandler)
  553     {
  554         Status = AE_ALREADY_EXISTS;
  555         goto Cleanup;
  556     }
  557 
  558     /* Install the handler */
  559 
  560     AcpiGbl_ExceptionHandler = Handler;
  561 
  562 Cleanup:
  563     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
  564     return_ACPI_STATUS (Status);
  565 }
  566 
  567 ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler)
  568 
  569 
  570 #if (!ACPI_REDUCED_HARDWARE)
  571 /*******************************************************************************
  572  *
  573  * FUNCTION:    AcpiInstallSciHandler
  574  *
  575  * PARAMETERS:  Address             - Address of the handler
  576  *              Context             - Value passed to the handler on each SCI
  577  *
  578  * RETURN:      Status
  579  *
  580  * DESCRIPTION: Install a handler for a System Control Interrupt.
  581  *
  582  ******************************************************************************/
  583 
  584 ACPI_STATUS
  585 AcpiInstallSciHandler (
  586     ACPI_SCI_HANDLER        Address,
  587     void                    *Context)
  588 {
  589     ACPI_SCI_HANDLER_INFO   *NewSciHandler;
  590     ACPI_SCI_HANDLER_INFO   *SciHandler;
  591     ACPI_CPU_FLAGS          Flags;
  592     ACPI_STATUS             Status;
  593 
  594 
  595     ACPI_FUNCTION_TRACE (AcpiInstallSciHandler);
  596 
  597 
  598     if (!Address)
  599     {
  600         return_ACPI_STATUS (AE_BAD_PARAMETER);
  601     }
  602 
  603     /* Allocate and init a handler object */
  604 
  605     NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO));
  606     if (!NewSciHandler)
  607     {
  608         return_ACPI_STATUS (AE_NO_MEMORY);
  609     }
  610 
  611     NewSciHandler->Address = Address;
  612     NewSciHandler->Context = Context;
  613 
  614     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
  615     if (ACPI_FAILURE (Status))
  616     {
  617         goto Exit;
  618     }
  619 
  620     /* Lock list during installation */
  621 
  622     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
  623     SciHandler = AcpiGbl_SciHandlerList;
  624 
  625     /* Ensure handler does not already exist */
  626 
  627     while (SciHandler)
  628     {
  629         if (Address == SciHandler->Address)
  630         {
  631             Status = AE_ALREADY_EXISTS;
  632             goto UnlockAndExit;
  633         }
  634 
  635         SciHandler = SciHandler->Next;
  636     }
  637 
  638     /* Install the new handler into the global list (at head) */
  639 
  640     NewSciHandler->Next = AcpiGbl_SciHandlerList;
  641     AcpiGbl_SciHandlerList = NewSciHandler;
  642 
  643 
  644 UnlockAndExit:
  645 
  646     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  647     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
  648 
  649 Exit:
  650     if (ACPI_FAILURE (Status))
  651     {
  652         ACPI_FREE (NewSciHandler);
  653     }
  654     return_ACPI_STATUS (Status);
  655 }
  656 
  657 ACPI_EXPORT_SYMBOL (AcpiInstallSciHandler)
  658 
  659 
  660 /*******************************************************************************
  661  *
  662  * FUNCTION:    AcpiRemoveSciHandler
  663  *
  664  * PARAMETERS:  Address             - Address of the handler
  665  *
  666  * RETURN:      Status
  667  *
  668  * DESCRIPTION: Remove a handler for a System Control Interrupt.
  669  *
  670  ******************************************************************************/
  671 
  672 ACPI_STATUS
  673 AcpiRemoveSciHandler (
  674     ACPI_SCI_HANDLER        Address)
  675 {
  676     ACPI_SCI_HANDLER_INFO   *PrevSciHandler;
  677     ACPI_SCI_HANDLER_INFO   *NextSciHandler;
  678     ACPI_CPU_FLAGS          Flags;
  679     ACPI_STATUS             Status;
  680 
  681 
  682     ACPI_FUNCTION_TRACE (AcpiRemoveSciHandler);
  683 
  684 
  685     if (!Address)
  686     {
  687         return_ACPI_STATUS (AE_BAD_PARAMETER);
  688     }
  689 
  690     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
  691     if (ACPI_FAILURE (Status))
  692     {
  693         return_ACPI_STATUS (Status);
  694     }
  695 
  696     /* Remove the SCI handler with lock */
  697 
  698     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
  699 
  700     PrevSciHandler = NULL;
  701     NextSciHandler = AcpiGbl_SciHandlerList;
  702     while (NextSciHandler)
  703     {
  704         if (NextSciHandler->Address == Address)
  705         {
  706             /* Unlink and free the SCI handler info block */
  707 
  708             if (PrevSciHandler)
  709             {
  710                 PrevSciHandler->Next = NextSciHandler->Next;
  711             }
  712             else
  713             {
  714                 AcpiGbl_SciHandlerList = NextSciHandler->Next;
  715             }
  716 
  717             AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  718             ACPI_FREE (NextSciHandler);
  719             goto UnlockAndExit;
  720         }
  721 
  722         PrevSciHandler = NextSciHandler;
  723         NextSciHandler = NextSciHandler->Next;
  724     }
  725 
  726     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  727     Status = AE_NOT_EXIST;
  728 
  729 
  730 UnlockAndExit:
  731     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
  732     return_ACPI_STATUS (Status);
  733 }
  734 
  735 ACPI_EXPORT_SYMBOL (AcpiRemoveSciHandler)
  736 
  737 
  738 /*******************************************************************************
  739  *
  740  * FUNCTION:    AcpiInstallGlobalEventHandler
  741  *
  742  * PARAMETERS:  Handler         - Pointer to the global event handler function
  743  *              Context         - Value passed to the handler on each event
  744  *
  745  * RETURN:      Status
  746  *
  747  * DESCRIPTION: Saves the pointer to the handler function. The global handler
  748  *              is invoked upon each incoming GPE and Fixed Event. It is
  749  *              invoked at interrupt level at the time of the event dispatch.
  750  *              Can be used to update event counters, etc.
  751  *
  752  ******************************************************************************/
  753 
  754 ACPI_STATUS
  755 AcpiInstallGlobalEventHandler (
  756     ACPI_GBL_EVENT_HANDLER  Handler,
  757     void                    *Context)
  758 {
  759     ACPI_STATUS             Status;
  760 
  761 
  762     ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler);
  763 
  764 
  765     /* Parameter validation */
  766 
  767     if (!Handler)
  768     {
  769         return_ACPI_STATUS (AE_BAD_PARAMETER);
  770     }
  771 
  772     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
  773     if (ACPI_FAILURE (Status))
  774     {
  775         return_ACPI_STATUS (Status);
  776     }
  777 
  778     /* Don't allow two handlers. */
  779 
  780     if (AcpiGbl_GlobalEventHandler)
  781     {
  782         Status = AE_ALREADY_EXISTS;
  783         goto Cleanup;
  784     }
  785 
  786     AcpiGbl_GlobalEventHandler = Handler;
  787     AcpiGbl_GlobalEventHandlerContext = Context;
  788 
  789 
  790 Cleanup:
  791     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
  792     return_ACPI_STATUS (Status);
  793 }
  794 
  795 ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler)
  796 
  797 
  798 /*******************************************************************************
  799  *
  800  * FUNCTION:    AcpiInstallFixedEventHandler
  801  *
  802  * PARAMETERS:  Event           - Event type to enable.
  803  *              Handler         - Pointer to the handler function for the
  804  *                                event
  805  *              Context         - Value passed to the handler on each GPE
  806  *
  807  * RETURN:      Status
  808  *
  809  * DESCRIPTION: Saves the pointer to the handler function and then enables the
  810  *              event.
  811  *
  812  ******************************************************************************/
  813 
  814 ACPI_STATUS
  815 AcpiInstallFixedEventHandler (
  816     UINT32                  Event,
  817     ACPI_EVENT_HANDLER      Handler,
  818     void                    *Context)
  819 {
  820     ACPI_STATUS             Status;
  821 
  822 
  823     ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler);
  824 
  825 
  826     /* Parameter validation */
  827 
  828     if (Event > ACPI_EVENT_MAX)
  829     {
  830         return_ACPI_STATUS (AE_BAD_PARAMETER);
  831     }
  832 
  833     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
  834     if (ACPI_FAILURE (Status))
  835     {
  836         return_ACPI_STATUS (Status);
  837     }
  838 
  839     /* Do not allow multiple handlers */
  840 
  841     if (AcpiGbl_FixedEventHandlers[Event].Handler)
  842     {
  843         Status = AE_ALREADY_EXISTS;
  844         goto Cleanup;
  845     }
  846 
  847     /* Install the handler before enabling the event */
  848 
  849     AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
  850     AcpiGbl_FixedEventHandlers[Event].Context = Context;
  851 
  852     Status = AcpiEnableEvent (Event, 0);
  853     if (ACPI_FAILURE (Status))
  854     {
  855         ACPI_WARNING ((AE_INFO,
  856             "Could not enable fixed event - %s (%u)",
  857             AcpiUtGetEventName (Event), Event));
  858 
  859         /* Remove the handler */
  860 
  861         AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
  862         AcpiGbl_FixedEventHandlers[Event].Context = NULL;
  863     }
  864     else
  865     {
  866         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  867             "Enabled fixed event %s (%X), Handler=%p\n",
  868             AcpiUtGetEventName (Event), Event, Handler));
  869     }
  870 
  871 
  872 Cleanup:
  873     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
  874     return_ACPI_STATUS (Status);
  875 }
  876 
  877 ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler)
  878 
  879 
  880 /*******************************************************************************
  881  *
  882  * FUNCTION:    AcpiRemoveFixedEventHandler
  883  *
  884  * PARAMETERS:  Event           - Event type to disable.
  885  *              Handler         - Address of the handler
  886  *
  887  * RETURN:      Status
  888  *
  889  * DESCRIPTION: Disables the event and unregisters the event handler.
  890  *
  891  ******************************************************************************/
  892 
  893 ACPI_STATUS
  894 AcpiRemoveFixedEventHandler (
  895     UINT32                  Event,
  896     ACPI_EVENT_HANDLER      Handler)
  897 {
  898     ACPI_STATUS             Status = AE_OK;
  899 
  900 
  901     ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler);
  902 
  903 
  904     /* Parameter validation */
  905 
  906     if (Event > ACPI_EVENT_MAX)
  907     {
  908         return_ACPI_STATUS (AE_BAD_PARAMETER);
  909     }
  910 
  911     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
  912     if (ACPI_FAILURE (Status))
  913     {
  914         return_ACPI_STATUS (Status);
  915     }
  916 
  917     /* Disable the event before removing the handler */
  918 
  919     Status = AcpiDisableEvent (Event, 0);
  920 
  921     /* Always Remove the handler */
  922 
  923     AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
  924     AcpiGbl_FixedEventHandlers[Event].Context = NULL;
  925 
  926     if (ACPI_FAILURE (Status))
  927     {
  928         ACPI_WARNING ((AE_INFO,
  929             "Could not disable fixed event - %s (%u)",
  930             AcpiUtGetEventName (Event), Event));
  931     }
  932     else
  933     {
  934         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  935             "Disabled fixed event - %s (%X)\n",
  936             AcpiUtGetEventName (Event), Event));
  937     }
  938 
  939     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
  940     return_ACPI_STATUS (Status);
  941 }
  942 
  943 ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler)
  944 
  945 
  946 /*******************************************************************************
  947  *
  948  * FUNCTION:    AcpiEvInstallGpeHandler
  949  *
  950  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
  951  *                                defined GPEs)
  952  *              GpeNumber       - The GPE number within the GPE block
  953  *              Type            - Whether this GPE should be treated as an
  954  *                                edge- or level-triggered interrupt.
  955  *              IsRawHandler    - Whether this GPE should be handled using
  956  *                                the special GPE handler mode.
  957  *              Address         - Address of the handler
  958  *              Context         - Value passed to the handler on each GPE
  959  *
  960  * RETURN:      Status
  961  *
  962  * DESCRIPTION: Internal function to install a handler for a General Purpose
  963  *              Event.
  964  *
  965  ******************************************************************************/
  966 
  967 static ACPI_STATUS
  968 AcpiEvInstallGpeHandler (
  969     ACPI_HANDLE             GpeDevice,
  970     UINT32                  GpeNumber,
  971     UINT32                  Type,
  972     BOOLEAN                 IsRawHandler,
  973     ACPI_GPE_HANDLER        Address,
  974     void                    *Context)
  975 {
  976     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
  977     ACPI_GPE_HANDLER_INFO   *Handler;
  978     ACPI_STATUS             Status;
  979     ACPI_CPU_FLAGS          Flags;
  980 
  981 
  982     ACPI_FUNCTION_TRACE (EvInstallGpeHandler);
  983 
  984 
  985     /* Parameter validation */
  986 
  987     if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK))
  988     {
  989         return_ACPI_STATUS (AE_BAD_PARAMETER);
  990     }
  991 
  992     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
  993     if (ACPI_FAILURE (Status))
  994     {
  995         return_ACPI_STATUS (Status);
  996     }
  997 
  998     /* Allocate and init handler object (before lock) */
  999 
 1000     Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO));
 1001     if (!Handler)
 1002     {
 1003         Status = AE_NO_MEMORY;
 1004         goto UnlockAndExit;
 1005     }
 1006 
 1007     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
 1008 
 1009     /* Ensure that we have a valid GPE number */
 1010 
 1011     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
 1012     if (!GpeEventInfo)
 1013     {
 1014         Status = AE_BAD_PARAMETER;
 1015         goto FreeAndExit;
 1016     }
 1017 
 1018     /* Make sure that there isn't a handler there already */
 1019 
 1020     if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
 1021             ACPI_GPE_DISPATCH_HANDLER) ||
 1022         (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
 1023             ACPI_GPE_DISPATCH_RAW_HANDLER))
 1024     {
 1025         Status = AE_ALREADY_EXISTS;
 1026         goto FreeAndExit;
 1027     }
 1028 
 1029     Handler->Address = Address;
 1030     Handler->Context = Context;
 1031     Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;
 1032     Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags &
 1033         (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK));
 1034 
 1035     /*
 1036      * If the GPE is associated with a method, it may have been enabled
 1037      * automatically during initialization, in which case it has to be
 1038      * disabled now to avoid spurious execution of the handler.
 1039      */
 1040     if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
 1041             ACPI_GPE_DISPATCH_METHOD) ||
 1042          (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
 1043             ACPI_GPE_DISPATCH_NOTIFY)) &&
 1044         GpeEventInfo->RuntimeCount)
 1045     {
 1046         Handler->OriginallyEnabled = TRUE;
 1047         (void) AcpiEvRemoveGpeReference (GpeEventInfo);
 1048 
 1049         /* Sanity check of original type against new type */
 1050 
 1051         if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK))
 1052         {
 1053             ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)"));
 1054         }
 1055     }
 1056 
 1057     /* Install the handler */
 1058 
 1059     GpeEventInfo->Dispatch.Handler = Handler;
 1060 
 1061     /* Setup up dispatch flags to indicate handler (vs. method/notify) */
 1062 
 1063     GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
 1064     GpeEventInfo->Flags |= (UINT8) (Type | (IsRawHandler ?
 1065         ACPI_GPE_DISPATCH_RAW_HANDLER : ACPI_GPE_DISPATCH_HANDLER));
 1066 
 1067     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
 1068 
 1069 
 1070 UnlockAndExit:
 1071     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
 1072     return_ACPI_STATUS (Status);
 1073 
 1074 FreeAndExit:
 1075     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
 1076     ACPI_FREE (Handler);
 1077     goto UnlockAndExit;
 1078 }
 1079 
 1080 
 1081 /*******************************************************************************
 1082  *
 1083  * FUNCTION:    AcpiInstallGpeHandler
 1084  *
 1085  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
 1086  *                                defined GPEs)
 1087  *              GpeNumber       - The GPE number within the GPE block
 1088  *              Type            - Whether this GPE should be treated as an
 1089  *                                edge- or level-triggered interrupt.
 1090  *              Address         - Address of the handler
 1091  *              Context         - Value passed to the handler on each GPE
 1092  *
 1093  * RETURN:      Status
 1094  *
 1095  * DESCRIPTION: Install a handler for a General Purpose Event.
 1096  *
 1097  ******************************************************************************/
 1098 
 1099 ACPI_STATUS
 1100 AcpiInstallGpeHandler (
 1101     ACPI_HANDLE             GpeDevice,
 1102     UINT32                  GpeNumber,
 1103     UINT32                  Type,
 1104     ACPI_GPE_HANDLER        Address,
 1105     void                    *Context)
 1106 {
 1107     ACPI_STATUS             Status;
 1108 
 1109 
 1110     ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler);
 1111 
 1112 
 1113     Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type,
 1114         FALSE, Address, Context);
 1115 
 1116     return_ACPI_STATUS (Status);
 1117 }
 1118 
 1119 ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler)
 1120 
 1121 
 1122 /*******************************************************************************
 1123  *
 1124  * FUNCTION:    AcpiInstallGpeRawHandler
 1125  *
 1126  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
 1127  *                                defined GPEs)
 1128  *              GpeNumber       - The GPE number within the GPE block
 1129  *              Type            - Whether this GPE should be treated as an
 1130  *                                edge- or level-triggered interrupt.
 1131  *              Address         - Address of the handler
 1132  *              Context         - Value passed to the handler on each GPE
 1133  *
 1134  * RETURN:      Status
 1135  *
 1136  * DESCRIPTION: Install a handler for a General Purpose Event.
 1137  *
 1138  ******************************************************************************/
 1139 
 1140 ACPI_STATUS
 1141 AcpiInstallGpeRawHandler (
 1142     ACPI_HANDLE             GpeDevice,
 1143     UINT32                  GpeNumber,
 1144     UINT32                  Type,
 1145     ACPI_GPE_HANDLER        Address,
 1146     void                    *Context)
 1147 {
 1148     ACPI_STATUS             Status;
 1149 
 1150 
 1151     ACPI_FUNCTION_TRACE (AcpiInstallGpeRawHandler);
 1152 
 1153 
 1154     Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type,
 1155         TRUE, Address, Context);
 1156 
 1157     return_ACPI_STATUS (Status);
 1158 }
 1159 
 1160 ACPI_EXPORT_SYMBOL (AcpiInstallGpeRawHandler)
 1161 
 1162 
 1163 /*******************************************************************************
 1164  *
 1165  * FUNCTION:    AcpiRemoveGpeHandler
 1166  *
 1167  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
 1168  *                                defined GPEs)
 1169  *              GpeNumber       - The event to remove a handler
 1170  *              Address         - Address of the handler
 1171  *
 1172  * RETURN:      Status
 1173  *
 1174  * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
 1175  *
 1176  ******************************************************************************/
 1177 
 1178 ACPI_STATUS
 1179 AcpiRemoveGpeHandler (
 1180     ACPI_HANDLE             GpeDevice,
 1181     UINT32                  GpeNumber,
 1182     ACPI_GPE_HANDLER        Address)
 1183 {
 1184     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
 1185     ACPI_GPE_HANDLER_INFO   *Handler;
 1186     ACPI_STATUS             Status;
 1187     ACPI_CPU_FLAGS          Flags;
 1188 
 1189 
 1190     ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler);
 1191 
 1192 
 1193     /* Parameter validation */
 1194 
 1195     if (!Address)
 1196     {
 1197         return_ACPI_STATUS (AE_BAD_PARAMETER);
 1198     }
 1199 
 1200     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
 1201     if (ACPI_FAILURE (Status))
 1202     {
 1203         return_ACPI_STATUS (Status);
 1204     }
 1205 
 1206     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
 1207 
 1208     /* Ensure that we have a valid GPE number */
 1209 
 1210     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
 1211     if (!GpeEventInfo)
 1212     {
 1213         Status = AE_BAD_PARAMETER;
 1214         goto UnlockAndExit;
 1215     }
 1216 
 1217     /* Make sure that a handler is indeed installed */
 1218 
 1219     if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
 1220             ACPI_GPE_DISPATCH_HANDLER) &&
 1221         (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
 1222             ACPI_GPE_DISPATCH_RAW_HANDLER))
 1223     {
 1224         Status = AE_NOT_EXIST;
 1225         goto UnlockAndExit;
 1226     }
 1227 
 1228     /* Make sure that the installed handler is the same */
 1229 
 1230     if (GpeEventInfo->Dispatch.Handler->Address != Address)
 1231     {
 1232         Status = AE_BAD_PARAMETER;
 1233         goto UnlockAndExit;
 1234     }
 1235 
 1236     /* Remove the handler */
 1237 
 1238     Handler = GpeEventInfo->Dispatch.Handler;
 1239     GpeEventInfo->Dispatch.Handler = NULL;
 1240 
 1241     /* Restore Method node (if any), set dispatch flags */
 1242 
 1243     GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode;
 1244     GpeEventInfo->Flags &=
 1245         ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
 1246     GpeEventInfo->Flags |= Handler->OriginalFlags;
 1247 
 1248     /*
 1249      * If the GPE was previously associated with a method and it was
 1250      * enabled, it should be enabled at this point to restore the
 1251      * post-initialization configuration.
 1252      */
 1253     if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
 1254             ACPI_GPE_DISPATCH_METHOD) ||
 1255          (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
 1256             ACPI_GPE_DISPATCH_NOTIFY)) &&
 1257         Handler->OriginallyEnabled)
 1258     {
 1259         (void) AcpiEvAddGpeReference (GpeEventInfo, FALSE);
 1260         if (ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo))
 1261         {
 1262             /* Poll edge triggered GPEs to handle existing events */
 1263 
 1264             AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
 1265             (void) AcpiEvDetectGpe (
 1266                 GpeDevice, GpeEventInfo, GpeNumber);
 1267             Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
 1268         }
 1269     }
 1270 
 1271     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
 1272     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
 1273 
 1274     /* Make sure all deferred GPE tasks are completed */
 1275 
 1276     AcpiOsWaitEventsComplete ();
 1277 
 1278     /* Now we can free the handler object */
 1279 
 1280     ACPI_FREE (Handler);
 1281     return_ACPI_STATUS (Status);
 1282 
 1283 UnlockAndExit:
 1284     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
 1285     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
 1286     return_ACPI_STATUS (Status);
 1287 }
 1288 
 1289 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler)
 1290 
 1291 
 1292 /*******************************************************************************
 1293  *
 1294  * FUNCTION:    AcpiAcquireGlobalLock
 1295  *
 1296  * PARAMETERS:  Timeout         - How long the caller is willing to wait
 1297  *              Handle          - Where the handle to the lock is returned
 1298  *                                (if acquired)
 1299  *
 1300  * RETURN:      Status
 1301  *
 1302  * DESCRIPTION: Acquire the ACPI Global Lock
 1303  *
 1304  * Note: Allows callers with the same thread ID to acquire the global lock
 1305  * multiple times. In other words, externally, the behavior of the global lock
 1306  * is identical to an AML mutex. On the first acquire, a new handle is
 1307  * returned. On any subsequent calls to acquire by the same thread, the same
 1308  * handle is returned.
 1309  *
 1310  ******************************************************************************/
 1311 
 1312 ACPI_STATUS
 1313 AcpiAcquireGlobalLock (
 1314     UINT16                  Timeout,
 1315     UINT32                  *Handle)
 1316 {
 1317     ACPI_STATUS             Status;
 1318 
 1319 
 1320     if (!Handle)
 1321     {
 1322         return (AE_BAD_PARAMETER);
 1323     }
 1324 
 1325     /* Must lock interpreter to prevent race conditions */
 1326 
 1327     AcpiExEnterInterpreter ();
 1328 
 1329     Status = AcpiExAcquireMutexObject (Timeout,
 1330         AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ());
 1331 
 1332     if (ACPI_SUCCESS (Status))
 1333     {
 1334         /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */
 1335 
 1336         *Handle = AcpiGbl_GlobalLockHandle;
 1337     }
 1338 
 1339     AcpiExExitInterpreter ();
 1340     return (Status);
 1341 }
 1342 
 1343 ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock)
 1344 
 1345 
 1346 /*******************************************************************************
 1347  *
 1348  * FUNCTION:    AcpiReleaseGlobalLock
 1349  *
 1350  * PARAMETERS:  Handle      - Returned from AcpiAcquireGlobalLock
 1351  *
 1352  * RETURN:      Status
 1353  *
 1354  * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
 1355  *
 1356  ******************************************************************************/
 1357 
 1358 ACPI_STATUS
 1359 AcpiReleaseGlobalLock (
 1360     UINT32                  Handle)
 1361 {
 1362     ACPI_STATUS             Status;
 1363 
 1364 
 1365     if (!Handle || (Handle != AcpiGbl_GlobalLockHandle))
 1366     {
 1367         return (AE_NOT_ACQUIRED);
 1368     }
 1369 
 1370     Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex);
 1371     return (Status);
 1372 }
 1373 
 1374 ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock)
 1375 
 1376 #endif /* !ACPI_REDUCED_HARDWARE */

Cache object: d5f0c367907474ab6ec61274bf6b228e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.