evmisc.c revision 298714
1169695Skan/****************************************************************************** 2169695Skan * 3169695Skan * Module Name: evmisc - Miscellaneous event manager support functions 4169695Skan * 5169695Skan *****************************************************************************/ 6169695Skan 7169695Skan/* 8169695Skan * Copyright (C) 2000 - 2016, Intel Corp. 9169695Skan * All rights reserved. 10169695Skan * 11169695Skan * Redistribution and use in source and binary forms, with or without 12169695Skan * modification, are permitted provided that the following conditions 13169695Skan * are met: 14169695Skan * 1. Redistributions of source code must retain the above copyright 15169695Skan * notice, this list of conditions, and the following disclaimer, 16169695Skan * without modification. 17169695Skan * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18169695Skan * substantially similar to the "NO WARRANTY" disclaimer below 19169695Skan * ("Disclaimer") and any redistribution must be conditioned upon 20169695Skan * including a substantially similar Disclaimer requirement for further 21169695Skan * binary redistribution. 22169695Skan * 3. Neither the names of the above-listed copyright holders nor the names 23169695Skan * of any contributors may be used to endorse or promote products derived 24169695Skan * from this software without specific prior written permission. 25169695Skan * 26169695Skan * Alternatively, this software may be distributed under the terms of the 27169695Skan * GNU General Public License ("GPL") version 2 as published by the Free 28169695Skan * Software Foundation. 29169695Skan * 30169695Skan * NO WARRANTY 31169695Skan * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32169695Skan * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33169695Skan * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34169695Skan * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35169695Skan * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36169695Skan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37169695Skan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38169695Skan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39169695Skan * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40169695Skan * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41169695Skan * POSSIBILITY OF SUCH DAMAGES. 42169695Skan */ 43169695Skan 44169695Skan#include <contrib/dev/acpica/include/acpi.h> 45169695Skan#include <contrib/dev/acpica/include/accommon.h> 46169695Skan#include <contrib/dev/acpica/include/acevents.h> 47169695Skan#include <contrib/dev/acpica/include/acnamesp.h> 48169695Skan 49169695Skan#define _COMPONENT ACPI_EVENTS 50169695Skan ACPI_MODULE_NAME ("evmisc") 51169695Skan 52169695Skan 53169695Skan/* Local prototypes */ 54169695Skan 55169695Skanstatic void ACPI_SYSTEM_XFACE 56169695SkanAcpiEvNotifyDispatch ( 57169695Skan void *Context); 58169695Skan 59169695Skan 60169695Skan/******************************************************************************* 61169695Skan * 62169695Skan * FUNCTION: AcpiEvIsNotifyObject 63169695Skan * 64169695Skan * PARAMETERS: Node - Node to check 65169695Skan * 66169695Skan * RETURN: TRUE if notifies allowed on this object 67169695Skan * 68169695Skan * DESCRIPTION: Check type of node for a object that supports notifies. 69169695Skan * 70169695Skan * TBD: This could be replaced by a flag bit in the node. 71169695Skan * 72169695Skan ******************************************************************************/ 73169695Skan 74169695SkanBOOLEAN 75169695SkanAcpiEvIsNotifyObject ( 76169695Skan ACPI_NAMESPACE_NODE *Node) 77169695Skan{ 78169695Skan 79169695Skan switch (Node->Type) 80169695Skan { 81169695Skan case ACPI_TYPE_DEVICE: 82169695Skan case ACPI_TYPE_PROCESSOR: 83169695Skan case ACPI_TYPE_THERMAL: 84169695Skan /* 85169695Skan * These are the ONLY objects that can receive ACPI notifications 86169695Skan */ 87169695Skan return (TRUE); 88169695Skan 89169695Skan default: 90169695Skan 91169695Skan return (FALSE); 92169695Skan } 93169695Skan} 94169695Skan 95169695Skan 96169695Skan/******************************************************************************* 97169695Skan * 98169695Skan * FUNCTION: AcpiEvQueueNotifyRequest 99169695Skan * 100169695Skan * PARAMETERS: Node - NS node for the notified object 101169695Skan * NotifyValue - Value from the Notify() request 102169695Skan * 103169695Skan * RETURN: Status 104169695Skan * 105169695Skan * DESCRIPTION: Dispatch a device notification event to a previously 106169695Skan * installed handler. 107169695Skan * 108169695Skan ******************************************************************************/ 109169695Skan 110169695SkanACPI_STATUS 111169695SkanAcpiEvQueueNotifyRequest ( 112169695Skan ACPI_NAMESPACE_NODE *Node, 113169695Skan UINT32 NotifyValue) 114169695Skan{ 115169695Skan ACPI_OPERAND_OBJECT *ObjDesc; 116169695Skan ACPI_OPERAND_OBJECT *HandlerListHead = NULL; 117169695Skan ACPI_GENERIC_STATE *Info; 118169695Skan UINT8 HandlerListId = 0; 119169695Skan ACPI_STATUS Status = AE_OK; 120169695Skan 121169695Skan 122169695Skan ACPI_FUNCTION_NAME (EvQueueNotifyRequest); 123169695Skan 124169695Skan 125169695Skan /* Are Notifies allowed on this object? */ 126169695Skan 127169695Skan if (!AcpiEvIsNotifyObject (Node)) 128169695Skan { 129169695Skan return (AE_TYPE); 130169695Skan } 131169695Skan 132169695Skan /* Get the correct notify list type (System or Device) */ 133169695Skan 134169695Skan if (NotifyValue <= ACPI_MAX_SYS_NOTIFY) 135169695Skan { 136169695Skan HandlerListId = ACPI_SYSTEM_HANDLER_LIST; 137169695Skan } 138169695Skan else 139169695Skan { 140169695Skan HandlerListId = ACPI_DEVICE_HANDLER_LIST; 141169695Skan } 142169695Skan 143169695Skan /* Get the notify object attached to the namespace Node */ 144169695Skan 145169695Skan ObjDesc = AcpiNsGetAttachedObject (Node); 146169695Skan if (ObjDesc) 147169695Skan { 148169695Skan /* We have an attached object, Get the correct handler list */ 149169695Skan 150169695Skan HandlerListHead = ObjDesc->CommonNotify.NotifyList[HandlerListId]; 151169695Skan } 152169695Skan 153169695Skan /* 154169695Skan * If there is no notify handler (Global or Local) 155169695Skan * for this object, just ignore the notify 156169695Skan */ 157169695Skan if (!AcpiGbl_GlobalNotify[HandlerListId].Handler && !HandlerListHead) 158169695Skan { 159169695Skan ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 160169695Skan "No notify handler for Notify, ignoring (%4.4s, %X) node %p\n", 161169695Skan AcpiUtGetNodeName (Node), NotifyValue, Node)); 162169695Skan 163169695Skan return (AE_OK); 164169695Skan } 165169695Skan 166169695Skan /* Setup notify info and schedule the notify dispatcher */ 167169695Skan 168169695Skan Info = AcpiUtCreateGenericState (); 169169695Skan if (!Info) 170169695Skan { 171169695Skan return (AE_NO_MEMORY); 172169695Skan } 173169695Skan 174169695Skan Info->Common.DescriptorType = ACPI_DESC_TYPE_STATE_NOTIFY; 175169695Skan 176169695Skan Info->Notify.Node = Node; 177169695Skan Info->Notify.Value = (UINT16) NotifyValue; 178169695Skan Info->Notify.HandlerListId = HandlerListId; 179169695Skan Info->Notify.HandlerListHead = HandlerListHead; 180169695Skan Info->Notify.Global = &AcpiGbl_GlobalNotify[HandlerListId]; 181169695Skan 182169695Skan ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 183169695Skan "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n", 184169695Skan AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), 185169695Skan NotifyValue, AcpiUtGetNotifyName (NotifyValue, ACPI_TYPE_ANY), Node)); 186169695Skan 187169695Skan Status = AcpiOsExecute (OSL_NOTIFY_HANDLER, 188169695Skan AcpiEvNotifyDispatch, Info); 189169695Skan if (ACPI_FAILURE (Status)) 190169695Skan { 191169695Skan AcpiUtDeleteGenericState (Info); 192169695Skan } 193169695Skan 194169695Skan return (Status); 195169695Skan} 196169695Skan 197169695Skan 198169695Skan/******************************************************************************* 199169695Skan * 200169695Skan * FUNCTION: AcpiEvNotifyDispatch 201169695Skan * 202169695Skan * PARAMETERS: Context - To be passed to the notify handler 203169695Skan * 204169695Skan * RETURN: None. 205169695Skan * 206169695Skan * DESCRIPTION: Dispatch a device notification event to a previously 207169695Skan * installed handler. 208169695Skan * 209169695Skan ******************************************************************************/ 210169695Skan 211169695Skanstatic void ACPI_SYSTEM_XFACE 212169695SkanAcpiEvNotifyDispatch ( 213169695Skan void *Context) 214169695Skan{ 215169695Skan ACPI_GENERIC_STATE *Info = (ACPI_GENERIC_STATE *) Context; 216169695Skan ACPI_OPERAND_OBJECT *HandlerObj; 217169695Skan 218169695Skan 219169695Skan ACPI_FUNCTION_ENTRY (); 220169695Skan 221169695Skan 222169695Skan /* Invoke a global notify handler if installed */ 223169695Skan 224169695Skan if (Info->Notify.Global->Handler) 225169695Skan { 226169695Skan Info->Notify.Global->Handler (Info->Notify.Node, 227169695Skan Info->Notify.Value, 228169695Skan Info->Notify.Global->Context); 229169695Skan } 230169695Skan 231169695Skan /* Now invoke the local notify handler(s) if any are installed */ 232169695Skan 233169695Skan HandlerObj = Info->Notify.HandlerListHead; 234169695Skan while (HandlerObj) 235169695Skan { 236169695Skan HandlerObj->Notify.Handler (Info->Notify.Node, 237169695Skan Info->Notify.Value, 238169695Skan HandlerObj->Notify.Context); 239169695Skan 240169695Skan HandlerObj = HandlerObj->Notify.Next[Info->Notify.HandlerListId]; 241169695Skan } 242169695Skan 243169695Skan /* All done with the info object */ 244169695Skan 245169695Skan AcpiUtDeleteGenericState (Info); 246169695Skan} 247169695Skan 248169695Skan 249169695Skan#if (!ACPI_REDUCED_HARDWARE) 250169695Skan/****************************************************************************** 251169695Skan * 252169695Skan * FUNCTION: AcpiEvTerminate 253169695Skan * 254169695Skan * PARAMETERS: none 255169695Skan * 256169695Skan * RETURN: none 257169695Skan * 258169695Skan * DESCRIPTION: Disable events and free memory allocated for table storage. 259169695Skan * 260169695Skan ******************************************************************************/ 261169695Skan 262169695Skanvoid 263169695SkanAcpiEvTerminate ( 264169695Skan void) 265169695Skan{ 266169695Skan UINT32 i; 267169695Skan ACPI_STATUS Status; 268169695Skan 269169695Skan 270169695Skan ACPI_FUNCTION_TRACE (EvTerminate); 271169695Skan 272169695Skan 273169695Skan if (AcpiGbl_EventsInitialized) 274169695Skan { 275169695Skan /* 276169695Skan * Disable all event-related functionality. In all cases, on error, 277169695Skan * print a message but obviously we don't abort. 278169695Skan */ 279169695Skan 280169695Skan /* Disable all fixed events */ 281169695Skan 282169695Skan for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) 283169695Skan { 284169695Skan Status = AcpiDisableEvent (i, 0); 285169695Skan if (ACPI_FAILURE (Status)) 286169695Skan { 287169695Skan ACPI_ERROR ((AE_INFO, 288169695Skan "Could not disable fixed event %u", (UINT32) i)); 289169695Skan } 290169695Skan } 291169695Skan 292169695Skan /* Disable all GPEs in all GPE blocks */ 293169695Skan 294169695Skan Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock, NULL); 295169695Skan 296169695Skan Status = AcpiEvRemoveGlobalLockHandler (); 297169695Skan if (ACPI_FAILURE(Status)) 298169695Skan { 299169695Skan ACPI_ERROR ((AE_INFO, 300169695Skan "Could not remove Global Lock handler")); 301169695Skan } 302169695Skan 303169695Skan AcpiGbl_EventsInitialized = FALSE; 304169695Skan } 305169695Skan 306169695Skan /* Remove SCI handlers */ 307169695Skan 308169695Skan Status = AcpiEvRemoveAllSciHandlers (); 309169695Skan if (ACPI_FAILURE(Status)) 310169695Skan { 311169695Skan ACPI_ERROR ((AE_INFO, 312169695Skan "Could not remove SCI handler")); 313169695Skan } 314169695Skan 315169695Skan /* Deallocate all handler objects installed within GPE info structs */ 316169695Skan 317169695Skan Status = AcpiEvWalkGpeList (AcpiEvDeleteGpeHandlers, NULL); 318169695Skan 319169695Skan /* Return to original mode if necessary */ 320169695Skan 321169695Skan if (AcpiGbl_OriginalMode == ACPI_SYS_MODE_LEGACY) 322169695Skan { 323169695Skan Status = AcpiDisable (); 324169695Skan if (ACPI_FAILURE (Status)) 325169695Skan { 326169695Skan ACPI_WARNING ((AE_INFO, "AcpiDisable failed")); 327169695Skan } 328169695Skan } 329169695Skan return_VOID; 330169695Skan} 331169695Skan 332169695Skan#endif /* !ACPI_REDUCED_HARDWARE */ 333169695Skan