1433d6423SLionel Sambuc /******************************************************************************
2433d6423SLionel Sambuc *
3433d6423SLionel Sambuc * Module Name: evmisc - Miscellaneous event manager support functions
4433d6423SLionel Sambuc *
5433d6423SLionel Sambuc *****************************************************************************/
6433d6423SLionel Sambuc
7*29492bb7SDavid van Moolenbroek /*
8*29492bb7SDavid van Moolenbroek * Copyright (C) 2000 - 2014, Intel Corp.
9433d6423SLionel Sambuc * All rights reserved.
10433d6423SLionel Sambuc *
11*29492bb7SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
12*29492bb7SDavid van Moolenbroek * modification, are permitted provided that the following conditions
13*29492bb7SDavid van Moolenbroek * are met:
14*29492bb7SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
15*29492bb7SDavid van Moolenbroek * notice, this list of conditions, and the following disclaimer,
16*29492bb7SDavid van Moolenbroek * without modification.
17*29492bb7SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*29492bb7SDavid van Moolenbroek * substantially similar to the "NO WARRANTY" disclaimer below
19*29492bb7SDavid van Moolenbroek * ("Disclaimer") and any redistribution must be conditioned upon
20*29492bb7SDavid van Moolenbroek * including a substantially similar Disclaimer requirement for further
21*29492bb7SDavid van Moolenbroek * binary redistribution.
22*29492bb7SDavid van Moolenbroek * 3. Neither the names of the above-listed copyright holders nor the names
23*29492bb7SDavid van Moolenbroek * of any contributors may be used to endorse or promote products derived
24*29492bb7SDavid van Moolenbroek * from this software without specific prior written permission.
25433d6423SLionel Sambuc *
26*29492bb7SDavid van Moolenbroek * Alternatively, this software may be distributed under the terms of the
27*29492bb7SDavid van Moolenbroek * GNU General Public License ("GPL") version 2 as published by the Free
28*29492bb7SDavid van Moolenbroek * Software Foundation.
29433d6423SLionel Sambuc *
30*29492bb7SDavid van Moolenbroek * NO WARRANTY
31*29492bb7SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*29492bb7SDavid van Moolenbroek * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*29492bb7SDavid van Moolenbroek * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*29492bb7SDavid van Moolenbroek * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*29492bb7SDavid van Moolenbroek * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*29492bb7SDavid van Moolenbroek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*29492bb7SDavid van Moolenbroek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*29492bb7SDavid van Moolenbroek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*29492bb7SDavid van Moolenbroek * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*29492bb7SDavid van Moolenbroek * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*29492bb7SDavid van Moolenbroek * POSSIBILITY OF SUCH DAMAGES.
42*29492bb7SDavid van Moolenbroek */
43433d6423SLionel Sambuc
44433d6423SLionel Sambuc #include "acpi.h"
45433d6423SLionel Sambuc #include "accommon.h"
46433d6423SLionel Sambuc #include "acevents.h"
47433d6423SLionel Sambuc #include "acnamesp.h"
48433d6423SLionel Sambuc
49433d6423SLionel Sambuc #define _COMPONENT ACPI_EVENTS
50433d6423SLionel Sambuc ACPI_MODULE_NAME ("evmisc")
51433d6423SLionel Sambuc
52433d6423SLionel Sambuc
53433d6423SLionel Sambuc /* Local prototypes */
54433d6423SLionel Sambuc
55433d6423SLionel Sambuc static void ACPI_SYSTEM_XFACE
56433d6423SLionel Sambuc AcpiEvNotifyDispatch (
57433d6423SLionel Sambuc void *Context);
58433d6423SLionel Sambuc
59433d6423SLionel Sambuc
60433d6423SLionel Sambuc /*******************************************************************************
61433d6423SLionel Sambuc *
62433d6423SLionel Sambuc * FUNCTION: AcpiEvIsNotifyObject
63433d6423SLionel Sambuc *
64433d6423SLionel Sambuc * PARAMETERS: Node - Node to check
65433d6423SLionel Sambuc *
66433d6423SLionel Sambuc * RETURN: TRUE if notifies allowed on this object
67433d6423SLionel Sambuc *
68433d6423SLionel Sambuc * DESCRIPTION: Check type of node for a object that supports notifies.
69433d6423SLionel Sambuc *
70433d6423SLionel Sambuc * TBD: This could be replaced by a flag bit in the node.
71433d6423SLionel Sambuc *
72433d6423SLionel Sambuc ******************************************************************************/
73433d6423SLionel Sambuc
74433d6423SLionel Sambuc BOOLEAN
AcpiEvIsNotifyObject(ACPI_NAMESPACE_NODE * Node)75433d6423SLionel Sambuc AcpiEvIsNotifyObject (
76433d6423SLionel Sambuc ACPI_NAMESPACE_NODE *Node)
77433d6423SLionel Sambuc {
78433d6423SLionel Sambuc switch (Node->Type)
79433d6423SLionel Sambuc {
80433d6423SLionel Sambuc case ACPI_TYPE_DEVICE:
81433d6423SLionel Sambuc case ACPI_TYPE_PROCESSOR:
82433d6423SLionel Sambuc case ACPI_TYPE_THERMAL:
83433d6423SLionel Sambuc /*
84433d6423SLionel Sambuc * These are the ONLY objects that can receive ACPI notifications
85433d6423SLionel Sambuc */
86433d6423SLionel Sambuc return (TRUE);
87433d6423SLionel Sambuc
88433d6423SLionel Sambuc default:
89*29492bb7SDavid van Moolenbroek
90433d6423SLionel Sambuc return (FALSE);
91433d6423SLionel Sambuc }
92433d6423SLionel Sambuc }
93433d6423SLionel Sambuc
94433d6423SLionel Sambuc
95433d6423SLionel Sambuc /*******************************************************************************
96433d6423SLionel Sambuc *
97433d6423SLionel Sambuc * FUNCTION: AcpiEvQueueNotifyRequest
98433d6423SLionel Sambuc *
99433d6423SLionel Sambuc * PARAMETERS: Node - NS node for the notified object
100433d6423SLionel Sambuc * NotifyValue - Value from the Notify() request
101433d6423SLionel Sambuc *
102433d6423SLionel Sambuc * RETURN: Status
103433d6423SLionel Sambuc *
104433d6423SLionel Sambuc * DESCRIPTION: Dispatch a device notification event to a previously
105433d6423SLionel Sambuc * installed handler.
106433d6423SLionel Sambuc *
107433d6423SLionel Sambuc ******************************************************************************/
108433d6423SLionel Sambuc
109433d6423SLionel Sambuc ACPI_STATUS
AcpiEvQueueNotifyRequest(ACPI_NAMESPACE_NODE * Node,UINT32 NotifyValue)110433d6423SLionel Sambuc AcpiEvQueueNotifyRequest (
111433d6423SLionel Sambuc ACPI_NAMESPACE_NODE *Node,
112433d6423SLionel Sambuc UINT32 NotifyValue)
113433d6423SLionel Sambuc {
114433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *ObjDesc;
115*29492bb7SDavid van Moolenbroek ACPI_OPERAND_OBJECT *HandlerListHead = NULL;
116*29492bb7SDavid van Moolenbroek ACPI_GENERIC_STATE *Info;
117*29492bb7SDavid van Moolenbroek UINT8 HandlerListId = 0;
118433d6423SLionel Sambuc ACPI_STATUS Status = AE_OK;
119433d6423SLionel Sambuc
120433d6423SLionel Sambuc
121433d6423SLionel Sambuc ACPI_FUNCTION_NAME (EvQueueNotifyRequest);
122433d6423SLionel Sambuc
123433d6423SLionel Sambuc
124*29492bb7SDavid van Moolenbroek /* Are Notifies allowed on this object? */
125433d6423SLionel Sambuc
126*29492bb7SDavid van Moolenbroek if (!AcpiEvIsNotifyObject (Node))
127*29492bb7SDavid van Moolenbroek {
128*29492bb7SDavid van Moolenbroek return (AE_TYPE);
129*29492bb7SDavid van Moolenbroek }
130*29492bb7SDavid van Moolenbroek
131*29492bb7SDavid van Moolenbroek /* Get the correct notify list type (System or Device) */
132*29492bb7SDavid van Moolenbroek
133*29492bb7SDavid van Moolenbroek if (NotifyValue <= ACPI_MAX_SYS_NOTIFY)
134*29492bb7SDavid van Moolenbroek {
135*29492bb7SDavid van Moolenbroek HandlerListId = ACPI_SYSTEM_HANDLER_LIST;
136*29492bb7SDavid van Moolenbroek }
137*29492bb7SDavid van Moolenbroek else
138*29492bb7SDavid van Moolenbroek {
139*29492bb7SDavid van Moolenbroek HandlerListId = ACPI_DEVICE_HANDLER_LIST;
140*29492bb7SDavid van Moolenbroek }
141*29492bb7SDavid van Moolenbroek
142*29492bb7SDavid van Moolenbroek /* Get the notify object attached to the namespace Node */
143433d6423SLionel Sambuc
144433d6423SLionel Sambuc ObjDesc = AcpiNsGetAttachedObject (Node);
145433d6423SLionel Sambuc if (ObjDesc)
146433d6423SLionel Sambuc {
147*29492bb7SDavid van Moolenbroek /* We have an attached object, Get the correct handler list */
148433d6423SLionel Sambuc
149*29492bb7SDavid van Moolenbroek HandlerListHead = ObjDesc->CommonNotify.NotifyList[HandlerListId];
150433d6423SLionel Sambuc }
151433d6423SLionel Sambuc
152433d6423SLionel Sambuc /*
153*29492bb7SDavid van Moolenbroek * If there is no notify handler (Global or Local)
154*29492bb7SDavid van Moolenbroek * for this object, just ignore the notify
155433d6423SLionel Sambuc */
156*29492bb7SDavid van Moolenbroek if (!AcpiGbl_GlobalNotify[HandlerListId].Handler && !HandlerListHead)
157433d6423SLionel Sambuc {
158*29492bb7SDavid van Moolenbroek ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
159*29492bb7SDavid van Moolenbroek "No notify handler for Notify, ignoring (%4.4s, %X) node %p\n",
160*29492bb7SDavid van Moolenbroek AcpiUtGetNodeName (Node), NotifyValue, Node));
161*29492bb7SDavid van Moolenbroek
162*29492bb7SDavid van Moolenbroek return (AE_OK);
163*29492bb7SDavid van Moolenbroek }
164*29492bb7SDavid van Moolenbroek
165*29492bb7SDavid van Moolenbroek /* Setup notify info and schedule the notify dispatcher */
166*29492bb7SDavid van Moolenbroek
167*29492bb7SDavid van Moolenbroek Info = AcpiUtCreateGenericState ();
168*29492bb7SDavid van Moolenbroek if (!Info)
169433d6423SLionel Sambuc {
170433d6423SLionel Sambuc return (AE_NO_MEMORY);
171433d6423SLionel Sambuc }
172433d6423SLionel Sambuc
173*29492bb7SDavid van Moolenbroek Info->Common.DescriptorType = ACPI_DESC_TYPE_STATE_NOTIFY;
174*29492bb7SDavid van Moolenbroek
175*29492bb7SDavid van Moolenbroek Info->Notify.Node = Node;
176*29492bb7SDavid van Moolenbroek Info->Notify.Value = (UINT16) NotifyValue;
177*29492bb7SDavid van Moolenbroek Info->Notify.HandlerListId = HandlerListId;
178*29492bb7SDavid van Moolenbroek Info->Notify.HandlerListHead = HandlerListHead;
179*29492bb7SDavid van Moolenbroek Info->Notify.Global = &AcpiGbl_GlobalNotify[HandlerListId];
180*29492bb7SDavid van Moolenbroek
181433d6423SLionel Sambuc ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
182*29492bb7SDavid van Moolenbroek "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n",
183*29492bb7SDavid van Moolenbroek AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type),
184*29492bb7SDavid van Moolenbroek NotifyValue, AcpiUtGetNotifyName (NotifyValue, ACPI_TYPE_ANY), Node));
185433d6423SLionel Sambuc
186*29492bb7SDavid van Moolenbroek Status = AcpiOsExecute (OSL_NOTIFY_HANDLER, AcpiEvNotifyDispatch,
187*29492bb7SDavid van Moolenbroek Info);
188433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
189433d6423SLionel Sambuc {
190*29492bb7SDavid van Moolenbroek AcpiUtDeleteGenericState (Info);
191433d6423SLionel Sambuc }
192433d6423SLionel Sambuc
193433d6423SLionel Sambuc return (Status);
194433d6423SLionel Sambuc }
195433d6423SLionel Sambuc
196433d6423SLionel Sambuc
197433d6423SLionel Sambuc /*******************************************************************************
198433d6423SLionel Sambuc *
199433d6423SLionel Sambuc * FUNCTION: AcpiEvNotifyDispatch
200433d6423SLionel Sambuc *
201433d6423SLionel Sambuc * PARAMETERS: Context - To be passed to the notify handler
202433d6423SLionel Sambuc *
203433d6423SLionel Sambuc * RETURN: None.
204433d6423SLionel Sambuc *
205433d6423SLionel Sambuc * DESCRIPTION: Dispatch a device notification event to a previously
206433d6423SLionel Sambuc * installed handler.
207433d6423SLionel Sambuc *
208433d6423SLionel Sambuc ******************************************************************************/
209433d6423SLionel Sambuc
210433d6423SLionel Sambuc static void ACPI_SYSTEM_XFACE
AcpiEvNotifyDispatch(void * Context)211433d6423SLionel Sambuc AcpiEvNotifyDispatch (
212433d6423SLionel Sambuc void *Context)
213433d6423SLionel Sambuc {
214*29492bb7SDavid van Moolenbroek ACPI_GENERIC_STATE *Info = (ACPI_GENERIC_STATE *) Context;
215433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *HandlerObj;
216433d6423SLionel Sambuc
217433d6423SLionel Sambuc
218433d6423SLionel Sambuc ACPI_FUNCTION_ENTRY ();
219433d6423SLionel Sambuc
220433d6423SLionel Sambuc
221*29492bb7SDavid van Moolenbroek /* Invoke a global notify handler if installed */
222433d6423SLionel Sambuc
223*29492bb7SDavid van Moolenbroek if (Info->Notify.Global->Handler)
224433d6423SLionel Sambuc {
225*29492bb7SDavid van Moolenbroek Info->Notify.Global->Handler (Info->Notify.Node,
226*29492bb7SDavid van Moolenbroek Info->Notify.Value,
227*29492bb7SDavid van Moolenbroek Info->Notify.Global->Context);
228433d6423SLionel Sambuc }
229433d6423SLionel Sambuc
230*29492bb7SDavid van Moolenbroek /* Now invoke the local notify handler(s) if any are installed */
231433d6423SLionel Sambuc
232*29492bb7SDavid van Moolenbroek HandlerObj = Info->Notify.HandlerListHead;
233*29492bb7SDavid van Moolenbroek while (HandlerObj)
234433d6423SLionel Sambuc {
235*29492bb7SDavid van Moolenbroek HandlerObj->Notify.Handler (Info->Notify.Node,
236*29492bb7SDavid van Moolenbroek Info->Notify.Value,
237433d6423SLionel Sambuc HandlerObj->Notify.Context);
238*29492bb7SDavid van Moolenbroek
239*29492bb7SDavid van Moolenbroek HandlerObj = HandlerObj->Notify.Next[Info->Notify.HandlerListId];
240433d6423SLionel Sambuc }
241433d6423SLionel Sambuc
242433d6423SLionel Sambuc /* All done with the info object */
243433d6423SLionel Sambuc
244*29492bb7SDavid van Moolenbroek AcpiUtDeleteGenericState (Info);
245433d6423SLionel Sambuc }
246433d6423SLionel Sambuc
247433d6423SLionel Sambuc
248*29492bb7SDavid van Moolenbroek #if (!ACPI_REDUCED_HARDWARE)
249433d6423SLionel Sambuc /******************************************************************************
250433d6423SLionel Sambuc *
251433d6423SLionel Sambuc * FUNCTION: AcpiEvTerminate
252433d6423SLionel Sambuc *
253433d6423SLionel Sambuc * PARAMETERS: none
254433d6423SLionel Sambuc *
255433d6423SLionel Sambuc * RETURN: none
256433d6423SLionel Sambuc *
257433d6423SLionel Sambuc * DESCRIPTION: Disable events and free memory allocated for table storage.
258433d6423SLionel Sambuc *
259433d6423SLionel Sambuc ******************************************************************************/
260433d6423SLionel Sambuc
261433d6423SLionel Sambuc void
AcpiEvTerminate(void)262433d6423SLionel Sambuc AcpiEvTerminate (
263433d6423SLionel Sambuc void)
264433d6423SLionel Sambuc {
265433d6423SLionel Sambuc UINT32 i;
266433d6423SLionel Sambuc ACPI_STATUS Status;
267433d6423SLionel Sambuc
268433d6423SLionel Sambuc
269433d6423SLionel Sambuc ACPI_FUNCTION_TRACE (EvTerminate);
270433d6423SLionel Sambuc
271433d6423SLionel Sambuc
272433d6423SLionel Sambuc if (AcpiGbl_EventsInitialized)
273433d6423SLionel Sambuc {
274433d6423SLionel Sambuc /*
275433d6423SLionel Sambuc * Disable all event-related functionality. In all cases, on error,
276433d6423SLionel Sambuc * print a message but obviously we don't abort.
277433d6423SLionel Sambuc */
278433d6423SLionel Sambuc
279433d6423SLionel Sambuc /* Disable all fixed events */
280433d6423SLionel Sambuc
281433d6423SLionel Sambuc for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++)
282433d6423SLionel Sambuc {
283433d6423SLionel Sambuc Status = AcpiDisableEvent (i, 0);
284433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
285433d6423SLionel Sambuc {
286433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO,
287433d6423SLionel Sambuc "Could not disable fixed event %u", (UINT32) i));
288433d6423SLionel Sambuc }
289433d6423SLionel Sambuc }
290433d6423SLionel Sambuc
291433d6423SLionel Sambuc /* Disable all GPEs in all GPE blocks */
292433d6423SLionel Sambuc
293433d6423SLionel Sambuc Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock, NULL);
294433d6423SLionel Sambuc
295433d6423SLionel Sambuc Status = AcpiEvRemoveGlobalLockHandler ();
296433d6423SLionel Sambuc if (ACPI_FAILURE(Status))
297433d6423SLionel Sambuc {
298433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO,
299433d6423SLionel Sambuc "Could not remove Global Lock handler"));
300433d6423SLionel Sambuc }
301*29492bb7SDavid van Moolenbroek
302*29492bb7SDavid van Moolenbroek AcpiGbl_EventsInitialized = FALSE;
303*29492bb7SDavid van Moolenbroek }
304*29492bb7SDavid van Moolenbroek
305*29492bb7SDavid van Moolenbroek /* Remove SCI handlers */
306*29492bb7SDavid van Moolenbroek
307*29492bb7SDavid van Moolenbroek Status = AcpiEvRemoveAllSciHandlers ();
308*29492bb7SDavid van Moolenbroek if (ACPI_FAILURE(Status))
309*29492bb7SDavid van Moolenbroek {
310*29492bb7SDavid van Moolenbroek ACPI_ERROR ((AE_INFO,
311*29492bb7SDavid van Moolenbroek "Could not remove SCI handler"));
312433d6423SLionel Sambuc }
313433d6423SLionel Sambuc
314433d6423SLionel Sambuc /* Deallocate all handler objects installed within GPE info structs */
315433d6423SLionel Sambuc
316433d6423SLionel Sambuc Status = AcpiEvWalkGpeList (AcpiEvDeleteGpeHandlers, NULL);
317433d6423SLionel Sambuc
318433d6423SLionel Sambuc /* Return to original mode if necessary */
319433d6423SLionel Sambuc
320433d6423SLionel Sambuc if (AcpiGbl_OriginalMode == ACPI_SYS_MODE_LEGACY)
321433d6423SLionel Sambuc {
322433d6423SLionel Sambuc Status = AcpiDisable ();
323433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
324433d6423SLionel Sambuc {
325433d6423SLionel Sambuc ACPI_WARNING ((AE_INFO, "AcpiDisable failed"));
326433d6423SLionel Sambuc }
327433d6423SLionel Sambuc }
328433d6423SLionel Sambuc return_VOID;
329433d6423SLionel Sambuc }
330433d6423SLionel Sambuc
331*29492bb7SDavid van Moolenbroek #endif /* !ACPI_REDUCED_HARDWARE */
332