evxface.c revision 138287
167754Smsmith/******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: evxface - External interfaces for ACPI events
4138287Smarks *              $Revision: 147 $
567754Smsmith *
667754Smsmith *****************************************************************************/
767754Smsmith
867754Smsmith/******************************************************************************
967754Smsmith *
1067754Smsmith * 1. Copyright Notice
1167754Smsmith *
12126372Snjl * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp.
1370243Smsmith * All rights reserved.
1467754Smsmith *
1567754Smsmith * 2. License
1667754Smsmith *
1767754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property
1867754Smsmith * rights.  You may have additional license terms from the party that provided
1967754Smsmith * you this software, covering your right to use that party's intellectual
2067754Smsmith * property rights.
2167754Smsmith *
2267754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2367754Smsmith * copy of the source code appearing in this file ("Covered Code") an
2467754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2567754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy,
2667754Smsmith * make derivatives, distribute, use and display any portion of the Covered
2767754Smsmith * Code in any form, with the right to sublicense such rights; and
2867754Smsmith *
2967754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
3067754Smsmith * license (with the right to sublicense), under only those claims of Intel
3167754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell,
3267754Smsmith * offer to sell, and import the Covered Code and derivative works thereof
3367754Smsmith * solely to the minimum extent necessary to exercise the above copyright
3467754Smsmith * license, and in no event shall the patent license extend to any additions
3567754Smsmith * to or modifications of the Original Intel Code.  No other license or right
3667754Smsmith * is granted directly or by implication, estoppel or otherwise;
3767754Smsmith *
3867754Smsmith * The above copyright and patent license is granted only if the following
3967754Smsmith * conditions are met:
4067754Smsmith *
4167754Smsmith * 3. Conditions
4267754Smsmith *
4367754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4467754Smsmith * Redistribution of source code of any substantial prton of the Covered
4567754Smsmith * Code or modification with rights to further distribute source must include
4667754Smsmith * the above Copyright Notice, the above License, this list of Conditions,
4767754Smsmith * and the following Disclaimer and Export Compliance provision.  In addition,
4867754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to
4967754Smsmith * contain a file documenting the changes Licensee made to create that Covered
5067754Smsmith * Code and the date of any change.  Licensee must include in that file the
5167754Smsmith * documentation of any changes made by any predecessor Licensee.  Licensee
5267754Smsmith * must include a prominent statement that the modification is derived,
5367754Smsmith * directly or indirectly, from Original Intel Code.
5467754Smsmith *
5567754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5667754Smsmith * Redistribution of source code of any substantial portion of the Covered
5767754Smsmith * Code or modification without rights to further distribute source must
5867754Smsmith * include the following Disclaimer and Export Compliance provision in the
5967754Smsmith * documentation and/or other materials provided with distribution.  In
6067754Smsmith * addition, Licensee may not authorize further sublicense of source of any
6167754Smsmith * portion of the Covered Code, and must include terms to the effect that the
6267754Smsmith * license from Licensee to its licensee is limited to the intellectual
6367754Smsmith * property embodied in the software Licensee provides to its licensee, and
6467754Smsmith * not to intellectual property embodied in modifications its licensee may
6567754Smsmith * make.
6667754Smsmith *
6767754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any
6867754Smsmith * substantial portion of the Covered Code or modification must reproduce the
6967754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance
7067754Smsmith * provision in the documentation and/or other materials provided with the
7167754Smsmith * distribution.
7267754Smsmith *
7367754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original
7467754Smsmith * Intel Code.
7567754Smsmith *
7667754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7767754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or
7867754Smsmith * other dealings in products derived from or relating to the Covered Code
7967754Smsmith * without prior written authorization from Intel.
8067754Smsmith *
8167754Smsmith * 4. Disclaimer and Export Compliance
8267754Smsmith *
8367754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8467754Smsmith * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8567754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8667754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8767754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8867754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8967754Smsmith * PARTICULAR PURPOSE.
9067754Smsmith *
9167754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9267754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9367754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9467754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9567754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9667754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9767754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9867754Smsmith * LIMITED REMEDY.
9967754Smsmith *
10067754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this
10167754Smsmith * software or system incorporating such software without first obtaining any
10267754Smsmith * required license or other approval from the U. S. Department of Commerce or
10367754Smsmith * any other agency or department of the United States Government.  In the
10467754Smsmith * event Licensee exports any such software from the United States or
10567754Smsmith * re-exports any such software from a foreign destination, Licensee shall
10667754Smsmith * ensure that the distribution and export/re-export of the software is in
10767754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the
10867754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10967754Smsmith * any of its subsidiaries will export/re-export any technical data, process,
11067754Smsmith * software, or service, directly or indirectly, to any country for which the
11167754Smsmith * United States government or any agency thereof requires an export license,
11267754Smsmith * other governmental approval, or letter of assurance, without first obtaining
11367754Smsmith * such license, approval or letter.
11467754Smsmith *
11567754Smsmith *****************************************************************************/
11667754Smsmith
11767754Smsmith
11867754Smsmith#define __EVXFACE_C__
11967754Smsmith
12067754Smsmith#include "acpi.h"
12167754Smsmith#include "acnamesp.h"
12267754Smsmith#include "acevents.h"
12367754Smsmith#include "acinterp.h"
12467754Smsmith
12577424Smsmith#define _COMPONENT          ACPI_EVENTS
12691116Smsmith        ACPI_MODULE_NAME    ("evxface")
12767754Smsmith
12867754Smsmith
12977424Smsmith/*******************************************************************************
13067754Smsmith *
131138287Smarks * FUNCTION:    AcpiInstallExceptionHandler
132138287Smarks *
133138287Smarks * PARAMETERS:  Handler         - Pointer to the handler function for the
134138287Smarks *                                event
135138287Smarks *
136138287Smarks * RETURN:      Status
137138287Smarks *
138138287Smarks * DESCRIPTION: Saves the pointer to the handler function
139138287Smarks *
140138287Smarks ******************************************************************************/
141138287Smarks
142138287SmarksACPI_STATUS
143138287SmarksAcpiInstallExceptionHandler (
144138287Smarks    ACPI_EXCEPTION_HANDLER  Handler)
145138287Smarks{
146138287Smarks    ACPI_STATUS             Status;
147138287Smarks
148138287Smarks
149138287Smarks    ACPI_FUNCTION_TRACE ("AcpiInstallExceptionHandler");
150138287Smarks
151138287Smarks
152138287Smarks    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
153138287Smarks    if (ACPI_FAILURE (Status))
154138287Smarks    {
155138287Smarks        return_ACPI_STATUS (Status);
156138287Smarks    }
157138287Smarks
158138287Smarks    /* Don't allow two handlers. */
159138287Smarks
160138287Smarks    if (AcpiGbl_ExceptionHandler)
161138287Smarks    {
162138287Smarks        Status = AE_ALREADY_EXISTS;
163138287Smarks        goto Cleanup;
164138287Smarks    }
165138287Smarks
166138287Smarks    /* Install the handler */
167138287Smarks
168138287Smarks    AcpiGbl_ExceptionHandler = Handler;
169138287Smarks
170138287SmarksCleanup:
171138287Smarks    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
172138287Smarks    return_ACPI_STATUS (Status);
173138287Smarks}
174138287Smarks
175138287Smarks
176138287Smarks/*******************************************************************************
177138287Smarks *
17867754Smsmith * FUNCTION:    AcpiInstallFixedEventHandler
17967754Smsmith *
18067754Smsmith * PARAMETERS:  Event           - Event type to enable.
18167754Smsmith *              Handler         - Pointer to the handler function for the
18267754Smsmith *                                event
18367754Smsmith *              Context         - Value passed to the handler on each GPE
18467754Smsmith *
18567754Smsmith * RETURN:      Status
18667754Smsmith *
18767754Smsmith * DESCRIPTION: Saves the pointer to the handler function and then enables the
18867754Smsmith *              event.
18967754Smsmith *
19067754Smsmith ******************************************************************************/
19167754Smsmith
19267754SmsmithACPI_STATUS
19367754SmsmithAcpiInstallFixedEventHandler (
19467754Smsmith    UINT32                  Event,
19577424Smsmith    ACPI_EVENT_HANDLER      Handler,
19667754Smsmith    void                    *Context)
19767754Smsmith{
19877424Smsmith    ACPI_STATUS             Status;
19967754Smsmith
20067754Smsmith
20191116Smsmith    ACPI_FUNCTION_TRACE ("AcpiInstallFixedEventHandler");
20267754Smsmith
20367754Smsmith
20477424Smsmith    /* Parameter validation */
20577424Smsmith
20677424Smsmith    if (Event > ACPI_EVENT_MAX)
20777424Smsmith    {
20867754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
20967754Smsmith    }
21067754Smsmith
21191116Smsmith    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
21291116Smsmith    if (ACPI_FAILURE (Status))
21391116Smsmith    {
21491116Smsmith        return_ACPI_STATUS (Status);
21591116Smsmith    }
21667754Smsmith
21767754Smsmith    /* Don't allow two handlers. */
21867754Smsmith
21967754Smsmith    if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler)
22067754Smsmith    {
22187031Smsmith        Status = AE_ALREADY_EXISTS;
22267754Smsmith        goto Cleanup;
22367754Smsmith    }
22467754Smsmith
22585756Smsmith    /* Install the handler before enabling the event */
22667754Smsmith
22767754Smsmith    AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
22867754Smsmith    AcpiGbl_FixedEventHandlers[Event].Context = Context;
22967754Smsmith
230117521Snjl    Status = AcpiEnableEvent (Event, 0);
23191116Smsmith    if (ACPI_FAILURE (Status))
23267754Smsmith    {
23382367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n"));
23467754Smsmith
23567754Smsmith        /* Remove the handler */
23667754Smsmith
23767754Smsmith        AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
23867754Smsmith        AcpiGbl_FixedEventHandlers[Event].Context = NULL;
23977424Smsmith    }
24077424Smsmith    else
24177424Smsmith    {
24282367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
24382367Smsmith            "Enabled fixed event %X, Handler=%p\n", Event, Handler));
24467754Smsmith    }
24567754Smsmith
24667754Smsmith
24767754SmsmithCleanup:
24891116Smsmith    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
24967754Smsmith    return_ACPI_STATUS (Status);
25067754Smsmith}
25167754Smsmith
25267754Smsmith
25377424Smsmith/*******************************************************************************
25467754Smsmith *
25567754Smsmith * FUNCTION:    AcpiRemoveFixedEventHandler
25667754Smsmith *
25767754Smsmith * PARAMETERS:  Event           - Event type to disable.
25867754Smsmith *              Handler         - Address of the handler
25967754Smsmith *
26067754Smsmith * RETURN:      Status
26167754Smsmith *
26267754Smsmith * DESCRIPTION: Disables the event and unregisters the event handler.
26367754Smsmith *
26467754Smsmith ******************************************************************************/
26567754Smsmith
26667754SmsmithACPI_STATUS
26767754SmsmithAcpiRemoveFixedEventHandler (
26867754Smsmith    UINT32                  Event,
26977424Smsmith    ACPI_EVENT_HANDLER      Handler)
27067754Smsmith{
27167754Smsmith    ACPI_STATUS             Status = AE_OK;
27267754Smsmith
27367754Smsmith
27491116Smsmith    ACPI_FUNCTION_TRACE ("AcpiRemoveFixedEventHandler");
27567754Smsmith
27667754Smsmith
27777424Smsmith    /* Parameter validation */
27877424Smsmith
27977424Smsmith    if (Event > ACPI_EVENT_MAX)
28077424Smsmith    {
28167754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
28267754Smsmith    }
28367754Smsmith
28491116Smsmith    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
28591116Smsmith    if (ACPI_FAILURE (Status))
28691116Smsmith    {
28791116Smsmith        return_ACPI_STATUS (Status);
28891116Smsmith    }
28967754Smsmith
29085756Smsmith    /* Disable the event before removing the handler */
29167754Smsmith
292117521Snjl    Status = AcpiDisableEvent (Event, 0);
29369450Smsmith
29477424Smsmith    /* Always Remove the handler */
29577424Smsmith
29677424Smsmith    AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
29777424Smsmith    AcpiGbl_FixedEventHandlers[Event].Context = NULL;
29877424Smsmith
29991116Smsmith    if (ACPI_FAILURE (Status))
30067754Smsmith    {
30182367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
30282367Smsmith            "Could not write to fixed event enable register.\n"));
30377424Smsmith    }
30477424Smsmith    else
30577424Smsmith    {
30682367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X.\n", Event));
30767754Smsmith    }
30867754Smsmith
30991116Smsmith    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
31067754Smsmith    return_ACPI_STATUS (Status);
31167754Smsmith}
31267754Smsmith
31367754Smsmith
31477424Smsmith/*******************************************************************************
31567754Smsmith *
31667754Smsmith * FUNCTION:    AcpiInstallNotifyHandler
31767754Smsmith *
31867754Smsmith * PARAMETERS:  Device          - The device for which notifies will be handled
31967754Smsmith *              HandlerType     - The type of handler:
32067754Smsmith *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
32167754Smsmith *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
322129684Snjl *                                  ACPI_ALL_NOTIFY:  both system and device
32367754Smsmith *              Handler         - Address of the handler
32467754Smsmith *              Context         - Value passed to the handler on each GPE
32567754Smsmith *
32667754Smsmith * RETURN:      Status
32767754Smsmith *
32867754Smsmith * DESCRIPTION: Install a handler for notifies on an ACPI device
32967754Smsmith *
33067754Smsmith ******************************************************************************/
33167754Smsmith
33267754SmsmithACPI_STATUS
33367754SmsmithAcpiInstallNotifyHandler (
33467754Smsmith    ACPI_HANDLE             Device,
33567754Smsmith    UINT32                  HandlerType,
33677424Smsmith    ACPI_NOTIFY_HANDLER     Handler,
33767754Smsmith    void                    *Context)
33867754Smsmith{
33967754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
34067754Smsmith    ACPI_OPERAND_OBJECT     *NotifyObj;
34199146Siwasaki    ACPI_NAMESPACE_NODE     *Node;
34291116Smsmith    ACPI_STATUS             Status;
34367754Smsmith
34467754Smsmith
34591116Smsmith    ACPI_FUNCTION_TRACE ("AcpiInstallNotifyHandler");
34667754Smsmith
34767754Smsmith
34867754Smsmith    /* Parameter validation */
34967754Smsmith
35099146Siwasaki    if ((!Device)  ||
35199146Siwasaki        (!Handler) ||
35267754Smsmith        (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
35367754Smsmith    {
35467754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
35567754Smsmith    }
35667754Smsmith
35791116Smsmith    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
35891116Smsmith    if (ACPI_FAILURE (Status))
35991116Smsmith    {
36091116Smsmith        return_ACPI_STATUS (Status);
36191116Smsmith    }
36271867Smsmith
36367754Smsmith    /* Convert and validate the device handle */
36467754Smsmith
36599146Siwasaki    Node = AcpiNsMapHandleToNode (Device);
36699146Siwasaki    if (!Node)
36767754Smsmith    {
36867754Smsmith        Status = AE_BAD_PARAMETER;
36967754Smsmith        goto UnlockAndExit;
37067754Smsmith    }
37167754Smsmith
37267754Smsmith    /*
37371867Smsmith     * Root Object:
37471867Smsmith     * Registering a notify handler on the root object indicates that the
37571867Smsmith     * caller wishes to receive notifications for all objects.  Note that
37671867Smsmith     * only one <external> global handler can be regsitered (per notify type).
37767754Smsmith     */
37867754Smsmith    if (Device == ACPI_ROOT_OBJECT)
37967754Smsmith    {
38071867Smsmith        /* Make sure the handler is not already installed */
38167754Smsmith
382129684Snjl        if (((HandlerType & ACPI_SYSTEM_NOTIFY) &&
383129684Snjl                AcpiGbl_SystemNotify.Handler)       ||
384129684Snjl            ((HandlerType & ACPI_DEVICE_NOTIFY) &&
385117521Snjl                AcpiGbl_DeviceNotify.Handler))
38667754Smsmith        {
38787031Smsmith            Status = AE_ALREADY_EXISTS;
38867754Smsmith            goto UnlockAndExit;
38967754Smsmith        }
39067754Smsmith
391129684Snjl        if (HandlerType & ACPI_SYSTEM_NOTIFY)
39267754Smsmith        {
393117521Snjl            AcpiGbl_SystemNotify.Node    = Node;
394117521Snjl            AcpiGbl_SystemNotify.Handler = Handler;
395117521Snjl            AcpiGbl_SystemNotify.Context = Context;
39667754Smsmith        }
397129684Snjl
398129684Snjl        if (HandlerType & ACPI_DEVICE_NOTIFY)
39967754Smsmith        {
400117521Snjl            AcpiGbl_DeviceNotify.Node    = Node;
401117521Snjl            AcpiGbl_DeviceNotify.Handler = Handler;
402117521Snjl            AcpiGbl_DeviceNotify.Context = Context;
40367754Smsmith        }
40467754Smsmith
40567754Smsmith        /* Global notify handler installed */
40667754Smsmith    }
40767754Smsmith
40867754Smsmith    /*
40985756Smsmith     * All Other Objects:
41071867Smsmith     * Caller will only receive notifications specific to the target object.
41171867Smsmith     * Note that only certain object types can receive notifications.
41267754Smsmith     */
41387031Smsmith    else
41485756Smsmith    {
41599146Siwasaki        /* Notifies allowed on this object? */
41699146Siwasaki
41799146Siwasaki        if (!AcpiEvIsNotifyObject (Node))
41867754Smsmith        {
41999146Siwasaki            Status = AE_TYPE;
42067754Smsmith            goto UnlockAndExit;
42167754Smsmith        }
42267754Smsmith
42371867Smsmith        /* Check for an existing internal object */
42467754Smsmith
42599146Siwasaki        ObjDesc = AcpiNsGetAttachedObject (Node);
42671867Smsmith        if (ObjDesc)
42767754Smsmith        {
42871867Smsmith            /* Object exists - make sure there's no handler */
42971867Smsmith
430129684Snjl            if (((HandlerType & ACPI_SYSTEM_NOTIFY) &&
431117521Snjl                    ObjDesc->CommonNotify.SystemNotify)   ||
432129684Snjl                ((HandlerType & ACPI_DEVICE_NOTIFY) &&
433117521Snjl                    ObjDesc->CommonNotify.DeviceNotify))
43471867Smsmith            {
43587031Smsmith                Status = AE_ALREADY_EXISTS;
43671867Smsmith                goto UnlockAndExit;
43771867Smsmith            }
43867754Smsmith        }
43971867Smsmith        else
44071867Smsmith        {
44171867Smsmith            /* Create a new object */
44267754Smsmith
44399146Siwasaki            ObjDesc = AcpiUtCreateInternalObject (Node->Type);
44471867Smsmith            if (!ObjDesc)
44571867Smsmith            {
44671867Smsmith                Status = AE_NO_MEMORY;
44771867Smsmith                goto UnlockAndExit;
44871867Smsmith            }
44967754Smsmith
45071867Smsmith            /* Attach new object to the Node */
45171867Smsmith
45299146Siwasaki            Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
453117521Snjl
454117521Snjl            /* Remove local reference to the object */
455117521Snjl
456117521Snjl            AcpiUtRemoveReference (ObjDesc);
45771867Smsmith            if (ACPI_FAILURE (Status))
45871867Smsmith            {
45971867Smsmith                goto UnlockAndExit;
46071867Smsmith            }
46171867Smsmith        }
46271867Smsmith
46371867Smsmith        /* Install the handler */
46471867Smsmith
465107325Siwasaki        NotifyObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
46671867Smsmith        if (!NotifyObj)
46767754Smsmith        {
46871867Smsmith            Status = AE_NO_MEMORY;
46967754Smsmith            goto UnlockAndExit;
47067754Smsmith        }
47167754Smsmith
472117521Snjl        NotifyObj->Notify.Node    = Node;
473117521Snjl        NotifyObj->Notify.Handler = Handler;
474117521Snjl        NotifyObj->Notify.Context = Context;
47567754Smsmith
476129684Snjl        if (HandlerType & ACPI_SYSTEM_NOTIFY)
47771867Smsmith        {
478117521Snjl            ObjDesc->CommonNotify.SystemNotify = NotifyObj;
47971867Smsmith        }
480129684Snjl
481129684Snjl        if (HandlerType & ACPI_DEVICE_NOTIFY)
48271867Smsmith        {
483117521Snjl            ObjDesc->CommonNotify.DeviceNotify = NotifyObj;
48471867Smsmith        }
485129684Snjl
486129684Snjl        if (HandlerType == ACPI_ALL_NOTIFY)
487129684Snjl        {
488129684Snjl            /* Extra ref if installed in both */
489129684Snjl
490129684Snjl            AcpiUtAddReference (NotifyObj);
491129684Snjl        }
49267754Smsmith    }
49367754Smsmith
49485756Smsmith
49567754SmsmithUnlockAndExit:
49691116Smsmith    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
49767754Smsmith    return_ACPI_STATUS (Status);
49867754Smsmith}
49967754Smsmith
50067754Smsmith
50177424Smsmith/*******************************************************************************
50267754Smsmith *
50367754Smsmith * FUNCTION:    AcpiRemoveNotifyHandler
50467754Smsmith *
50567754Smsmith * PARAMETERS:  Device          - The device for which notifies will be handled
50667754Smsmith *              HandlerType     - The type of handler:
50767754Smsmith *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
50867754Smsmith *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
509129684Snjl *                                  ACPI_ALL_NOTIFY:  both system and device
51067754Smsmith *              Handler         - Address of the handler
511138287Smarks *
51267754Smsmith * RETURN:      Status
51367754Smsmith *
51467754Smsmith * DESCRIPTION: Remove a handler for notifies on an ACPI device
51567754Smsmith *
51667754Smsmith ******************************************************************************/
51767754Smsmith
51867754SmsmithACPI_STATUS
51967754SmsmithAcpiRemoveNotifyHandler (
52067754Smsmith    ACPI_HANDLE             Device,
52167754Smsmith    UINT32                  HandlerType,
52277424Smsmith    ACPI_NOTIFY_HANDLER     Handler)
52367754Smsmith{
52467754Smsmith    ACPI_OPERAND_OBJECT     *NotifyObj;
52567754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
52699146Siwasaki    ACPI_NAMESPACE_NODE     *Node;
52791116Smsmith    ACPI_STATUS             Status;
52867754Smsmith
52977424Smsmith
53091116Smsmith    ACPI_FUNCTION_TRACE ("AcpiRemoveNotifyHandler");
53167754Smsmith
53277424Smsmith
53367754Smsmith    /* Parameter validation */
53467754Smsmith
53599146Siwasaki    if ((!Device)  ||
53699146Siwasaki        (!Handler) ||
53767754Smsmith        (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
53867754Smsmith    {
53967754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
54067754Smsmith    }
54167754Smsmith
54291116Smsmith    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
54391116Smsmith    if (ACPI_FAILURE (Status))
54491116Smsmith    {
54591116Smsmith        return_ACPI_STATUS (Status);
54691116Smsmith    }
54767754Smsmith
54867754Smsmith    /* Convert and validate the device handle */
54967754Smsmith
55099146Siwasaki    Node = AcpiNsMapHandleToNode (Device);
55199146Siwasaki    if (!Node)
55267754Smsmith    {
55367754Smsmith        Status = AE_BAD_PARAMETER;
55467754Smsmith        goto UnlockAndExit;
55567754Smsmith    }
55667754Smsmith
557138287Smarks    /* Root Object */
558138287Smarks
55987031Smsmith    if (Device == ACPI_ROOT_OBJECT)
56085756Smsmith    {
56182367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
56267754Smsmith
563129684Snjl        if (((HandlerType & ACPI_SYSTEM_NOTIFY) &&
564129684Snjl              !AcpiGbl_SystemNotify.Handler)        ||
565129684Snjl            ((HandlerType & ACPI_DEVICE_NOTIFY) &&
566117521Snjl              !AcpiGbl_DeviceNotify.Handler))
56771867Smsmith        {
56871867Smsmith            Status = AE_NOT_EXIST;
56971867Smsmith            goto UnlockAndExit;
57071867Smsmith        }
57167754Smsmith
572129684Snjl        if (HandlerType & ACPI_SYSTEM_NOTIFY)
57385756Smsmith        {
574117521Snjl            AcpiGbl_SystemNotify.Node    = NULL;
575117521Snjl            AcpiGbl_SystemNotify.Handler = NULL;
576117521Snjl            AcpiGbl_SystemNotify.Context = NULL;
57771867Smsmith        }
578129684Snjl
579129684Snjl        if (HandlerType & ACPI_DEVICE_NOTIFY)
58085756Smsmith        {
581117521Snjl            AcpiGbl_DeviceNotify.Node    = NULL;
582117521Snjl            AcpiGbl_DeviceNotify.Handler = NULL;
583117521Snjl            AcpiGbl_DeviceNotify.Context = NULL;
58471867Smsmith        }
58567754Smsmith    }
58667754Smsmith
587138287Smarks    /* All Other Objects */
588138287Smarks
58987031Smsmith    else
59085756Smsmith    {
59199146Siwasaki        /* Notifies allowed on this object? */
59299146Siwasaki
59399146Siwasaki        if (!AcpiEvIsNotifyObject (Node))
59471867Smsmith        {
59599146Siwasaki            Status = AE_TYPE;
59671867Smsmith            goto UnlockAndExit;
59771867Smsmith        }
59867754Smsmith
59971867Smsmith        /* Check for an existing internal object */
60067754Smsmith
60199146Siwasaki        ObjDesc = AcpiNsGetAttachedObject (Node);
60271867Smsmith        if (!ObjDesc)
60371867Smsmith        {
60471867Smsmith            Status = AE_NOT_EXIST;
60571867Smsmith            goto UnlockAndExit;
60671867Smsmith        }
60767754Smsmith
60871867Smsmith        /* Object exists - make sure there's an existing handler */
60971867Smsmith
610129684Snjl        if (HandlerType & ACPI_SYSTEM_NOTIFY)
61171867Smsmith        {
612117521Snjl            NotifyObj = ObjDesc->CommonNotify.SystemNotify;
613129684Snjl            if ((!NotifyObj) ||
614129684Snjl                 (NotifyObj->Notify.Handler != Handler))
615129684Snjl            {
616129684Snjl                Status = AE_BAD_PARAMETER;
617129684Snjl                goto UnlockAndExit;
618129684Snjl            }
619129684Snjl
620129684Snjl            /* Remove the handler */
621129684Snjl
622129684Snjl            ObjDesc->CommonNotify.SystemNotify = NULL;
623129684Snjl            AcpiUtRemoveReference (NotifyObj);
62471867Smsmith        }
625129684Snjl
626129684Snjl        if (HandlerType & ACPI_DEVICE_NOTIFY)
62771867Smsmith        {
628117521Snjl            NotifyObj = ObjDesc->CommonNotify.DeviceNotify;
629129684Snjl            if ((!NotifyObj) ||
630129684Snjl                 (NotifyObj->Notify.Handler != Handler))
631129684Snjl            {
632129684Snjl                Status = AE_BAD_PARAMETER;
633129684Snjl                goto UnlockAndExit;
634129684Snjl            }
63571867Smsmith
636129684Snjl            /* Remove the handler */
63771867Smsmith
638117521Snjl            ObjDesc->CommonNotify.DeviceNotify = NULL;
639129684Snjl            AcpiUtRemoveReference (NotifyObj);
64071867Smsmith        }
64167754Smsmith    }
64267754Smsmith
64367754Smsmith
64467754SmsmithUnlockAndExit:
64591116Smsmith    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
64667754Smsmith    return_ACPI_STATUS (Status);
64767754Smsmith}
64867754Smsmith
64971867Smsmith
65077424Smsmith/*******************************************************************************
65167754Smsmith *
65267754Smsmith * FUNCTION:    AcpiInstallGpeHandler
65367754Smsmith *
654117521Snjl * PARAMETERS:  GpeNumber       - The GPE number within the GPE block
655117521Snjl *              GpeBlock        - GPE block (NULL == FADT GPEs)
65667754Smsmith *              Type            - Whether this GPE should be treated as an
65767754Smsmith *                                edge- or level-triggered interrupt.
658129684Snjl *              Address         - Address of the handler
65967754Smsmith *              Context         - Value passed to the handler on each GPE
66067754Smsmith *
66167754Smsmith * RETURN:      Status
66267754Smsmith *
66367754Smsmith * DESCRIPTION: Install a handler for a General Purpose Event.
66467754Smsmith *
66567754Smsmith ******************************************************************************/
66667754Smsmith
66767754SmsmithACPI_STATUS
66867754SmsmithAcpiInstallGpeHandler (
669117521Snjl    ACPI_HANDLE             GpeDevice,
67067754Smsmith    UINT32                  GpeNumber,
67167754Smsmith    UINT32                  Type,
672129684Snjl    ACPI_EVENT_HANDLER      Address,
67367754Smsmith    void                    *Context)
67467754Smsmith{
675129684Snjl    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
676129684Snjl    ACPI_HANDLER_INFO       *Handler;
67791116Smsmith    ACPI_STATUS             Status;
67867754Smsmith
67977424Smsmith
68091116Smsmith    ACPI_FUNCTION_TRACE ("AcpiInstallGpeHandler");
68167754Smsmith
68277424Smsmith
68367754Smsmith    /* Parameter validation */
68467754Smsmith
685129684Snjl    if ((!Address) || (Type > ACPI_GPE_XRUPT_TYPE_MASK))
68667754Smsmith    {
68767754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
68867754Smsmith    }
68967754Smsmith
690117521Snjl    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
691117521Snjl    if (ACPI_FAILURE (Status))
692117521Snjl    {
693117521Snjl        return_ACPI_STATUS (Status);
694117521Snjl    }
695117521Snjl
69667754Smsmith    /* Ensure that we have a valid GPE number */
69767754Smsmith
698117521Snjl    GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
699114237Snjl    if (!GpeEventInfo)
70067754Smsmith    {
701117521Snjl        Status = AE_BAD_PARAMETER;
702117521Snjl        goto UnlockAndExit;
70367754Smsmith    }
70467754Smsmith
70567754Smsmith    /* Make sure that there isn't a handler there already */
70667754Smsmith
707129684Snjl    if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER)
70867754Smsmith    {
70987031Smsmith        Status = AE_ALREADY_EXISTS;
710117521Snjl        goto UnlockAndExit;
71167754Smsmith    }
71267754Smsmith
713129684Snjl    /* Allocate and init handler object */
71467754Smsmith
715129684Snjl    Handler = ACPI_MEM_CALLOCATE (sizeof (ACPI_HANDLER_INFO));
716129684Snjl    if (!Handler)
717129684Snjl    {
718129684Snjl        Status = AE_NO_MEMORY;
719129684Snjl        goto UnlockAndExit;
720129684Snjl    }
72167754Smsmith
722129684Snjl    Handler->Address    = Address;
723129684Snjl    Handler->Context    = Context;
724129684Snjl    Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;
72567754Smsmith
726129684Snjl    /* Disable the GPE before installing the handler */
727129684Snjl
728129684Snjl    Status = AcpiEvDisableGpe (GpeEventInfo);
72999679Siwasaki    if (ACPI_FAILURE (Status))
73099679Siwasaki    {
731117521Snjl        goto UnlockAndExit;
73299679Siwasaki    }
73367754Smsmith
734129684Snjl    /* Install the handler */
73585756Smsmith
736129684Snjl    AcpiOsAcquireLock (AcpiGbl_GpeLock, ACPI_NOT_ISR);
737129684Snjl    GpeEventInfo->Dispatch.Handler = Handler;
73899679Siwasaki
739129684Snjl    /* Setup up dispatch flags to indicate handler (vs. method) */
740129684Snjl
741129684Snjl    GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);  /* Clear bits */
742129684Snjl    GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER);
743129684Snjl
744129684Snjl    AcpiOsReleaseLock (AcpiGbl_GpeLock, ACPI_NOT_ISR);
745129684Snjl
746129684Snjl
747117521SnjlUnlockAndExit:
74891116Smsmith    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
74967754Smsmith    return_ACPI_STATUS (Status);
75067754Smsmith}
75167754Smsmith
75267754Smsmith
75377424Smsmith/*******************************************************************************
75467754Smsmith *
75567754Smsmith * FUNCTION:    AcpiRemoveGpeHandler
75667754Smsmith *
75767754Smsmith * PARAMETERS:  GpeNumber       - The event to remove a handler
758117521Snjl *              GpeBlock        - GPE block (NULL == FADT GPEs)
759129684Snjl *              Address         - Address of the handler
76067754Smsmith *
76167754Smsmith * RETURN:      Status
76267754Smsmith *
76367754Smsmith * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
76467754Smsmith *
76567754Smsmith ******************************************************************************/
76667754Smsmith
76767754SmsmithACPI_STATUS
76867754SmsmithAcpiRemoveGpeHandler (
769117521Snjl    ACPI_HANDLE             GpeDevice,
77067754Smsmith    UINT32                  GpeNumber,
771129684Snjl    ACPI_EVENT_HANDLER      Address)
77267754Smsmith{
773129684Snjl    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
774129684Snjl    ACPI_HANDLER_INFO       *Handler;
77591116Smsmith    ACPI_STATUS             Status;
77667754Smsmith
77767754Smsmith
77891116Smsmith    ACPI_FUNCTION_TRACE ("AcpiRemoveGpeHandler");
77967754Smsmith
78067754Smsmith
78167754Smsmith    /* Parameter validation */
78267754Smsmith
783129684Snjl    if (!Address)
78467754Smsmith    {
78567754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
78667754Smsmith    }
78767754Smsmith
788117521Snjl    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
789117521Snjl    if (ACPI_FAILURE (Status))
790117521Snjl    {
791117521Snjl        return_ACPI_STATUS (Status);
792117521Snjl    }
793117521Snjl
79467754Smsmith    /* Ensure that we have a valid GPE number */
79567754Smsmith
796117521Snjl    GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
797114237Snjl    if (!GpeEventInfo)
79867754Smsmith    {
799117521Snjl        Status = AE_BAD_PARAMETER;
800117521Snjl        goto UnlockAndExit;
80167754Smsmith    }
80267754Smsmith
803129684Snjl    /* Make sure that a handler is indeed installed */
80467754Smsmith
805129684Snjl    if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) != ACPI_GPE_DISPATCH_HANDLER)
80699679Siwasaki    {
807129684Snjl        Status = AE_NOT_EXIST;
808117521Snjl        goto UnlockAndExit;
80999679Siwasaki    }
81067754Smsmith
81167754Smsmith    /* Make sure that the installed handler is the same */
81267754Smsmith
813129684Snjl    if (GpeEventInfo->Dispatch.Handler->Address != Address)
81467754Smsmith    {
81567754Smsmith        Status = AE_BAD_PARAMETER;
816117521Snjl        goto UnlockAndExit;
81767754Smsmith    }
81867754Smsmith
819129684Snjl    /* Disable the GPE before removing the handler */
820129684Snjl
821129684Snjl    Status = AcpiEvDisableGpe (GpeEventInfo);
822129684Snjl    if (ACPI_FAILURE (Status))
823129684Snjl    {
824129684Snjl        goto UnlockAndExit;
825129684Snjl    }
826129684Snjl
82767754Smsmith    /* Remove the handler */
82867754Smsmith
829117521Snjl    AcpiOsAcquireLock (AcpiGbl_GpeLock, ACPI_NOT_ISR);
830129684Snjl    Handler = GpeEventInfo->Dispatch.Handler;
831129684Snjl
832129684Snjl    /* Restore Method node (if any), set dispatch flags */
833129684Snjl
834129684Snjl    GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode;
835129684Snjl    GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;  /* Clear bits */
836129684Snjl    if (Handler->MethodNode)
837129684Snjl    {
838129684Snjl        GpeEventInfo->Flags |= ACPI_GPE_DISPATCH_METHOD;
839129684Snjl    }
840117521Snjl    AcpiOsReleaseLock (AcpiGbl_GpeLock, ACPI_NOT_ISR);
84167754Smsmith
842129684Snjl    /* Now we can free the handler object */
84385756Smsmith
844129684Snjl    ACPI_MEM_FREE (Handler);
845129684Snjl
846129684Snjl
847117521SnjlUnlockAndExit:
84891116Smsmith    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
84967754Smsmith    return_ACPI_STATUS (Status);
85067754Smsmith}
85167754Smsmith
85267754Smsmith
85377424Smsmith/*******************************************************************************
85467754Smsmith *
85567754Smsmith * FUNCTION:    AcpiAcquireGlobalLock
85667754Smsmith *
85767754Smsmith * PARAMETERS:  Timeout         - How long the caller is willing to wait
85867754Smsmith *              OutHandle       - A handle to the lock if acquired
85967754Smsmith *
86067754Smsmith * RETURN:      Status
86167754Smsmith *
86267754Smsmith * DESCRIPTION: Acquire the ACPI Global Lock
86367754Smsmith *
86467754Smsmith ******************************************************************************/
86585756Smsmith
86667754SmsmithACPI_STATUS
86767754SmsmithAcpiAcquireGlobalLock (
868107325Siwasaki    UINT16                  Timeout,
86991116Smsmith    UINT32                  *Handle)
87067754Smsmith{
87167754Smsmith    ACPI_STATUS             Status;
87267754Smsmith
87367754Smsmith
87491116Smsmith    if (!Handle)
87591116Smsmith    {
87691116Smsmith        return (AE_BAD_PARAMETER);
87791116Smsmith    }
87891116Smsmith
87977424Smsmith    Status = AcpiExEnterInterpreter ();
88077424Smsmith    if (ACPI_FAILURE (Status))
88177424Smsmith    {
88277424Smsmith        return (Status);
88377424Smsmith    }
88477424Smsmith
88591116Smsmith    Status = AcpiEvAcquireGlobalLock (Timeout);
88677424Smsmith    AcpiExExitInterpreter ();
88767754Smsmith
88891116Smsmith    if (ACPI_SUCCESS (Status))
88991116Smsmith    {
89091116Smsmith        AcpiGbl_GlobalLockHandle++;
89191116Smsmith        *Handle = AcpiGbl_GlobalLockHandle;
89291116Smsmith    }
89391116Smsmith
89467754Smsmith    return (Status);
89567754Smsmith}
89667754Smsmith
89767754Smsmith
89877424Smsmith/*******************************************************************************
89967754Smsmith *
90067754Smsmith * FUNCTION:    AcpiReleaseGlobalLock
90167754Smsmith *
90267754Smsmith * PARAMETERS:  Handle      - Returned from AcpiAcquireGlobalLock
90367754Smsmith *
90467754Smsmith * RETURN:      Status
90567754Smsmith *
90667754Smsmith * DESCRIPTION: Release the ACPI Global Lock
90767754Smsmith *
90867754Smsmith ******************************************************************************/
90967754Smsmith
91067754SmsmithACPI_STATUS
91167754SmsmithAcpiReleaseGlobalLock (
91291116Smsmith    UINT32                  Handle)
91367754Smsmith{
91499679Siwasaki    ACPI_STATUS             Status;
91585756Smsmith
91699679Siwasaki
91791116Smsmith    if (Handle != AcpiGbl_GlobalLockHandle)
91891116Smsmith    {
91991116Smsmith        return (AE_NOT_ACQUIRED);
92091116Smsmith    }
92191116Smsmith
92299679Siwasaki    Status = AcpiEvReleaseGlobalLock ();
92399679Siwasaki    return (Status);
92467754Smsmith}
92567754Smsmith
92667754Smsmith
927