Home | History | Annotate | Line # | Download | only in events
evmisc.c revision 1.1.1.5
      1 /******************************************************************************
      2  *
      3  * Module Name: evmisc - Miscellaneous event manager support functions
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2014, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "acpi.h"
     45 #include "accommon.h"
     46 #include "acevents.h"
     47 #include "acnamesp.h"
     48 
     49 #define _COMPONENT          ACPI_EVENTS
     50         ACPI_MODULE_NAME    ("evmisc")
     51 
     52 
     53 /* Local prototypes */
     54 
     55 static void ACPI_SYSTEM_XFACE
     56 AcpiEvNotifyDispatch (
     57     void                    *Context);
     58 
     59 
     60 /*******************************************************************************
     61  *
     62  * FUNCTION:    AcpiEvIsNotifyObject
     63  *
     64  * PARAMETERS:  Node            - Node to check
     65  *
     66  * RETURN:      TRUE if notifies allowed on this object
     67  *
     68  * DESCRIPTION: Check type of node for a object that supports notifies.
     69  *
     70  *              TBD: This could be replaced by a flag bit in the node.
     71  *
     72  ******************************************************************************/
     73 
     74 BOOLEAN
     75 AcpiEvIsNotifyObject (
     76     ACPI_NAMESPACE_NODE     *Node)
     77 {
     78     switch (Node->Type)
     79     {
     80     case ACPI_TYPE_DEVICE:
     81     case ACPI_TYPE_PROCESSOR:
     82     case ACPI_TYPE_THERMAL:
     83         /*
     84          * These are the ONLY objects that can receive ACPI notifications
     85          */
     86         return (TRUE);
     87 
     88     default:
     89 
     90         return (FALSE);
     91     }
     92 }
     93 
     94 
     95 /*******************************************************************************
     96  *
     97  * FUNCTION:    AcpiEvQueueNotifyRequest
     98  *
     99  * PARAMETERS:  Node            - NS node for the notified object
    100  *              NotifyValue     - Value from the Notify() request
    101  *
    102  * RETURN:      Status
    103  *
    104  * DESCRIPTION: Dispatch a device notification event to a previously
    105  *              installed handler.
    106  *
    107  ******************************************************************************/
    108 
    109 ACPI_STATUS
    110 AcpiEvQueueNotifyRequest (
    111     ACPI_NAMESPACE_NODE     *Node,
    112     UINT32                  NotifyValue)
    113 {
    114     ACPI_OPERAND_OBJECT     *ObjDesc;
    115     ACPI_OPERAND_OBJECT     *HandlerListHead = NULL;
    116     ACPI_GENERIC_STATE      *Info;
    117     UINT8                   HandlerListId = 0;
    118     ACPI_STATUS             Status = AE_OK;
    119 
    120 
    121     ACPI_FUNCTION_NAME (EvQueueNotifyRequest);
    122 
    123 
    124     /* Are Notifies allowed on this object? */
    125 
    126     if (!AcpiEvIsNotifyObject (Node))
    127     {
    128         return (AE_TYPE);
    129     }
    130 
    131     /* Get the correct notify list type (System or Device) */
    132 
    133     if (NotifyValue <= ACPI_MAX_SYS_NOTIFY)
    134     {
    135         HandlerListId = ACPI_SYSTEM_HANDLER_LIST;
    136     }
    137     else
    138     {
    139         HandlerListId = ACPI_DEVICE_HANDLER_LIST;
    140     }
    141 
    142     /* Get the notify object attached to the namespace Node */
    143 
    144     ObjDesc = AcpiNsGetAttachedObject (Node);
    145     if (ObjDesc)
    146     {
    147         /* We have an attached object, Get the correct handler list */
    148 
    149         HandlerListHead = ObjDesc->CommonNotify.NotifyList[HandlerListId];
    150     }
    151 
    152     /*
    153      * If there is no notify handler (Global or Local)
    154      * for this object, just ignore the notify
    155      */
    156     if (!AcpiGbl_GlobalNotify[HandlerListId].Handler && !HandlerListHead)
    157     {
    158         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    159             "No notify handler for Notify, ignoring (%4.4s, %X) node %p\n",
    160             AcpiUtGetNodeName (Node), NotifyValue, Node));
    161 
    162         return (AE_OK);
    163     }
    164 
    165     /* Setup notify info and schedule the notify dispatcher */
    166 
    167     Info = AcpiUtCreateGenericState ();
    168     if (!Info)
    169     {
    170         return (AE_NO_MEMORY);
    171     }
    172 
    173     Info->Common.DescriptorType = ACPI_DESC_TYPE_STATE_NOTIFY;
    174 
    175     Info->Notify.Node = Node;
    176     Info->Notify.Value = (UINT16) NotifyValue;
    177     Info->Notify.HandlerListId = HandlerListId;
    178     Info->Notify.HandlerListHead = HandlerListHead;
    179     Info->Notify.Global = &AcpiGbl_GlobalNotify[HandlerListId];
    180 
    181     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    182         "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n",
    183         AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type),
    184         NotifyValue, AcpiUtGetNotifyName (NotifyValue, ACPI_TYPE_ANY), Node));
    185 
    186     Status = AcpiOsExecute (OSL_NOTIFY_HANDLER, AcpiEvNotifyDispatch,
    187         Info);
    188     if (ACPI_FAILURE (Status))
    189     {
    190         AcpiUtDeleteGenericState (Info);
    191     }
    192 
    193     return (Status);
    194 }
    195 
    196 
    197 /*******************************************************************************
    198  *
    199  * FUNCTION:    AcpiEvNotifyDispatch
    200  *
    201  * PARAMETERS:  Context         - To be passed to the notify handler
    202  *
    203  * RETURN:      None.
    204  *
    205  * DESCRIPTION: Dispatch a device notification event to a previously
    206  *              installed handler.
    207  *
    208  ******************************************************************************/
    209 
    210 static void ACPI_SYSTEM_XFACE
    211 AcpiEvNotifyDispatch (
    212     void                    *Context)
    213 {
    214     ACPI_GENERIC_STATE      *Info = (ACPI_GENERIC_STATE *) Context;
    215     ACPI_OPERAND_OBJECT     *HandlerObj;
    216 
    217 
    218     ACPI_FUNCTION_ENTRY ();
    219 
    220 
    221     /* Invoke a global notify handler if installed */
    222 
    223     if (Info->Notify.Global->Handler)
    224     {
    225         Info->Notify.Global->Handler (Info->Notify.Node,
    226             Info->Notify.Value,
    227             Info->Notify.Global->Context);
    228     }
    229 
    230     /* Now invoke the local notify handler(s) if any are installed */
    231 
    232     HandlerObj = Info->Notify.HandlerListHead;
    233     while (HandlerObj)
    234     {
    235         HandlerObj->Notify.Handler (Info->Notify.Node,
    236             Info->Notify.Value,
    237             HandlerObj->Notify.Context);
    238 
    239         HandlerObj = HandlerObj->Notify.Next[Info->Notify.HandlerListId];
    240     }
    241 
    242     /* All done with the info object */
    243 
    244     AcpiUtDeleteGenericState (Info);
    245 }
    246 
    247 
    248 #if (!ACPI_REDUCED_HARDWARE)
    249 /******************************************************************************
    250  *
    251  * FUNCTION:    AcpiEvTerminate
    252  *
    253  * PARAMETERS:  none
    254  *
    255  * RETURN:      none
    256  *
    257  * DESCRIPTION: Disable events and free memory allocated for table storage.
    258  *
    259  ******************************************************************************/
    260 
    261 void
    262 AcpiEvTerminate (
    263     void)
    264 {
    265     UINT32                  i;
    266     ACPI_STATUS             Status;
    267 
    268 
    269     ACPI_FUNCTION_TRACE (EvTerminate);
    270 
    271 
    272     if (AcpiGbl_EventsInitialized)
    273     {
    274         /*
    275          * Disable all event-related functionality. In all cases, on error,
    276          * print a message but obviously we don't abort.
    277          */
    278 
    279         /* Disable all fixed events */
    280 
    281         for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++)
    282         {
    283             Status = AcpiDisableEvent (i, 0);
    284             if (ACPI_FAILURE (Status))
    285             {
    286                 ACPI_ERROR ((AE_INFO,
    287                     "Could not disable fixed event %u", (UINT32) i));
    288             }
    289         }
    290 
    291         /* Disable all GPEs in all GPE blocks */
    292 
    293         Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock, NULL);
    294 
    295         Status = AcpiEvRemoveGlobalLockHandler ();
    296         if (ACPI_FAILURE(Status))
    297         {
    298             ACPI_ERROR ((AE_INFO,
    299                 "Could not remove Global Lock handler"));
    300         }
    301 
    302         AcpiGbl_EventsInitialized = FALSE;
    303     }
    304 
    305     /* Remove SCI handlers */
    306 
    307     Status = AcpiEvRemoveAllSciHandlers ();
    308     if (ACPI_FAILURE(Status))
    309     {
    310         ACPI_ERROR ((AE_INFO,
    311             "Could not remove SCI handler"));
    312     }
    313 
    314     /* Deallocate all handler objects installed within GPE info structs */
    315 
    316     Status = AcpiEvWalkGpeList (AcpiEvDeleteGpeHandlers, NULL);
    317 
    318     /* Return to original mode if necessary */
    319 
    320     if (AcpiGbl_OriginalMode == ACPI_SYS_MODE_LEGACY)
    321     {
    322         Status = AcpiDisable ();
    323         if (ACPI_FAILURE (Status))
    324         {
    325             ACPI_WARNING ((AE_INFO, "AcpiDisable failed"));
    326         }
    327     }
    328     return_VOID;
    329 }
    330 
    331 #endif /* !ACPI_REDUCED_HARDWARE */
    332