Merge from vendor branch GCC:
[dragonfly.git] / sys / contrib / dev / acpica-unix-20031203 / events / evxface.c
1 /******************************************************************************
2  *
3  * Module Name: evxface - External interfaces for ACPI events
4  *              $Revision: 141 $
5  *
6  *****************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2003, 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  * FUNCTION:    AcpiInstallFixedEventHandler
132  *
133  * PARAMETERS:  Event           - Event type to enable.
134  *              Handler         - Pointer to the handler function for the
135  *                                event
136  *              Context         - Value passed to the handler on each GPE
137  *
138  * RETURN:      Status
139  *
140  * DESCRIPTION: Saves the pointer to the handler function and then enables the
141  *              event.
142  *
143  ******************************************************************************/
144
145 ACPI_STATUS
146 AcpiInstallFixedEventHandler (
147     UINT32                  Event,
148     ACPI_EVENT_HANDLER      Handler,
149     void                    *Context)
150 {
151     ACPI_STATUS             Status;
152
153
154     ACPI_FUNCTION_TRACE ("AcpiInstallFixedEventHandler");
155
156
157     /* Parameter validation */
158
159     if (Event > ACPI_EVENT_MAX)
160     {
161         return_ACPI_STATUS (AE_BAD_PARAMETER);
162     }
163
164     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
165     if (ACPI_FAILURE (Status))
166     {
167         return_ACPI_STATUS (Status);
168     }
169
170     /* Don't allow two handlers. */
171
172     if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler)
173     {
174         Status = AE_ALREADY_EXISTS;
175         goto Cleanup;
176     }
177
178     /* Install the handler before enabling the event */
179
180     AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
181     AcpiGbl_FixedEventHandlers[Event].Context = Context;
182
183     Status = AcpiEnableEvent (Event, 0);
184     if (ACPI_FAILURE (Status))
185     {
186         ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n"));
187
188         /* Remove the handler */
189
190         AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
191         AcpiGbl_FixedEventHandlers[Event].Context = NULL;
192     }
193     else
194     {
195         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
196             "Enabled fixed event %X, Handler=%p\n", Event, Handler));
197     }
198
199
200 Cleanup:
201     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
202     return_ACPI_STATUS (Status);
203 }
204
205
206 /*******************************************************************************
207  *
208  * FUNCTION:    AcpiRemoveFixedEventHandler
209  *
210  * PARAMETERS:  Event           - Event type to disable.
211  *              Handler         - Address of the handler
212  *
213  * RETURN:      Status
214  *
215  * DESCRIPTION: Disables the event and unregisters the event handler.
216  *
217  ******************************************************************************/
218
219 ACPI_STATUS
220 AcpiRemoveFixedEventHandler (
221     UINT32                  Event,
222     ACPI_EVENT_HANDLER      Handler)
223 {
224     ACPI_STATUS             Status = AE_OK;
225
226
227     ACPI_FUNCTION_TRACE ("AcpiRemoveFixedEventHandler");
228
229
230     /* Parameter validation */
231
232     if (Event > ACPI_EVENT_MAX)
233     {
234         return_ACPI_STATUS (AE_BAD_PARAMETER);
235     }
236
237     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
238     if (ACPI_FAILURE (Status))
239     {
240         return_ACPI_STATUS (Status);
241     }
242
243     /* Disable the event before removing the handler */
244
245     Status = AcpiDisableEvent (Event, 0);
246
247     /* Always Remove the handler */
248
249     AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
250     AcpiGbl_FixedEventHandlers[Event].Context = NULL;
251
252     if (ACPI_FAILURE (Status))
253     {
254         ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
255             "Could not write to fixed event enable register.\n"));
256     }
257     else
258     {
259         ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X.\n", Event));
260     }
261
262     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
263     return_ACPI_STATUS (Status);
264 }
265
266
267 /*******************************************************************************
268  *
269  * FUNCTION:    AcpiInstallNotifyHandler
270  *
271  * PARAMETERS:  Device          - The device for which notifies will be handled
272  *              HandlerType     - The type of handler:
273  *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
274  *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
275  *              Handler         - Address of the handler
276  *              Context         - Value passed to the handler on each GPE
277  *
278  * RETURN:      Status
279  *
280  * DESCRIPTION: Install a handler for notifies on an ACPI device
281  *
282  ******************************************************************************/
283
284 ACPI_STATUS
285 AcpiInstallNotifyHandler (
286     ACPI_HANDLE             Device,
287     UINT32                  HandlerType,
288     ACPI_NOTIFY_HANDLER     Handler,
289     void                    *Context)
290 {
291     ACPI_OPERAND_OBJECT     *ObjDesc;
292     ACPI_OPERAND_OBJECT     *NotifyObj;
293     ACPI_NAMESPACE_NODE     *Node;
294     ACPI_STATUS             Status;
295
296
297     ACPI_FUNCTION_TRACE ("AcpiInstallNotifyHandler");
298
299
300     /* Parameter validation */
301
302     if ((!Device)  ||
303         (!Handler) ||
304         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
305     {
306         return_ACPI_STATUS (AE_BAD_PARAMETER);
307     }
308
309     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
310     if (ACPI_FAILURE (Status))
311     {
312         return_ACPI_STATUS (Status);
313     }
314
315     /* Convert and validate the device handle */
316
317     Node = AcpiNsMapHandleToNode (Device);
318     if (!Node)
319     {
320         Status = AE_BAD_PARAMETER;
321         goto UnlockAndExit;
322     }
323
324     /*
325      * Root Object:
326      * Registering a notify handler on the root object indicates that the
327      * caller wishes to receive notifications for all objects.  Note that
328      * only one <external> global handler can be regsitered (per notify type).
329      */
330     if (Device == ACPI_ROOT_OBJECT)
331     {
332         /* Make sure the handler is not already installed */
333
334         if (((HandlerType == ACPI_SYSTEM_NOTIFY) &&
335                 AcpiGbl_SystemNotify.Handler)          ||
336             ((HandlerType == ACPI_DEVICE_NOTIFY) &&
337                 AcpiGbl_DeviceNotify.Handler))
338         {
339             Status = AE_ALREADY_EXISTS;
340             goto UnlockAndExit;
341         }
342
343         if (HandlerType == ACPI_SYSTEM_NOTIFY)
344         {
345             AcpiGbl_SystemNotify.Node    = Node;
346             AcpiGbl_SystemNotify.Handler = Handler;
347             AcpiGbl_SystemNotify.Context = Context;
348         }
349         else /* ACPI_DEVICE_NOTIFY */
350         {
351             AcpiGbl_DeviceNotify.Node    = Node;
352             AcpiGbl_DeviceNotify.Handler = Handler;
353             AcpiGbl_DeviceNotify.Context = Context;
354         }
355
356         /* Global notify handler installed */
357     }
358
359     /*
360      * All Other Objects:
361      * Caller will only receive notifications specific to the target object.
362      * Note that only certain object types can receive notifications.
363      */
364     else
365     {
366         /* Notifies allowed on this object? */
367
368         if (!AcpiEvIsNotifyObject (Node))
369         {
370             Status = AE_TYPE;
371             goto UnlockAndExit;
372         }
373
374         /* Check for an existing internal object */
375
376         ObjDesc = AcpiNsGetAttachedObject (Node);
377         if (ObjDesc)
378         {
379             /* Object exists - make sure there's no handler */
380
381             if (((HandlerType == ACPI_SYSTEM_NOTIFY) &&
382                     ObjDesc->CommonNotify.SystemNotify)   ||
383                 ((HandlerType == ACPI_DEVICE_NOTIFY) &&
384                     ObjDesc->CommonNotify.DeviceNotify))
385             {
386                 Status = AE_ALREADY_EXISTS;
387                 goto UnlockAndExit;
388             }
389         }
390         else
391         {
392             /* Create a new object */
393
394             ObjDesc = AcpiUtCreateInternalObject (Node->Type);
395             if (!ObjDesc)
396             {
397                 Status = AE_NO_MEMORY;
398                 goto UnlockAndExit;
399             }
400
401             /* Attach new object to the Node */
402
403             Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
404
405             /* Remove local reference to the object */
406
407             AcpiUtRemoveReference (ObjDesc);
408
409             if (ACPI_FAILURE (Status))
410             {
411                 goto UnlockAndExit;
412             }
413         }
414
415         /* Install the handler */
416
417         NotifyObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
418         if (!NotifyObj)
419         {
420             Status = AE_NO_MEMORY;
421             goto UnlockAndExit;
422         }
423
424         NotifyObj->Notify.Node    = Node;
425         NotifyObj->Notify.Handler = Handler;
426         NotifyObj->Notify.Context = Context;
427
428         if (HandlerType == ACPI_SYSTEM_NOTIFY)
429         {
430             ObjDesc->CommonNotify.SystemNotify = NotifyObj;
431         }
432         else /* ACPI_DEVICE_NOTIFY */
433         {
434             ObjDesc->CommonNotify.DeviceNotify = NotifyObj;
435         }
436     }
437
438
439 UnlockAndExit:
440     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
441     return_ACPI_STATUS (Status);
442 }
443
444
445 /*******************************************************************************
446  *
447  * FUNCTION:    AcpiRemoveNotifyHandler
448  *
449  * PARAMETERS:  Device          - The device for which notifies will be handled
450  *              HandlerType     - The type of handler:
451  *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
452  *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
453  *              Handler         - Address of the handler
454  * RETURN:      Status
455  *
456  * DESCRIPTION: Remove a handler for notifies on an ACPI device
457  *
458  ******************************************************************************/
459
460 ACPI_STATUS
461 AcpiRemoveNotifyHandler (
462     ACPI_HANDLE             Device,
463     UINT32                  HandlerType,
464     ACPI_NOTIFY_HANDLER     Handler)
465 {
466     ACPI_OPERAND_OBJECT     *NotifyObj;
467     ACPI_OPERAND_OBJECT     *ObjDesc;
468     ACPI_NAMESPACE_NODE     *Node;
469     ACPI_STATUS             Status;
470
471
472     ACPI_FUNCTION_TRACE ("AcpiRemoveNotifyHandler");
473
474
475     /* Parameter validation */
476
477     if ((!Device)  ||
478         (!Handler) ||
479         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
480     {
481         return_ACPI_STATUS (AE_BAD_PARAMETER);
482     }
483
484     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
485     if (ACPI_FAILURE (Status))
486     {
487         return_ACPI_STATUS (Status);
488     }
489
490     /* Convert and validate the device handle */
491
492     Node = AcpiNsMapHandleToNode (Device);
493     if (!Node)
494     {
495         Status = AE_BAD_PARAMETER;
496         goto UnlockAndExit;
497     }
498
499     /*
500      * Root Object
501      */
502     if (Device == ACPI_ROOT_OBJECT)
503     {
504         ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
505
506         if (((HandlerType == ACPI_SYSTEM_NOTIFY) &&
507               !AcpiGbl_SystemNotify.Handler) ||
508             ((HandlerType == ACPI_DEVICE_NOTIFY) &&
509               !AcpiGbl_DeviceNotify.Handler))
510         {
511             Status = AE_NOT_EXIST;
512             goto UnlockAndExit;
513         }
514
515         if (HandlerType == ACPI_SYSTEM_NOTIFY)
516         {
517             AcpiGbl_SystemNotify.Node    = NULL;
518             AcpiGbl_SystemNotify.Handler = NULL;
519             AcpiGbl_SystemNotify.Context = NULL;
520         }
521         else
522         {
523             AcpiGbl_DeviceNotify.Node    = NULL;
524             AcpiGbl_DeviceNotify.Handler = NULL;
525             AcpiGbl_DeviceNotify.Context = NULL;
526         }
527     }
528
529     /*
530      * All Other Objects
531      */
532     else
533     {
534         /* Notifies allowed on this object? */
535
536         if (!AcpiEvIsNotifyObject (Node))
537         {
538             Status = AE_TYPE;
539             goto UnlockAndExit;
540         }
541
542         /* Check for an existing internal object */
543
544         ObjDesc = AcpiNsGetAttachedObject (Node);
545         if (!ObjDesc)
546         {
547             Status = AE_NOT_EXIST;
548             goto UnlockAndExit;
549         }
550
551         /* Object exists - make sure there's an existing handler */
552
553         if (HandlerType == ACPI_SYSTEM_NOTIFY)
554         {
555             NotifyObj = ObjDesc->CommonNotify.SystemNotify;
556         }
557         else
558         {
559             NotifyObj = ObjDesc->CommonNotify.DeviceNotify;
560         }
561
562         if ((!NotifyObj) ||
563             (NotifyObj->Notify.Handler != Handler))
564         {
565             Status = AE_BAD_PARAMETER;
566             goto UnlockAndExit;
567         }
568
569         /* Remove the handler */
570
571         if (HandlerType == ACPI_SYSTEM_NOTIFY)
572         {
573             ObjDesc->CommonNotify.SystemNotify = NULL;
574         }
575         else
576         {
577             ObjDesc->CommonNotify.DeviceNotify = NULL;
578         }
579
580         AcpiUtRemoveReference (NotifyObj);
581     }
582
583
584 UnlockAndExit:
585     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
586     return_ACPI_STATUS (Status);
587 }
588
589
590 /*******************************************************************************
591  *
592  * FUNCTION:    AcpiInstallGpeHandler
593  *
594  * PARAMETERS:  GpeNumber       - The GPE number within the GPE block
595  *              GpeBlock        - GPE block (NULL == FADT GPEs)
596  *              Type            - Whether this GPE should be treated as an
597  *                                edge- or level-triggered interrupt.
598  *              Handler         - Address of the handler
599  *              Context         - Value passed to the handler on each GPE
600  *
601  * RETURN:      Status
602  *
603  * DESCRIPTION: Install a handler for a General Purpose Event.
604  *
605  ******************************************************************************/
606
607 ACPI_STATUS
608 AcpiInstallGpeHandler (
609     ACPI_HANDLE             GpeDevice,
610     UINT32                  GpeNumber,
611     UINT32                  Type,
612     ACPI_GPE_HANDLER        Handler,
613     void                    *Context)
614 {
615     ACPI_STATUS             Status;
616     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
617
618
619     ACPI_FUNCTION_TRACE ("AcpiInstallGpeHandler");
620
621
622     /* Parameter validation */
623
624     if (!Handler)
625     {
626         return_ACPI_STATUS (AE_BAD_PARAMETER);
627     }
628
629     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
630     if (ACPI_FAILURE (Status))
631     {
632         return_ACPI_STATUS (Status);
633     }
634
635     /* Ensure that we have a valid GPE number */
636
637     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
638     if (!GpeEventInfo)
639     {
640         Status = AE_BAD_PARAMETER;
641         goto UnlockAndExit;
642     }
643
644     /* Make sure that there isn't a handler there already */
645
646     if (GpeEventInfo->Handler)
647     {
648         Status = AE_ALREADY_EXISTS;
649         goto UnlockAndExit;
650     }
651
652     /* Install the handler */
653
654     AcpiOsAcquireLock (AcpiGbl_GpeLock, ACPI_NOT_ISR);
655     GpeEventInfo->Handler = Handler;
656     GpeEventInfo->Context = Context;
657     GpeEventInfo->Flags   = (UINT8) Type;
658     AcpiOsReleaseLock (AcpiGbl_GpeLock, ACPI_NOT_ISR);
659
660     /* Clear the GPE (of stale events), the enable it */
661
662     Status = AcpiHwClearGpe (GpeEventInfo);
663     if (ACPI_FAILURE (Status))
664     {
665         goto UnlockAndExit;
666     }
667
668     Status = AcpiHwEnableGpe (GpeEventInfo);
669
670
671 UnlockAndExit:
672     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
673     return_ACPI_STATUS (Status);
674 }
675
676
677 /*******************************************************************************
678  *
679  * FUNCTION:    AcpiRemoveGpeHandler
680  *
681  * PARAMETERS:  GpeNumber       - The event to remove a handler
682  *              GpeBlock        - GPE block (NULL == FADT GPEs)
683  *              Handler         - Address of the handler
684  *
685  * RETURN:      Status
686  *
687  * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
688  *
689  ******************************************************************************/
690
691 ACPI_STATUS
692 AcpiRemoveGpeHandler (
693     ACPI_HANDLE             GpeDevice,
694     UINT32                  GpeNumber,
695     ACPI_GPE_HANDLER        Handler)
696 {
697     ACPI_STATUS             Status;
698     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
699
700
701     ACPI_FUNCTION_TRACE ("AcpiRemoveGpeHandler");
702
703
704     /* Parameter validation */
705
706     if (!Handler)
707     {
708         return_ACPI_STATUS (AE_BAD_PARAMETER);
709     }
710
711     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
712     if (ACPI_FAILURE (Status))
713     {
714         return_ACPI_STATUS (Status);
715     }
716
717     /* Ensure that we have a valid GPE number */
718
719     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
720     if (!GpeEventInfo)
721     {
722         Status = AE_BAD_PARAMETER;
723         goto UnlockAndExit;
724     }
725
726     /* Disable the GPE before removing the handler */
727
728     Status = AcpiHwDisableGpe (GpeEventInfo);
729     if (ACPI_FAILURE (Status))
730     {
731         goto UnlockAndExit;
732     }
733
734     /* Make sure that the installed handler is the same */
735
736     if (GpeEventInfo->Handler != Handler)
737     {
738         (void) AcpiHwEnableGpe (GpeEventInfo);
739         Status = AE_BAD_PARAMETER;
740         goto UnlockAndExit;
741     }
742
743     /* Remove the handler */
744
745     AcpiOsAcquireLock (AcpiGbl_GpeLock, ACPI_NOT_ISR);
746     GpeEventInfo->Handler = NULL;
747     GpeEventInfo->Context = NULL;
748     AcpiOsReleaseLock (AcpiGbl_GpeLock, ACPI_NOT_ISR);
749
750
751 UnlockAndExit:
752     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
753     return_ACPI_STATUS (Status);
754 }
755
756
757 /*******************************************************************************
758  *
759  * FUNCTION:    AcpiAcquireGlobalLock
760  *
761  * PARAMETERS:  Timeout         - How long the caller is willing to wait
762  *              OutHandle       - A handle to the lock if acquired
763  *
764  * RETURN:      Status
765  *
766  * DESCRIPTION: Acquire the ACPI Global Lock
767  *
768  ******************************************************************************/
769
770 ACPI_STATUS
771 AcpiAcquireGlobalLock (
772     UINT16                  Timeout,
773     UINT32                  *Handle)
774 {
775     ACPI_STATUS             Status;
776
777
778     if (!Handle)
779     {
780         return (AE_BAD_PARAMETER);
781     }
782
783     Status = AcpiExEnterInterpreter ();
784     if (ACPI_FAILURE (Status))
785     {
786         return (Status);
787     }
788
789     Status = AcpiEvAcquireGlobalLock (Timeout);
790     AcpiExExitInterpreter ();
791
792     if (ACPI_SUCCESS (Status))
793     {
794         AcpiGbl_GlobalLockHandle++;
795         *Handle = AcpiGbl_GlobalLockHandle;
796     }
797
798     return (Status);
799 }
800
801
802 /*******************************************************************************
803  *
804  * FUNCTION:    AcpiReleaseGlobalLock
805  *
806  * PARAMETERS:  Handle      - Returned from AcpiAcquireGlobalLock
807  *
808  * RETURN:      Status
809  *
810  * DESCRIPTION: Release the ACPI Global Lock
811  *
812  ******************************************************************************/
813
814 ACPI_STATUS
815 AcpiReleaseGlobalLock (
816     UINT32                  Handle)
817 {
818     ACPI_STATUS             Status;
819
820
821     if (Handle != AcpiGbl_GlobalLockHandle)
822     {
823         return (AE_NOT_ACQUIRED);
824     }
825
826     Status = AcpiEvReleaseGlobalLock ();
827     return (Status);
828 }
829
830