evxface.c revision 117521
1142403Snectar/******************************************************************************
2142403Snectar *
3142403Snectar * Module Name: evxface - External interfaces for ACPI events
4142403Snectar *              $Revision: 141 $
5142403Snectar *
6142403Snectar *****************************************************************************/
7142403Snectar
8142403Snectar/******************************************************************************
9142403Snectar *
10142403Snectar * 1. Copyright Notice
11142403Snectar *
12142403Snectar * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp.
13142403Snectar * All rights reserved.
14142403Snectar *
15142403Snectar * 2. License
16142403Snectar *
17142403Snectar * 2.1. This is your license from Intel Corp. under its intellectual property
18142403Snectar * rights.  You may have additional license terms from the party that provided
19142403Snectar * you this software, covering your right to use that party's intellectual
20142403Snectar * property rights.
21142403Snectar *
22142403Snectar * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23142403Snectar * copy of the source code appearing in this file ("Covered Code") an
24142403Snectar * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25142403Snectar * base code distributed originally by Intel ("Original Intel Code") to copy,
26142403Snectar * make derivatives, distribute, use and display any portion of the Covered
27142403Snectar * Code in any form, with the right to sublicense such rights; and
28142403Snectar *
29142403Snectar * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30142403Snectar * license (with the right to sublicense), under only those claims of Intel
31142403Snectar * patents that are infringed by the Original Intel Code, to make, use, sell,
32142403Snectar * offer to sell, and import the Covered Code and derivative works thereof
33142403Snectar * solely to the minimum extent necessary to exercise the above copyright
34142403Snectar * license, and in no event shall the patent license extend to any additions
35142403Snectar * to or modifications of the Original Intel Code.  No other license or right
36142403Snectar * is granted directly or by implication, estoppel or otherwise;
37142403Snectar *
38142403Snectar * The above copyright and patent license is granted only if the following
39142403Snectar * conditions are met:
40142403Snectar *
41142403Snectar * 3. Conditions
42142403Snectar *
43142403Snectar * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44142403Snectar * Redistribution of source code of any substantial prton of the Covered
45142403Snectar * Code or modification with rights to further distribute source must include
46142403Snectar * the above Copyright Notice, the above License, this list of Conditions,
47142403Snectar * and the following Disclaimer and Export Compliance provision.  In addition,
48142403Snectar * Licensee must cause all Covered Code to which Licensee contributes to
49142403Snectar * contain a file documenting the changes Licensee made to create that Covered
50142403Snectar * Code and the date of any change.  Licensee must include in that file the
51142403Snectar * documentation of any changes made by any predecessor Licensee.  Licensee
52142403Snectar * must include a prominent statement that the modification is derived,
53142403Snectar * directly or indirectly, from Original Intel Code.
54142403Snectar *
55142403Snectar * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56142403Snectar * Redistribution of source code of any substantial portion of the Covered
57142403Snectar * Code or modification without rights to further distribute source must
58142403Snectar * include the following Disclaimer and Export Compliance provision in the
59142403Snectar * documentation and/or other materials provided with distribution.  In
60142403Snectar * addition, Licensee may not authorize further sublicense of source of any
61142403Snectar * portion of the Covered Code, and must include terms to the effect that the
62142403Snectar * license from Licensee to its licensee is limited to the intellectual
63142403Snectar * property embodied in the software Licensee provides to its licensee, and
64142403Snectar * not to intellectual property embodied in modifications its licensee may
65127808Snectar * make.
66127808Snectar *
67127808Snectar * 3.3. Redistribution of Executable. Redistribution in executable form of any
68127808Snectar * substantial portion of the Covered Code or modification must reproduce the
69127808Snectar * above Copyright Notice, and the following Disclaimer and Export Compliance
70127808Snectar * provision in the documentation and/or other materials provided with the
71127808Snectar * distribution.
72127808Snectar *
73127808Snectar * 3.4. Intel retains all right, title, and interest in and to the Original
74127808Snectar * Intel Code.
75127808Snectar *
76127808Snectar * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77127808Snectar * Intel shall be used in advertising or otherwise to promote the sale, use or
78127808Snectar * other dealings in products derived from or relating to the Covered Code
79127808Snectar * without prior written authorization from Intel.
80127808Snectar *
81127808Snectar * 4. Disclaimer and Export Compliance
82127808Snectar *
83127808Snectar * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84127808Snectar * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85127808Snectar * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86127808Snectar * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87127808Snectar * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88127808Snectar * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89127808Snectar * PARTICULAR PURPOSE.
90127808Snectar *
91127808Snectar * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92127808Snectar * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93127808Snectar * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94127808Snectar * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95127808Snectar * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96127808Snectar * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97127808Snectar * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98127808Snectar * LIMITED REMEDY.
99127808Snectar *
100127808Snectar * 4.3. Licensee shall not export, either directly or indirectly, any of this
101127808Snectar * software or system incorporating such software without first obtaining any
102127808Snectar * required license or other approval from the U. S. Department of Commerce or
103127808Snectar * any other agency or department of the United States Government.  In the
104127808Snectar * event Licensee exports any such software from the United States or
105127808Snectar * re-exports any such software from a foreign destination, Licensee shall
106127808Snectar * ensure that the distribution and export/re-export of the software is in
107127808Snectar * compliance with all laws, regulations, orders, or other restrictions of the
108127808Snectar * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109127808Snectar * any of its subsidiaries will export/re-export any technical data, process,
110127808Snectar * software, or service, directly or indirectly, to any country for which the
111127808Snectar * United States government or any agency thereof requires an export license,
112127808Snectar * other governmental approval, or letter of assurance, without first obtaining
113127808Snectar * such license, approval or letter.
114127808Snectar *
115127808Snectar *****************************************************************************/
116127808Snectar
117127808Snectar
118127808Snectar#define __EVXFACE_C__
119127808Snectar
120127808Snectar#include "acpi.h"
121127808Snectar#include "acnamesp.h"
122127808Snectar#include "acevents.h"
123127808Snectar#include "acinterp.h"
124127808Snectar
125127808Snectar#define _COMPONENT          ACPI_EVENTS
126127808Snectar        ACPI_MODULE_NAME    ("evxface")
127127808Snectar
128127808Snectar
129127808Snectar/*******************************************************************************
130127808Snectar *
131127808Snectar * FUNCTION:    AcpiInstallFixedEventHandler
132127808Snectar *
133127808Snectar * PARAMETERS:  Event           - Event type to enable.
134127808Snectar *              Handler         - Pointer to the handler function for the
135127808Snectar *                                event
136127808Snectar *              Context         - Value passed to the handler on each GPE
137127808Snectar *
138127808Snectar * RETURN:      Status
139127808Snectar *
140127808Snectar * DESCRIPTION: Saves the pointer to the handler function and then enables the
141127808Snectar *              event.
142127808Snectar *
143127808Snectar ******************************************************************************/
144127808Snectar
145127808SnectarACPI_STATUS
146127808SnectarAcpiInstallFixedEventHandler (
147127808Snectar    UINT32                  Event,
148127808Snectar    ACPI_EVENT_HANDLER      Handler,
149127808Snectar    void                    *Context)
150127808Snectar{
151127808Snectar    ACPI_STATUS             Status;
152127808Snectar
153127808Snectar
154127808Snectar    ACPI_FUNCTION_TRACE ("AcpiInstallFixedEventHandler");
155127808Snectar
156127808Snectar
157127808Snectar    /* Parameter validation */
158127808Snectar
159127808Snectar    if (Event > ACPI_EVENT_MAX)
160127808Snectar    {
161127808Snectar        return_ACPI_STATUS (AE_BAD_PARAMETER);
162127808Snectar    }
163127808Snectar
164127808Snectar    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
165127808Snectar    if (ACPI_FAILURE (Status))
166127808Snectar    {
167127808Snectar        return_ACPI_STATUS (Status);
168127808Snectar    }
169127808Snectar
170127808Snectar    /* Don't allow two handlers. */
171127808Snectar
172127808Snectar    if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler)
173127808Snectar    {
174127808Snectar        Status = AE_ALREADY_EXISTS;
175127808Snectar        goto Cleanup;
176127808Snectar    }
177127808Snectar
178127808Snectar    /* Install the handler before enabling the event */
179127808Snectar
180127808Snectar    AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
181127808Snectar    AcpiGbl_FixedEventHandlers[Event].Context = Context;
182127808Snectar
183127808Snectar    Status = AcpiEnableEvent (Event, 0);
184127808Snectar    if (ACPI_FAILURE (Status))
185127808Snectar    {
186127808Snectar        ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n"));
187127808Snectar
188127808Snectar        /* Remove the handler */
189127808Snectar
190127808Snectar        AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
191127808Snectar        AcpiGbl_FixedEventHandlers[Event].Context = NULL;
192127808Snectar    }
193127808Snectar    else
194127808Snectar    {
195127808Snectar        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
196127808Snectar            "Enabled fixed event %X, Handler=%p\n", Event, Handler));
197127808Snectar    }
198127808Snectar
199127808Snectar
200127808SnectarCleanup:
201127808Snectar    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
202127808Snectar    return_ACPI_STATUS (Status);
203127808Snectar}
204127808Snectar
205127808Snectar
206127808Snectar/*******************************************************************************
207127808Snectar *
208127808Snectar * FUNCTION:    AcpiRemoveFixedEventHandler
209127808Snectar *
210127808Snectar * PARAMETERS:  Event           - Event type to disable.
211127808Snectar *              Handler         - Address of the handler
212127808Snectar *
213127808Snectar * RETURN:      Status
214127808Snectar *
215127808Snectar * DESCRIPTION: Disables the event and unregisters the event handler.
216127808Snectar *
217127808Snectar ******************************************************************************/
218127808Snectar
219127808SnectarACPI_STATUS
220127808SnectarAcpiRemoveFixedEventHandler (
221127808Snectar    UINT32                  Event,
222127808Snectar    ACPI_EVENT_HANDLER      Handler)
223127808Snectar{
224127808Snectar    ACPI_STATUS             Status = AE_OK;
225127808Snectar
226127808Snectar
227127808Snectar    ACPI_FUNCTION_TRACE ("AcpiRemoveFixedEventHandler");
228127808Snectar
229127808Snectar
230127808Snectar    /* Parameter validation */
231127808Snectar
232127808Snectar    if (Event > ACPI_EVENT_MAX)
233127808Snectar    {
234127808Snectar        return_ACPI_STATUS (AE_BAD_PARAMETER);
235127808Snectar    }
236127808Snectar
237127808Snectar    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
238127808Snectar    if (ACPI_FAILURE (Status))
239127808Snectar    {
240127808Snectar        return_ACPI_STATUS (Status);
241127808Snectar    }
242127808Snectar
243127808Snectar    /* Disable the event before removing the handler */
244127808Snectar
245127808Snectar    Status = AcpiDisableEvent (Event, 0);
246127808Snectar
247127808Snectar    /* Always Remove the handler */
248127808Snectar
249127808Snectar    AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
250127808Snectar    AcpiGbl_FixedEventHandlers[Event].Context = NULL;
251127808Snectar
252127808Snectar    if (ACPI_FAILURE (Status))
253127808Snectar    {
254127808Snectar        ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
255127808Snectar            "Could not write to fixed event enable register.\n"));
256127808Snectar    }
257127808Snectar    else
258127808Snectar    {
259127808Snectar        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X.\n", Event));
260127808Snectar    }
261127808Snectar
262127808Snectar    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
263127808Snectar    return_ACPI_STATUS (Status);
264127808Snectar}
265127808Snectar
266127808Snectar
267127808Snectar/*******************************************************************************
268127808Snectar *
269127808Snectar * FUNCTION:    AcpiInstallNotifyHandler
270127808Snectar *
271127808Snectar * PARAMETERS:  Device          - The device for which notifies will be handled
272127808Snectar *              HandlerType     - The type of handler:
273127808Snectar *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
274127808Snectar *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
275127808Snectar *              Handler         - Address of the handler
276127808Snectar *              Context         - Value passed to the handler on each GPE
277127808Snectar *
278127808Snectar * RETURN:      Status
279127808Snectar *
280127808Snectar * DESCRIPTION: Install a handler for notifies on an ACPI device
281127808Snectar *
282127808Snectar ******************************************************************************/
283127808Snectar
284127808SnectarACPI_STATUS
285127808SnectarAcpiInstallNotifyHandler (
286127808Snectar    ACPI_HANDLE             Device,
287127808Snectar    UINT32                  HandlerType,
288127808Snectar    ACPI_NOTIFY_HANDLER     Handler,
289127808Snectar    void                    *Context)
290127808Snectar{
291127808Snectar    ACPI_OPERAND_OBJECT     *ObjDesc;
292127808Snectar    ACPI_OPERAND_OBJECT     *NotifyObj;
293127808Snectar    ACPI_NAMESPACE_NODE     *Node;
294127808Snectar    ACPI_STATUS             Status;
295127808Snectar
296127808Snectar
297127808Snectar    ACPI_FUNCTION_TRACE ("AcpiInstallNotifyHandler");
298127808Snectar
299127808Snectar
300127808Snectar    /* Parameter validation */
301127808Snectar
302127808Snectar    if ((!Device)  ||
303127808Snectar        (!Handler) ||
304127808Snectar        (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
305127808Snectar    {
306127808Snectar        return_ACPI_STATUS (AE_BAD_PARAMETER);
307127808Snectar    }
308127808Snectar
309127808Snectar    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
310127808Snectar    if (ACPI_FAILURE (Status))
311127808Snectar    {
312127808Snectar        return_ACPI_STATUS (Status);
313127808Snectar    }
314127808Snectar
315127808Snectar    /* Convert and validate the device handle */
316127808Snectar
317127808Snectar    Node = AcpiNsMapHandleToNode (Device);
318127808Snectar    if (!Node)
319127808Snectar    {
320127808Snectar        Status = AE_BAD_PARAMETER;
321127808Snectar        goto UnlockAndExit;
322127808Snectar    }
323127808Snectar
324127808Snectar    /*
325127808Snectar     * Root Object:
326127808Snectar     * Registering a notify handler on the root object indicates that the
327127808Snectar     * caller wishes to receive notifications for all objects.  Note that
328127808Snectar     * only one <external> global handler can be regsitered (per notify type).
329127808Snectar     */
330127808Snectar    if (Device == ACPI_ROOT_OBJECT)
331127808Snectar    {
332127808Snectar        /* Make sure the handler is not already installed */
333127808Snectar
334127808Snectar        if (((HandlerType == ACPI_SYSTEM_NOTIFY) &&
335127808Snectar                AcpiGbl_SystemNotify.Handler)          ||
336127808Snectar            ((HandlerType == ACPI_DEVICE_NOTIFY) &&
337127808Snectar                AcpiGbl_DeviceNotify.Handler))
338127808Snectar        {
339127808Snectar            Status = AE_ALREADY_EXISTS;
340127808Snectar            goto UnlockAndExit;
341127808Snectar        }
342127808Snectar
343127808Snectar        if (HandlerType == ACPI_SYSTEM_NOTIFY)
344120945Snectar        {
345103423Snectar            AcpiGbl_SystemNotify.Node    = Node;
346120945Snectar            AcpiGbl_SystemNotify.Handler = Handler;
347103423Snectar            AcpiGbl_SystemNotify.Context = Context;
348120945Snectar        }
349103423Snectar        else /* ACPI_DEVICE_NOTIFY */
350120945Snectar        {
351120945Snectar            AcpiGbl_DeviceNotify.Node    = Node;
352103423Snectar            AcpiGbl_DeviceNotify.Handler = Handler;
353120945Snectar            AcpiGbl_DeviceNotify.Context = Context;
354120945Snectar        }
355103423Snectar
356120945Snectar        /* Global notify handler installed */
357120945Snectar    }
358103423Snectar
359120945Snectar    /*
360107207Snectar     * All Other Objects:
361120945Snectar     * Caller will only receive notifications specific to the target object.
362120945Snectar     * Note that only certain object types can receive notifications.
363107207Snectar     */
364120945Snectar    else
365120945Snectar    {
366120945Snectar        /* Notifies allowed on this object? */
367107207Snectar
368120945Snectar        if (!AcpiEvIsNotifyObject (Node))
369107207Snectar        {
370120945Snectar            Status = AE_TYPE;
371120945Snectar            goto UnlockAndExit;
372120945Snectar        }
373120945Snectar
374107207Snectar        /* Check for an existing internal object */
375120945Snectar
376107207Snectar        ObjDesc = AcpiNsGetAttachedObject (Node);
377120945Snectar        if (ObjDesc)
378107207Snectar        {
379120945Snectar            /* Object exists - make sure there's no handler */
380120945Snectar
381120945Snectar            if (((HandlerType == ACPI_SYSTEM_NOTIFY) &&
382107207Snectar                    ObjDesc->CommonNotify.SystemNotify)   ||
383120945Snectar                ((HandlerType == ACPI_DEVICE_NOTIFY) &&
384120945Snectar                    ObjDesc->CommonNotify.DeviceNotify))
385103423Snectar            {
386120945Snectar                Status = AE_ALREADY_EXISTS;
387107207Snectar                goto UnlockAndExit;
388120945Snectar            }
389120945Snectar        }
390103423Snectar        else
391120945Snectar        {
392103423Snectar            /* Create a new object */
393120945Snectar
394120945Snectar            ObjDesc = AcpiUtCreateInternalObject (Node->Type);
395103423Snectar            if (!ObjDesc)
396120945Snectar            {
397103423Snectar                Status = AE_NO_MEMORY;
398120945Snectar                goto UnlockAndExit;
399120945Snectar            }
400120945Snectar
401120945Snectar            /* Attach new object to the Node */
402120945Snectar
403120945Snectar            Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
404120945Snectar
405120945Snectar            /* Remove local reference to the object */
406120945Snectar
407120945Snectar            AcpiUtRemoveReference (ObjDesc);
408120945Snectar
409103423Snectar            if (ACPI_FAILURE (Status))
410120945Snectar            {
411120945Snectar                goto UnlockAndExit;
412120945Snectar            }
413120945Snectar        }
414120945Snectar
415120945Snectar        /* Install the handler */
416120945Snectar
417120945Snectar        NotifyObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
418120945Snectar        if (!NotifyObj)
419120945Snectar        {
420103423Snectar            Status = AE_NO_MEMORY;
421120945Snectar            goto UnlockAndExit;
422120945Snectar        }
423120945Snectar
424103423Snectar        NotifyObj->Notify.Node    = Node;
425120945Snectar        NotifyObj->Notify.Handler = Handler;
426120945Snectar        NotifyObj->Notify.Context = Context;
427120945Snectar
428120945Snectar        if (HandlerType == ACPI_SYSTEM_NOTIFY)
429120945Snectar        {
430120945Snectar            ObjDesc->CommonNotify.SystemNotify = NotifyObj;
431120945Snectar        }
432103423Snectar        else /* ACPI_DEVICE_NOTIFY */
433120945Snectar        {
434103423Snectar            ObjDesc->CommonNotify.DeviceNotify = NotifyObj;
435120945Snectar        }
436120945Snectar    }
437120945Snectar
438103423Snectar
439120945SnectarUnlockAndExit:
440120945Snectar    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
441120945Snectar    return_ACPI_STATUS (Status);
442103423Snectar}
443120945Snectar
444120945Snectar
445120945Snectar/*******************************************************************************
446103423Snectar *
447120945Snectar * FUNCTION:    AcpiRemoveNotifyHandler
448120945Snectar *
449120945Snectar * PARAMETERS:  Device          - The device for which notifies will be handled
450120945Snectar *              HandlerType     - The type of handler:
451120945Snectar *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
452120945Snectar *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
453120945Snectar *              Handler         - Address of the handler
454120945Snectar * RETURN:      Status
455120945Snectar *
456103423Snectar * DESCRIPTION: Remove a handler for notifies on an ACPI device
457120945Snectar *
458120945Snectar ******************************************************************************/
459120945Snectar
460120945SnectarACPI_STATUS
461120945SnectarAcpiRemoveNotifyHandler (
462103423Snectar    ACPI_HANDLE             Device,
463120945Snectar    UINT32                  HandlerType,
464120945Snectar    ACPI_NOTIFY_HANDLER     Handler)
465120945Snectar{
466120945Snectar    ACPI_OPERAND_OBJECT     *NotifyObj;
467120945Snectar    ACPI_OPERAND_OBJECT     *ObjDesc;
468120945Snectar    ACPI_NAMESPACE_NODE     *Node;
469120945Snectar    ACPI_STATUS             Status;
470120945Snectar
471103423Snectar
472120945Snectar    ACPI_FUNCTION_TRACE ("AcpiRemoveNotifyHandler");
473120945Snectar
474120945Snectar
475120945Snectar    /* Parameter validation */
476120945Snectar
477120945Snectar    if ((!Device)  ||
478103423Snectar        (!Handler) ||
479120945Snectar        (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
480120945Snectar    {
481120945Snectar        return_ACPI_STATUS (AE_BAD_PARAMETER);
482103423Snectar    }
483120945Snectar
484120945Snectar    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
485103423Snectar    if (ACPI_FAILURE (Status))
486120945Snectar    {
487103423Snectar        return_ACPI_STATUS (Status);
488120945Snectar    }
489120945Snectar
490103423Snectar    /* Convert and validate the device handle */
491120945Snectar
492103423Snectar    Node = AcpiNsMapHandleToNode (Device);
493120945Snectar    if (!Node)
494120945Snectar    {
495103423Snectar        Status = AE_BAD_PARAMETER;
496120945Snectar        goto UnlockAndExit;
497120945Snectar    }
498120945Snectar
499103423Snectar    /*
500120945Snectar     * Root Object
501120945Snectar     */
502120945Snectar    if (Device == ACPI_ROOT_OBJECT)
503120945Snectar    {
504103423Snectar        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
505120945Snectar
506120945Snectar        if (((HandlerType == ACPI_SYSTEM_NOTIFY) &&
507120945Snectar              !AcpiGbl_SystemNotify.Handler) ||
508120945Snectar            ((HandlerType == ACPI_DEVICE_NOTIFY) &&
509103423Snectar              !AcpiGbl_DeviceNotify.Handler))
510120945Snectar        {
511120945Snectar            Status = AE_NOT_EXIST;
512120945Snectar            goto UnlockAndExit;
513120945Snectar        }
514120945Snectar
515103423Snectar        if (HandlerType == ACPI_SYSTEM_NOTIFY)
516120945Snectar        {
517120945Snectar            AcpiGbl_SystemNotify.Node    = NULL;
518103423Snectar            AcpiGbl_SystemNotify.Handler = NULL;
519120945Snectar            AcpiGbl_SystemNotify.Context = NULL;
520120945Snectar        }
521103423Snectar        else
522120945Snectar        {
523103423Snectar            AcpiGbl_DeviceNotify.Node    = NULL;
524120945Snectar            AcpiGbl_DeviceNotify.Handler = NULL;
525120945Snectar            AcpiGbl_DeviceNotify.Context = NULL;
526120945Snectar        }
527120945Snectar    }
528103423Snectar
529120945Snectar    /*
530120945Snectar     * All Other Objects
531103423Snectar     */
532120945Snectar    else
533120945Snectar    {
534120945Snectar        /* Notifies allowed on this object? */
535120945Snectar
536103423Snectar        if (!AcpiEvIsNotifyObject (Node))
537120945Snectar        {
538120945Snectar            Status = AE_TYPE;
539120945Snectar            goto UnlockAndExit;
540103423Snectar        }
541120945Snectar
542103423Snectar        /* Check for an existing internal object */
543120945Snectar
544103423Snectar        ObjDesc = AcpiNsGetAttachedObject (Node);
545120945Snectar        if (!ObjDesc)
546120945Snectar        {
547120945Snectar            Status = AE_NOT_EXIST;
548103423Snectar            goto UnlockAndExit;
549120945Snectar        }
550120945Snectar
551120945Snectar        /* Object exists - make sure there's an existing handler */
552120945Snectar
553120945Snectar        if (HandlerType == ACPI_SYSTEM_NOTIFY)
554103423Snectar        {
555120945Snectar            NotifyObj = ObjDesc->CommonNotify.SystemNotify;
556103423Snectar        }
557120945Snectar        else
558103423Snectar        {
559120945Snectar            NotifyObj = ObjDesc->CommonNotify.DeviceNotify;
560103423Snectar        }
561120945Snectar
562120945Snectar        if ((!NotifyObj) ||
563120945Snectar            (NotifyObj->Notify.Handler != Handler))
564120945Snectar        {
565103423Snectar            Status = AE_BAD_PARAMETER;
566120945Snectar            goto UnlockAndExit;
567103423Snectar        }
568120945Snectar
569120945Snectar        /* Remove the handler */
570103423Snectar
571120945Snectar        if (HandlerType == ACPI_SYSTEM_NOTIFY)
572120945Snectar        {
573120945Snectar            ObjDesc->CommonNotify.SystemNotify = NULL;
574120945Snectar        }
575103423Snectar        else
576120945Snectar        {
577120945Snectar            ObjDesc->CommonNotify.DeviceNotify = NULL;
578103423Snectar        }
579120945Snectar
580103423Snectar        AcpiUtRemoveReference (NotifyObj);
581120945Snectar    }
582120945Snectar
583120945Snectar
584120945SnectarUnlockAndExit:
585120945Snectar    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
586103423Snectar    return_ACPI_STATUS (Status);
587120945Snectar}
588120945Snectar
589120945Snectar
590120945Snectar/*******************************************************************************
591120945Snectar *
592120945Snectar * FUNCTION:    AcpiInstallGpeHandler
593120945Snectar *
594103423Snectar * PARAMETERS:  GpeNumber       - The GPE number within the GPE block
595120945Snectar *              GpeBlock        - GPE block (NULL == FADT GPEs)
596120945Snectar *              Type            - Whether this GPE should be treated as an
597120945Snectar *                                edge- or level-triggered interrupt.
598120945Snectar *              Handler         - Address of the handler
599120945Snectar *              Context         - Value passed to the handler on each GPE
600120945Snectar *
601120945Snectar * RETURN:      Status
602103423Snectar *
603120945Snectar * DESCRIPTION: Install a handler for a General Purpose Event.
604103423Snectar *
605120945Snectar ******************************************************************************/
606120945Snectar
607120945SnectarACPI_STATUS
608120945SnectarAcpiInstallGpeHandler (
609103423Snectar    ACPI_HANDLE             GpeDevice,
610120945Snectar    UINT32                  GpeNumber,
611120945Snectar    UINT32                  Type,
612120945Snectar    ACPI_GPE_HANDLER        Handler,
613103423Snectar    void                    *Context)
614120945Snectar{
615103423Snectar    ACPI_STATUS             Status;
616120945Snectar    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
617103423Snectar
618120945Snectar
619120945Snectar    ACPI_FUNCTION_TRACE ("AcpiInstallGpeHandler");
620120945Snectar
621120945Snectar
622103423Snectar    /* Parameter validation */
623120945Snectar
624120945Snectar    if (!Handler)
625103423Snectar    {
626120945Snectar        return_ACPI_STATUS (AE_BAD_PARAMETER);
627102644Snectar    }
628120945Snectar
629102644Snectar    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
630120945Snectar    if (ACPI_FAILURE (Status))
631102644Snectar    {
632120945Snectar        return_ACPI_STATUS (Status);
633120945Snectar    }
634102644Snectar
635120945Snectar    /* Ensure that we have a valid GPE number */
636120945Snectar
63790926Snectar    GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
638120945Snectar    if (!GpeEventInfo)
63990926Snectar    {
640120945Snectar        Status = AE_BAD_PARAMETER;
641120945Snectar        goto UnlockAndExit;
64290926Snectar    }
643120945Snectar
644120945Snectar    /* Make sure that there isn't a handler there already */
645120945Snectar
64690926Snectar    if (GpeEventInfo->Handler)
647120945Snectar    {
64890926Snectar        Status = AE_ALREADY_EXISTS;
649120945Snectar        goto UnlockAndExit;
650120945Snectar    }
651120945Snectar
65290926Snectar    /* Install the handler */
653120945Snectar
654120945Snectar    AcpiOsAcquireLock (AcpiGbl_GpeLock, ACPI_NOT_ISR);
65590926Snectar    GpeEventInfo->Handler = Handler;
656120945Snectar    GpeEventInfo->Context = Context;
657120945Snectar    GpeEventInfo->Flags   = (UINT8) Type;
65890926Snectar    AcpiOsReleaseLock (AcpiGbl_GpeLock, ACPI_NOT_ISR);
659120945Snectar
66090926Snectar    /* Clear the GPE (of stale events), the enable it */
661120945Snectar
662120945Snectar    Status = AcpiHwClearGpe (GpeEventInfo);
663120945Snectar    if (ACPI_FAILURE (Status))
66490926Snectar    {
665120945Snectar        goto UnlockAndExit;
666120945Snectar    }
66790926Snectar
668120945Snectar    Status = AcpiHwEnableGpe (GpeEventInfo);
66990926Snectar
670120945Snectar
671120945SnectarUnlockAndExit:
67290926Snectar    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
673120945Snectar    return_ACPI_STATUS (Status);
67490926Snectar}
675120945Snectar
676120945Snectar
677120945Snectar/*******************************************************************************
678120945Snectar *
679120945Snectar * FUNCTION:    AcpiRemoveGpeHandler
680120945Snectar *
681120945Snectar * PARAMETERS:  GpeNumber       - The event to remove a handler
682120945Snectar *              GpeBlock        - GPE block (NULL == FADT GPEs)
68390926Snectar *              Handler         - Address of the handler
684120945Snectar *
68590926Snectar * RETURN:      Status
686120945Snectar *
68790926Snectar * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
688120945Snectar *
68990926Snectar ******************************************************************************/
690120945Snectar
69190926SnectarACPI_STATUS
692120945SnectarAcpiRemoveGpeHandler (
693120945Snectar    ACPI_HANDLE             GpeDevice,
694120945Snectar    UINT32                  GpeNumber,
695120945Snectar    ACPI_GPE_HANDLER        Handler)
696120945Snectar{
697120945Snectar    ACPI_STATUS             Status;
69890926Snectar    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
699120945Snectar
700120945Snectar
701120945Snectar    ACPI_FUNCTION_TRACE ("AcpiRemoveGpeHandler");
702120945Snectar
70390926Snectar
704120945Snectar    /* Parameter validation */
705120945Snectar
70690926Snectar    if (!Handler)
707120945Snectar    {
70890926Snectar        return_ACPI_STATUS (AE_BAD_PARAMETER);
709120945Snectar    }
710120945Snectar
71190926Snectar    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
712120945Snectar    if (ACPI_FAILURE (Status))
713120945Snectar    {
71490926Snectar        return_ACPI_STATUS (Status);
715120945Snectar    }
716120945Snectar
717120945Snectar    /* Ensure that we have a valid GPE number */
718120945Snectar
719120945Snectar    GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
720120945Snectar    if (!GpeEventInfo)
72190926Snectar    {
722120945Snectar        Status = AE_BAD_PARAMETER;
723120945Snectar        goto UnlockAndExit;
72490926Snectar    }
725120945Snectar
726120945Snectar    /* Disable the GPE before removing the handler */
727120945Snectar
72890926Snectar    Status = AcpiHwDisableGpe (GpeEventInfo);
729120945Snectar    if (ACPI_FAILURE (Status))
730120945Snectar    {
731120945Snectar        goto UnlockAndExit;
73290926Snectar    }
733120945Snectar
734120945Snectar    /* Make sure that the installed handler is the same */
73590926Snectar
736120945Snectar    if (GpeEventInfo->Handler != Handler)
73790926Snectar    {
738120945Snectar        (void) AcpiHwEnableGpe (GpeEventInfo);
739120945Snectar        Status = AE_BAD_PARAMETER;
740120945Snectar        goto UnlockAndExit;
74190926Snectar    }
742120945Snectar
74390926Snectar    /* Remove the handler */
744120945Snectar
74590926Snectar    AcpiOsAcquireLock (AcpiGbl_GpeLock, ACPI_NOT_ISR);
746120945Snectar    GpeEventInfo->Handler = NULL;
747120945Snectar    GpeEventInfo->Context = NULL;
748120945Snectar    AcpiOsReleaseLock (AcpiGbl_GpeLock, ACPI_NOT_ISR);
74990926Snectar
750120945Snectar
75190926SnectarUnlockAndExit:
752120945Snectar    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
753120945Snectar    return_ACPI_STATUS (Status);
754120945Snectar}
755120945Snectar
756120945Snectar
757120945Snectar/*******************************************************************************
75890926Snectar *
759120945Snectar * FUNCTION:    AcpiAcquireGlobalLock
76090926Snectar *
761120945Snectar * PARAMETERS:  Timeout         - How long the caller is willing to wait
762120945Snectar *              OutHandle       - A handle to the lock if acquired
763120945Snectar *
76490926Snectar * RETURN:      Status
765120945Snectar *
76690926Snectar * DESCRIPTION: Acquire the ACPI Global Lock
767120945Snectar *
768120945Snectar ******************************************************************************/
769120945Snectar
77090926SnectarACPI_STATUS
771120945SnectarAcpiAcquireGlobalLock (
772120945Snectar    UINT16                  Timeout,
773120945Snectar    UINT32                  *Handle)
774120945Snectar{
77590926Snectar    ACPI_STATUS             Status;
776120945Snectar
777120945Snectar
778120945Snectar    if (!Handle)
77990926Snectar    {
780120945Snectar        return (AE_BAD_PARAMETER);
781120945Snectar    }
78290926Snectar
783120945Snectar    Status = AcpiExEnterInterpreter ();
784120945Snectar    if (ACPI_FAILURE (Status))
785120945Snectar    {
78690926Snectar        return (Status);
787120945Snectar    }
78890926Snectar
789120945Snectar    Status = AcpiEvAcquireGlobalLock (Timeout);
790120945Snectar    AcpiExExitInterpreter ();
79190926Snectar
792120945Snectar    if (ACPI_SUCCESS (Status))
793120945Snectar    {
794120945Snectar        AcpiGbl_GlobalLockHandle++;
79590926Snectar        *Handle = AcpiGbl_GlobalLockHandle;
796120945Snectar    }
797120945Snectar
798120945Snectar    return (Status);
799120945Snectar}
80090926Snectar
801120945Snectar
802120945Snectar/*******************************************************************************
803120945Snectar *
804120945Snectar * FUNCTION:    AcpiReleaseGlobalLock
805120945Snectar *
806120945Snectar * PARAMETERS:  Handle      - Returned from AcpiAcquireGlobalLock
807120945Snectar *
808120945Snectar * RETURN:      Status
809120945Snectar *
810120945Snectar * DESCRIPTION: Release the ACPI Global Lock
81190926Snectar *
812120945Snectar ******************************************************************************/
813120945Snectar
81490926SnectarACPI_STATUS
815120945SnectarAcpiReleaseGlobalLock (
816120945Snectar    UINT32                  Handle)
81790926Snectar{
818120945Snectar    ACPI_STATUS             Status;
81990926Snectar
820120945Snectar
821120945Snectar    if (Handle != AcpiGbl_GlobalLockHandle)
82290926Snectar    {
823120945Snectar        return (AE_NOT_ACQUIRED);
824120945Snectar    }
825120945Snectar
826120945Snectar    Status = AcpiEvReleaseGlobalLock ();
82790926Snectar    return (Status);
828120945Snectar}
829120945Snectar
83090926Snectar
831120945Snectar