]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/evxface.c
Vendor import of the Intel ACPI CA 20021118 drop.
[FreeBSD/FreeBSD.git] / sys / contrib / dev / acpica / evxface.c
1 /******************************************************************************
2  *
3  * Module Name: evxface - External interfaces for ACPI events
4  *              $Revision: 132 $
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  * 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, ACPI_EVENT_FIXED, 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, ACPI_EVENT_FIXED, 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_SysNotify.Handler) ||
336             ((HandlerType == ACPI_DEVICE_NOTIFY) &&
337               AcpiGbl_DrvNotify.Handler))
338         {
339             Status = AE_ALREADY_EXISTS;
340             goto UnlockAndExit;
341         }
342
343         if (HandlerType == ACPI_SYSTEM_NOTIFY)
344         {
345             AcpiGbl_SysNotify.Node = Node;
346             AcpiGbl_SysNotify.Handler = Handler;
347             AcpiGbl_SysNotify.Context = Context;
348         }
349         else /* ACPI_DEVICE_NOTIFY */
350         {
351             AcpiGbl_DrvNotify.Node = Node;
352             AcpiGbl_DrvNotify.Handler = Handler;
353             AcpiGbl_DrvNotify.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
380             /* Object exists - make sure there's no handler */
381
382             if (((HandlerType == ACPI_SYSTEM_NOTIFY) &&
383                   ObjDesc->CommonNotify.SysHandler) ||
384                 ((HandlerType == ACPI_DEVICE_NOTIFY) &&
385                   ObjDesc->CommonNotify.DrvHandler))
386             {
387                 Status = AE_ALREADY_EXISTS;
388                 goto UnlockAndExit;
389             }
390         }
391         else
392         {
393             /* Create a new object */
394
395             ObjDesc = AcpiUtCreateInternalObject (Node->Type);
396             if (!ObjDesc)
397             {
398                 Status = AE_NO_MEMORY;
399                 goto UnlockAndExit;
400             }
401
402             /* Attach new object to the Node */
403
404             Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
405             if (ACPI_FAILURE (Status))
406             {
407                 goto UnlockAndExit;
408             }
409         }
410
411         /* Install the handler */
412
413         NotifyObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
414         if (!NotifyObj)
415         {
416             Status = AE_NO_MEMORY;
417             goto UnlockAndExit;
418         }
419
420         NotifyObj->NotifyHandler.Node = Node;
421         NotifyObj->NotifyHandler.Handler = Handler;
422         NotifyObj->NotifyHandler.Context = Context;
423
424         if (HandlerType == ACPI_SYSTEM_NOTIFY)
425         {
426             ObjDesc->CommonNotify.SysHandler = NotifyObj;
427         }
428         else /* ACPI_DEVICE_NOTIFY */
429         {
430             ObjDesc->CommonNotify.DrvHandler = NotifyObj;
431         }
432     }
433
434
435 UnlockAndExit:
436     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
437     return_ACPI_STATUS (Status);
438 }
439
440
441 /*******************************************************************************
442  *
443  * FUNCTION:    AcpiRemoveNotifyHandler
444  *
445  * PARAMETERS:  Device          - The device for which notifies will be handled
446  *              HandlerType     - The type of handler:
447  *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
448  *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
449  *              Handler         - Address of the handler
450  * RETURN:      Status
451  *
452  * DESCRIPTION: Remove a handler for notifies on an ACPI device
453  *
454  ******************************************************************************/
455
456 ACPI_STATUS
457 AcpiRemoveNotifyHandler (
458     ACPI_HANDLE             Device,
459     UINT32                  HandlerType,
460     ACPI_NOTIFY_HANDLER     Handler)
461 {
462     ACPI_OPERAND_OBJECT     *NotifyObj;
463     ACPI_OPERAND_OBJECT     *ObjDesc;
464     ACPI_NAMESPACE_NODE     *Node;
465     ACPI_STATUS             Status;
466
467
468     ACPI_FUNCTION_TRACE ("AcpiRemoveNotifyHandler");
469
470
471     /* Parameter validation */
472
473     if ((!Device)  ||
474         (!Handler) ||
475         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
476     {
477         return_ACPI_STATUS (AE_BAD_PARAMETER);
478     }
479
480     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
481     if (ACPI_FAILURE (Status))
482     {
483         return_ACPI_STATUS (Status);
484     }
485
486     /* Convert and validate the device handle */
487
488     Node = AcpiNsMapHandleToNode (Device);
489     if (!Node)
490     {
491         Status = AE_BAD_PARAMETER;
492         goto UnlockAndExit;
493     }
494
495     /*
496      * Root Object
497      */
498     if (Device == ACPI_ROOT_OBJECT)
499     {
500         ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
501
502         if (((HandlerType == ACPI_SYSTEM_NOTIFY) &&
503               !AcpiGbl_SysNotify.Handler) ||
504             ((HandlerType == ACPI_DEVICE_NOTIFY) &&
505               !AcpiGbl_DrvNotify.Handler))
506         {
507             Status = AE_NOT_EXIST;
508             goto UnlockAndExit;
509         }
510
511         if (HandlerType == ACPI_SYSTEM_NOTIFY)
512         {
513             AcpiGbl_SysNotify.Node    = NULL;
514             AcpiGbl_SysNotify.Handler = NULL;
515             AcpiGbl_SysNotify.Context = NULL;
516         }
517         else
518         {
519             AcpiGbl_DrvNotify.Node    = NULL;
520             AcpiGbl_DrvNotify.Handler = NULL;
521             AcpiGbl_DrvNotify.Context = NULL;
522         }
523     }
524
525     /*
526      * All Other Objects
527      */
528     else
529     {
530         /* Notifies allowed on this object? */
531
532         if (!AcpiEvIsNotifyObject (Node))
533         {
534             Status = AE_TYPE;
535             goto UnlockAndExit;
536         }
537
538         /* Check for an existing internal object */
539
540         ObjDesc = AcpiNsGetAttachedObject (Node);
541         if (!ObjDesc)
542         {
543             Status = AE_NOT_EXIST;
544             goto UnlockAndExit;
545         }
546
547         /* Object exists - make sure there's an existing handler */
548
549         if (HandlerType == ACPI_SYSTEM_NOTIFY)
550         {
551             NotifyObj = ObjDesc->CommonNotify.SysHandler;
552         }
553         else
554         {
555             NotifyObj = ObjDesc->CommonNotify.DrvHandler;
556         }
557
558         if ((!NotifyObj) ||
559             (NotifyObj->NotifyHandler.Handler != Handler))
560         {
561             Status = AE_BAD_PARAMETER;
562             goto UnlockAndExit;
563         }
564
565         /* Remove the handler */
566
567         if (HandlerType == ACPI_SYSTEM_NOTIFY)
568         {
569             ObjDesc->CommonNotify.SysHandler = NULL;
570         }
571         else
572         {
573             ObjDesc->CommonNotify.DrvHandler = NULL;
574         }
575
576         AcpiUtRemoveReference (NotifyObj);
577     }
578
579
580 UnlockAndExit:
581     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
582     return_ACPI_STATUS (Status);
583 }
584
585
586 /*******************************************************************************
587  *
588  * FUNCTION:    AcpiInstallGpeHandler
589  *
590  * PARAMETERS:  GpeNumber       - The GPE number.  The numbering scheme is
591  *                                bank 0 first, then bank 1.
592  *              Type            - Whether this GPE should be treated as an
593  *                                edge- or level-triggered interrupt.
594  *              Handler         - Address of the handler
595  *              Context         - Value passed to the handler on each GPE
596  *
597  * RETURN:      Status
598  *
599  * DESCRIPTION: Install a handler for a General Purpose Event.
600  *
601  ******************************************************************************/
602
603 ACPI_STATUS
604 AcpiInstallGpeHandler (
605     UINT32                  GpeNumber,
606     UINT32                  Type,
607     ACPI_GPE_HANDLER        Handler,
608     void                    *Context)
609 {
610     ACPI_STATUS             Status;
611     UINT32                  GpeNumberIndex;
612
613
614     ACPI_FUNCTION_TRACE ("AcpiInstallGpeHandler");
615
616
617     /* Parameter validation */
618
619     if (!Handler)
620     {
621         return_ACPI_STATUS (AE_BAD_PARAMETER);
622     }
623
624     /* Ensure that we have a valid GPE number */
625
626     GpeNumberIndex = AcpiEvGetGpeNumberIndex (GpeNumber);
627     if (GpeNumberIndex == ACPI_GPE_INVALID)
628     {
629         return_ACPI_STATUS (AE_BAD_PARAMETER);
630     }
631
632     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
633     if (ACPI_FAILURE (Status))
634     {
635         return_ACPI_STATUS (Status);
636     }
637
638     /* Make sure that there isn't a handler there already */
639
640     if (AcpiGbl_GpeNumberInfo[GpeNumberIndex].Handler)
641     {
642         Status = AE_ALREADY_EXISTS;
643         goto Cleanup;
644     }
645
646     /* Install the handler */
647
648     AcpiGbl_GpeNumberInfo[GpeNumberIndex].Handler = Handler;
649     AcpiGbl_GpeNumberInfo[GpeNumberIndex].Context = Context;
650     AcpiGbl_GpeNumberInfo[GpeNumberIndex].Type    = (UINT8) Type;
651
652     /* Clear the GPE (of stale events), the enable it */
653
654     Status = AcpiHwClearGpe (GpeNumber);
655     if (ACPI_FAILURE (Status))
656     {
657         goto Cleanup;
658     }
659
660     Status = AcpiHwEnableGpe (GpeNumber);
661
662
663 Cleanup:
664     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
665     return_ACPI_STATUS (Status);
666 }
667
668
669 /*******************************************************************************
670  *
671  * FUNCTION:    AcpiRemoveGpeHandler
672  *
673  * PARAMETERS:  GpeNumber       - The event to remove a handler
674  *              Handler         - Address of the handler
675  *
676  * RETURN:      Status
677  *
678  * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
679  *
680  ******************************************************************************/
681
682 ACPI_STATUS
683 AcpiRemoveGpeHandler (
684     UINT32                  GpeNumber,
685     ACPI_GPE_HANDLER        Handler)
686 {
687     ACPI_STATUS             Status;
688     UINT32                  GpeNumberIndex;
689
690
691     ACPI_FUNCTION_TRACE ("AcpiRemoveGpeHandler");
692
693
694     /* Parameter validation */
695
696     if (!Handler)
697     {
698         return_ACPI_STATUS (AE_BAD_PARAMETER);
699     }
700
701     /* Ensure that we have a valid GPE number */
702
703     GpeNumberIndex = AcpiEvGetGpeNumberIndex (GpeNumber);
704     if (GpeNumberIndex == ACPI_GPE_INVALID)
705     {
706         return_ACPI_STATUS (AE_BAD_PARAMETER);
707     }
708
709     /* Disable the GPE before removing the handler */
710
711     Status = AcpiHwDisableGpe (GpeNumber);
712     if (ACPI_FAILURE (Status))
713     {
714         return_ACPI_STATUS (Status);
715     }
716
717     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
718     if (ACPI_FAILURE (Status))
719     {
720         return_ACPI_STATUS (Status);
721     }
722
723     /* Make sure that the installed handler is the same */
724
725     if (AcpiGbl_GpeNumberInfo[GpeNumberIndex].Handler != Handler)
726     {
727         (void) AcpiHwEnableGpe (GpeNumber);
728         Status = AE_BAD_PARAMETER;
729         goto Cleanup;
730     }
731
732     /* Remove the handler */
733
734     AcpiGbl_GpeNumberInfo[GpeNumberIndex].Handler = NULL;
735     AcpiGbl_GpeNumberInfo[GpeNumberIndex].Context = NULL;
736
737
738 Cleanup:
739     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
740     return_ACPI_STATUS (Status);
741 }
742
743
744 /*******************************************************************************
745  *
746  * FUNCTION:    AcpiAcquireGlobalLock
747  *
748  * PARAMETERS:  Timeout         - How long the caller is willing to wait
749  *              OutHandle       - A handle to the lock if acquired
750  *
751  * RETURN:      Status
752  *
753  * DESCRIPTION: Acquire the ACPI Global Lock
754  *
755  ******************************************************************************/
756
757 ACPI_STATUS
758 AcpiAcquireGlobalLock (
759     UINT16                  Timeout,
760     UINT32                  *Handle)
761 {
762     ACPI_STATUS             Status;
763
764
765     if (!Handle)
766     {
767         return (AE_BAD_PARAMETER);
768     }
769
770     Status = AcpiExEnterInterpreter ();
771     if (ACPI_FAILURE (Status))
772     {
773         return (Status);
774     }
775
776     Status = AcpiEvAcquireGlobalLock (Timeout);
777     AcpiExExitInterpreter ();
778
779     if (ACPI_SUCCESS (Status))
780     {
781         AcpiGbl_GlobalLockHandle++;
782         *Handle = AcpiGbl_GlobalLockHandle;
783     }
784
785     return (Status);
786 }
787
788
789 /*******************************************************************************
790  *
791  * FUNCTION:    AcpiReleaseGlobalLock
792  *
793  * PARAMETERS:  Handle      - Returned from AcpiAcquireGlobalLock
794  *
795  * RETURN:      Status
796  *
797  * DESCRIPTION: Release the ACPI Global Lock
798  *
799  ******************************************************************************/
800
801 ACPI_STATUS
802 AcpiReleaseGlobalLock (
803     UINT32                  Handle)
804 {
805     ACPI_STATUS             Status;
806
807
808     if (Handle != AcpiGbl_GlobalLockHandle)
809     {
810         return (AE_NOT_ACQUIRED);
811     }
812
813     Status = AcpiEvReleaseGlobalLock ();
814     return (Status);
815 }
816
817