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