evxface.c revision 99679
1/******************************************************************************
2 *
3 * Module Name: evxface - External interfaces for ACPI events
4 *              $Revision: 129 $
5 *
6 *****************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp.
13 * All rights reserved.
14 *
15 * 2. License
16 *
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights.  You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
20 * property rights.
21 *
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
28 *
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code.  No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
37 *
38 * The above copyright and patent license is granted only if the following
39 * conditions are met:
40 *
41 * 3. Conditions
42 *
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial prton of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision.  In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change.  Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee.  Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
54 *
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution.  In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
65 * make.
66 *
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3.4. Intel retains all right, title, and interest in and to the Original
74 * Intel Code.
75 *
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
80 *
81 * 4. Disclaimer and Export Compliance
82 *
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 * PARTICULAR PURPOSE.
90 *
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 * LIMITED REMEDY.
99 *
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government.  In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************/
116
117
118#define __EVXFACE_C__
119
120#include "acpi.h"
121#include "acnamesp.h"
122#include "acevents.h"
123#include "acinterp.h"
124
125#define _COMPONENT          ACPI_EVENTS
126        ACPI_MODULE_NAME    ("evxface")
127
128
129
130/*******************************************************************************
131 *
132 * FUNCTION:    AcpiInstallFixedEventHandler
133 *
134 * PARAMETERS:  Event           - Event type to enable.
135 *              Handler         - Pointer to the handler function for the
136 *                                event
137 *              Context         - Value passed to the handler on each GPE
138 *
139 * RETURN:      Status
140 *
141 * DESCRIPTION: Saves the pointer to the handler function and then enables the
142 *              event.
143 *
144 ******************************************************************************/
145
146ACPI_STATUS
147AcpiInstallFixedEventHandler (
148    UINT32                  Event,
149    ACPI_EVENT_HANDLER      Handler,
150    void                    *Context)
151{
152    ACPI_STATUS             Status;
153
154
155    ACPI_FUNCTION_TRACE ("AcpiInstallFixedEventHandler");
156
157
158    /* Parameter validation */
159
160    if (Event > ACPI_EVENT_MAX)
161    {
162        return_ACPI_STATUS (AE_BAD_PARAMETER);
163    }
164
165    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
166    if (ACPI_FAILURE (Status))
167    {
168        return_ACPI_STATUS (Status);
169    }
170
171    /* Don't allow two handlers. */
172
173    if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler)
174    {
175        Status = AE_ALREADY_EXISTS;
176        goto Cleanup;
177    }
178
179    /* Install the handler before enabling the event */
180
181    AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
182    AcpiGbl_FixedEventHandlers[Event].Context = Context;
183
184    Status = AcpiEnableEvent (Event, ACPI_EVENT_FIXED, 0);
185    if (ACPI_FAILURE (Status))
186    {
187        ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n"));
188
189        /* Remove the handler */
190
191        AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
192        AcpiGbl_FixedEventHandlers[Event].Context = NULL;
193    }
194    else
195    {
196        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
197            "Enabled fixed event %X, Handler=%p\n", Event, Handler));
198    }
199
200
201Cleanup:
202    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
203    return_ACPI_STATUS (Status);
204}
205
206
207/*******************************************************************************
208 *
209 * FUNCTION:    AcpiRemoveFixedEventHandler
210 *
211 * PARAMETERS:  Event           - Event type to disable.
212 *              Handler         - Address of the handler
213 *
214 * RETURN:      Status
215 *
216 * DESCRIPTION: Disables the event and unregisters the event handler.
217 *
218 ******************************************************************************/
219
220ACPI_STATUS
221AcpiRemoveFixedEventHandler (
222    UINT32                  Event,
223    ACPI_EVENT_HANDLER      Handler)
224{
225    ACPI_STATUS             Status = AE_OK;
226
227
228    ACPI_FUNCTION_TRACE ("AcpiRemoveFixedEventHandler");
229
230
231    /* Parameter validation */
232
233    if (Event > ACPI_EVENT_MAX)
234    {
235        return_ACPI_STATUS (AE_BAD_PARAMETER);
236    }
237
238    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
239    if (ACPI_FAILURE (Status))
240    {
241        return_ACPI_STATUS (Status);
242    }
243
244    /* Disable the event before removing the handler */
245
246    Status = AcpiDisableEvent(Event, ACPI_EVENT_FIXED, 0);
247
248    /* Always Remove the handler */
249
250    AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
251    AcpiGbl_FixedEventHandlers[Event].Context = NULL;
252
253    if (ACPI_FAILURE (Status))
254    {
255        ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
256            "Could not write to fixed event enable register.\n"));
257    }
258    else
259    {
260        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X.\n", Event));
261    }
262
263    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
264    return_ACPI_STATUS (Status);
265}
266
267
268/*******************************************************************************
269 *
270 * FUNCTION:    AcpiInstallNotifyHandler
271 *
272 * PARAMETERS:  Device          - The device for which notifies will be handled
273 *              HandlerType     - The type of handler:
274 *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
275 *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
276 *              Handler         - Address of the handler
277 *              Context         - Value passed to the handler on each GPE
278 *
279 * RETURN:      Status
280 *
281 * DESCRIPTION: Install a handler for notifies on an ACPI device
282 *
283 ******************************************************************************/
284
285ACPI_STATUS
286AcpiInstallNotifyHandler (
287    ACPI_HANDLE             Device,
288    UINT32                  HandlerType,
289    ACPI_NOTIFY_HANDLER     Handler,
290    void                    *Context)
291{
292    ACPI_OPERAND_OBJECT     *ObjDesc;
293    ACPI_OPERAND_OBJECT     *NotifyObj;
294    ACPI_NAMESPACE_NODE     *Node;
295    ACPI_STATUS             Status;
296
297
298    ACPI_FUNCTION_TRACE ("AcpiInstallNotifyHandler");
299
300
301    /* Parameter validation */
302
303    if ((!Device)  ||
304        (!Handler) ||
305        (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
306    {
307        return_ACPI_STATUS (AE_BAD_PARAMETER);
308    }
309
310    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
311    if (ACPI_FAILURE (Status))
312    {
313        return_ACPI_STATUS (Status);
314    }
315
316    /* Convert and validate the device handle */
317
318    Node = AcpiNsMapHandleToNode (Device);
319    if (!Node)
320    {
321        Status = AE_BAD_PARAMETER;
322        goto UnlockAndExit;
323    }
324
325    /*
326     * Root Object:
327     * Registering a notify handler on the root object indicates that the
328     * caller wishes to receive notifications for all objects.  Note that
329     * only one <external> global handler can be regsitered (per notify type).
330     */
331    if (Device == ACPI_ROOT_OBJECT)
332    {
333        /* Make sure the handler is not already installed */
334
335        if (((HandlerType == ACPI_SYSTEM_NOTIFY) &&
336              AcpiGbl_SysNotify.Handler) ||
337            ((HandlerType == ACPI_DEVICE_NOTIFY) &&
338              AcpiGbl_DrvNotify.Handler))
339        {
340            Status = AE_ALREADY_EXISTS;
341            goto UnlockAndExit;
342        }
343
344        if (HandlerType == ACPI_SYSTEM_NOTIFY)
345        {
346            AcpiGbl_SysNotify.Node = Node;
347            AcpiGbl_SysNotify.Handler = Handler;
348            AcpiGbl_SysNotify.Context = Context;
349        }
350        else /* ACPI_DEVICE_NOTIFY */
351        {
352            AcpiGbl_DrvNotify.Node = Node;
353            AcpiGbl_DrvNotify.Handler = Handler;
354            AcpiGbl_DrvNotify.Context = Context;
355        }
356
357        /* Global notify handler installed */
358    }
359
360    /*
361     * All Other Objects:
362     * Caller will only receive notifications specific to the target object.
363     * Note that only certain object types can receive notifications.
364     */
365    else
366    {
367        /* Notifies allowed on this object? */
368
369        if (!AcpiEvIsNotifyObject (Node))
370        {
371            Status = AE_TYPE;
372            goto UnlockAndExit;
373        }
374
375        /* Check for an existing internal object */
376
377        ObjDesc = AcpiNsGetAttachedObject (Node);
378        if (ObjDesc)
379        {
380
381            /* Object exists - make sure there's no handler */
382
383            if (((HandlerType == ACPI_SYSTEM_NOTIFY) &&
384                  ObjDesc->CommonNotify.SysHandler) ||
385                ((HandlerType == ACPI_DEVICE_NOTIFY) &&
386                  ObjDesc->CommonNotify.DrvHandler))
387            {
388                Status = AE_ALREADY_EXISTS;
389                goto UnlockAndExit;
390            }
391        }
392        else
393        {
394            /* Create a new object */
395
396            ObjDesc = AcpiUtCreateInternalObject (Node->Type);
397            if (!ObjDesc)
398            {
399                Status = AE_NO_MEMORY;
400                goto UnlockAndExit;
401            }
402
403            /* Attach new object to the Node */
404
405            Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
406            if (ACPI_FAILURE (Status))
407            {
408                goto UnlockAndExit;
409            }
410        }
411
412        /* Install the handler */
413
414        NotifyObj = AcpiUtCreateInternalObject (INTERNAL_TYPE_NOTIFY);
415        if (!NotifyObj)
416        {
417            Status = AE_NO_MEMORY;
418            goto UnlockAndExit;
419        }
420
421        NotifyObj->NotifyHandler.Node = Node;
422        NotifyObj->NotifyHandler.Handler = Handler;
423        NotifyObj->NotifyHandler.Context = Context;
424
425        if (HandlerType == ACPI_SYSTEM_NOTIFY)
426        {
427            ObjDesc->CommonNotify.SysHandler = NotifyObj;
428        }
429        else /* ACPI_DEVICE_NOTIFY */
430        {
431            ObjDesc->CommonNotify.DrvHandler = NotifyObj;
432        }
433    }
434
435
436UnlockAndExit:
437    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
438    return_ACPI_STATUS (Status);
439}
440
441
442/*******************************************************************************
443 *
444 * FUNCTION:    AcpiRemoveNotifyHandler
445 *
446 * PARAMETERS:  Device          - The device for which notifies will be handled
447 *              HandlerType     - The type of handler:
448 *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
449 *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
450 *              Handler         - Address of the handler
451 * RETURN:      Status
452 *
453 * DESCRIPTION: Remove a handler for notifies on an ACPI device
454 *
455 ******************************************************************************/
456
457ACPI_STATUS
458AcpiRemoveNotifyHandler (
459    ACPI_HANDLE             Device,
460    UINT32                  HandlerType,
461    ACPI_NOTIFY_HANDLER     Handler)
462{
463    ACPI_OPERAND_OBJECT     *NotifyObj;
464    ACPI_OPERAND_OBJECT     *ObjDesc;
465    ACPI_NAMESPACE_NODE     *Node;
466    ACPI_STATUS             Status;
467
468
469    ACPI_FUNCTION_TRACE ("AcpiRemoveNotifyHandler");
470
471
472    /* Parameter validation */
473
474    if ((!Device)  ||
475        (!Handler) ||
476        (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
477    {
478        return_ACPI_STATUS (AE_BAD_PARAMETER);
479    }
480
481    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
482    if (ACPI_FAILURE (Status))
483    {
484        return_ACPI_STATUS (Status);
485    }
486
487    /* Convert and validate the device handle */
488
489    Node = AcpiNsMapHandleToNode (Device);
490    if (!Node)
491    {
492        Status = AE_BAD_PARAMETER;
493        goto UnlockAndExit;
494    }
495
496    /*
497     * Root Object
498     */
499    if (Device == ACPI_ROOT_OBJECT)
500    {
501        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
502
503        if (((HandlerType == ACPI_SYSTEM_NOTIFY) &&
504              !AcpiGbl_SysNotify.Handler) ||
505            ((HandlerType == ACPI_DEVICE_NOTIFY) &&
506              !AcpiGbl_DrvNotify.Handler))
507        {
508            Status = AE_NOT_EXIST;
509            goto UnlockAndExit;
510        }
511
512        if (HandlerType == ACPI_SYSTEM_NOTIFY)
513        {
514            AcpiGbl_SysNotify.Node    = NULL;
515            AcpiGbl_SysNotify.Handler = NULL;
516            AcpiGbl_SysNotify.Context = NULL;
517        }
518        else
519        {
520            AcpiGbl_DrvNotify.Node    = NULL;
521            AcpiGbl_DrvNotify.Handler = NULL;
522            AcpiGbl_DrvNotify.Context = NULL;
523        }
524    }
525
526    /*
527     * All Other Objects
528     */
529    else
530    {
531        /* Notifies allowed on this object? */
532
533        if (!AcpiEvIsNotifyObject (Node))
534        {
535            Status = AE_TYPE;
536            goto UnlockAndExit;
537        }
538
539        /* Check for an existing internal object */
540
541        ObjDesc = AcpiNsGetAttachedObject (Node);
542        if (!ObjDesc)
543        {
544            Status = AE_NOT_EXIST;
545            goto UnlockAndExit;
546        }
547
548        /* Object exists - make sure there's an existing handler */
549
550        if (HandlerType == ACPI_SYSTEM_NOTIFY)
551        {
552            NotifyObj = ObjDesc->CommonNotify.SysHandler;
553        }
554        else
555        {
556            NotifyObj = ObjDesc->CommonNotify.DrvHandler;
557        }
558
559        if ((!NotifyObj) ||
560            (NotifyObj->NotifyHandler.Handler != Handler))
561        {
562            Status = AE_BAD_PARAMETER;
563            goto UnlockAndExit;
564        }
565
566        /* Remove the handler */
567
568        if (HandlerType == ACPI_SYSTEM_NOTIFY)
569        {
570            ObjDesc->CommonNotify.SysHandler = NULL;
571        }
572        else
573        {
574            ObjDesc->CommonNotify.DrvHandler = NULL;
575        }
576
577        AcpiUtRemoveReference (NotifyObj);
578    }
579
580
581UnlockAndExit:
582    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
583    return_ACPI_STATUS (Status);
584}
585
586
587/*******************************************************************************
588 *
589 * FUNCTION:    AcpiInstallGpeHandler
590 *
591 * PARAMETERS:  GpeNumber       - The GPE number.  The numbering scheme is
592 *                                bank 0 first, then bank 1.
593 *              Type            - Whether this GPE should be treated as an
594 *                                edge- or level-triggered interrupt.
595 *              Handler         - Address of the handler
596 *              Context         - Value passed to the handler on each GPE
597 *
598 * RETURN:      Status
599 *
600 * DESCRIPTION: Install a handler for a General Purpose Event.
601 *
602 ******************************************************************************/
603
604ACPI_STATUS
605AcpiInstallGpeHandler (
606    UINT32                  GpeNumber,
607    UINT32                  Type,
608    ACPI_GPE_HANDLER        Handler,
609    void                    *Context)
610{
611    ACPI_STATUS             Status;
612    UINT32                  GpeNumberIndex;
613
614
615    ACPI_FUNCTION_TRACE ("AcpiInstallGpeHandler");
616
617
618    /* Parameter validation */
619
620    if (!Handler)
621    {
622        return_ACPI_STATUS (AE_BAD_PARAMETER);
623    }
624
625    /* Ensure that we have a valid GPE number */
626
627    GpeNumberIndex = AcpiEvGetGpeNumberIndex (GpeNumber);
628    if (GpeNumberIndex == ACPI_GPE_INVALID)
629    {
630        return_ACPI_STATUS (AE_BAD_PARAMETER);
631    }
632
633    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
634    if (ACPI_FAILURE (Status))
635    {
636        return_ACPI_STATUS (Status);
637    }
638
639    /* Make sure that there isn't a handler there already */
640
641    if (AcpiGbl_GpeNumberInfo[GpeNumberIndex].Handler)
642    {
643        Status = AE_ALREADY_EXISTS;
644        goto Cleanup;
645    }
646
647    /* Install the handler */
648
649    AcpiGbl_GpeNumberInfo[GpeNumberIndex].Handler = Handler;
650    AcpiGbl_GpeNumberInfo[GpeNumberIndex].Context = Context;
651    AcpiGbl_GpeNumberInfo[GpeNumberIndex].Type    = (UINT8) Type;
652
653    /* Clear the GPE (of stale events), the enable it */
654
655    Status = AcpiHwClearGpe (GpeNumber);
656    if (ACPI_FAILURE (Status))
657    {
658        goto Cleanup;
659    }
660
661    Status = AcpiHwEnableGpe (GpeNumber);
662
663
664Cleanup:
665    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
666    return_ACPI_STATUS (Status);
667}
668
669
670/*******************************************************************************
671 *
672 * FUNCTION:    AcpiRemoveGpeHandler
673 *
674 * PARAMETERS:  GpeNumber       - The event to remove a handler
675 *              Handler         - Address of the handler
676 *
677 * RETURN:      Status
678 *
679 * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
680 *
681 ******************************************************************************/
682
683ACPI_STATUS
684AcpiRemoveGpeHandler (
685    UINT32                  GpeNumber,
686    ACPI_GPE_HANDLER        Handler)
687{
688    ACPI_STATUS             Status;
689    UINT32                  GpeNumberIndex;
690
691
692    ACPI_FUNCTION_TRACE ("AcpiRemoveGpeHandler");
693
694
695    /* Parameter validation */
696
697    if (!Handler)
698    {
699        return_ACPI_STATUS (AE_BAD_PARAMETER);
700    }
701
702    /* Ensure that we have a valid GPE number */
703
704    GpeNumberIndex = AcpiEvGetGpeNumberIndex (GpeNumber);
705    if (GpeNumberIndex == ACPI_GPE_INVALID)
706    {
707        return_ACPI_STATUS (AE_BAD_PARAMETER);
708    }
709
710    /* Disable the GPE before removing the handler */
711
712    Status = AcpiHwDisableGpe (GpeNumber);
713    if (ACPI_FAILURE (Status))
714    {
715        return_ACPI_STATUS (Status);
716    }
717
718    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
719    if (ACPI_FAILURE (Status))
720    {
721        return_ACPI_STATUS (Status);
722    }
723
724    /* Make sure that the installed handler is the same */
725
726    if (AcpiGbl_GpeNumberInfo[GpeNumberIndex].Handler != Handler)
727    {
728        (void) AcpiHwEnableGpe (GpeNumber);
729        Status = AE_BAD_PARAMETER;
730        goto Cleanup;
731    }
732
733    /* Remove the handler */
734
735    AcpiGbl_GpeNumberInfo[GpeNumberIndex].Handler = NULL;
736    AcpiGbl_GpeNumberInfo[GpeNumberIndex].Context = NULL;
737
738
739Cleanup:
740    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
741    return_ACPI_STATUS (Status);
742}
743
744
745/*******************************************************************************
746 *
747 * FUNCTION:    AcpiAcquireGlobalLock
748 *
749 * PARAMETERS:  Timeout         - How long the caller is willing to wait
750 *              OutHandle       - A handle to the lock if acquired
751 *
752 * RETURN:      Status
753 *
754 * DESCRIPTION: Acquire the ACPI Global Lock
755 *
756 ******************************************************************************/
757
758ACPI_STATUS
759AcpiAcquireGlobalLock (
760    UINT32                  Timeout,
761    UINT32                  *Handle)
762{
763    ACPI_STATUS             Status;
764
765
766    if (!Handle)
767    {
768        return (AE_BAD_PARAMETER);
769    }
770
771    Status = AcpiExEnterInterpreter ();
772    if (ACPI_FAILURE (Status))
773    {
774        return (Status);
775    }
776
777    Status = AcpiEvAcquireGlobalLock (Timeout);
778    AcpiExExitInterpreter ();
779
780    if (ACPI_SUCCESS (Status))
781    {
782        AcpiGbl_GlobalLockHandle++;
783        *Handle = AcpiGbl_GlobalLockHandle;
784    }
785
786    return (Status);
787}
788
789
790/*******************************************************************************
791 *
792 * FUNCTION:    AcpiReleaseGlobalLock
793 *
794 * PARAMETERS:  Handle      - Returned from AcpiAcquireGlobalLock
795 *
796 * RETURN:      Status
797 *
798 * DESCRIPTION: Release the ACPI Global Lock
799 *
800 ******************************************************************************/
801
802ACPI_STATUS
803AcpiReleaseGlobalLock (
804    UINT32                  Handle)
805{
806    ACPI_STATUS             Status;
807
808
809    if (Handle != AcpiGbl_GlobalLockHandle)
810    {
811        return (AE_NOT_ACQUIRED);
812    }
813
814    Status = AcpiEvReleaseGlobalLock ();
815    return (Status);
816}
817
818
819