1 /****************************************************************************** 2 * 3 * Module Name: evxface - External interfaces for ACPI events 4 * $Revision: 1.157 $ 5 * 6 *****************************************************************************/ 7 8 /****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2006, 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 portion 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 142 ACPI_STATUS 143 AcpiInstallExceptionHandler ( 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 170 Cleanup: 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 192 ACPI_STATUS 193 AcpiInstallFixedEventHandler ( 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_WARNING ((AE_INFO, "Could not enable fixed event %X", Event)); 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 247 Cleanup: 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 266 ACPI_STATUS 267 AcpiRemoveFixedEventHandler ( 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_WARNING ((AE_INFO, 302 "Could not write to fixed event enable register %X", Event)); 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 332 ACPI_STATUS 333 AcpiInstallNotifyHandler ( 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 495 UnlockAndExit: 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 518 ACPI_STATUS 519 AcpiRemoveNotifyHandler ( 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, 562 "Removing notify handler for namespace root object\n")); 563 564 if (((HandlerType & ACPI_SYSTEM_NOTIFY) && 565 !AcpiGbl_SystemNotify.Handler) || 566 ((HandlerType & ACPI_DEVICE_NOTIFY) && 567 !AcpiGbl_DeviceNotify.Handler)) 568 { 569 Status = AE_NOT_EXIST; 570 goto UnlockAndExit; 571 } 572 573 if (HandlerType & ACPI_SYSTEM_NOTIFY) 574 { 575 AcpiGbl_SystemNotify.Node = NULL; 576 AcpiGbl_SystemNotify.Handler = NULL; 577 AcpiGbl_SystemNotify.Context = NULL; 578 } 579 580 if (HandlerType & ACPI_DEVICE_NOTIFY) 581 { 582 AcpiGbl_DeviceNotify.Node = NULL; 583 AcpiGbl_DeviceNotify.Handler = NULL; 584 AcpiGbl_DeviceNotify.Context = NULL; 585 } 586 } 587 588 /* All Other Objects */ 589 590 else 591 { 592 /* Notifies allowed on this object? */ 593 594 if (!AcpiEvIsNotifyObject (Node)) 595 { 596 Status = AE_TYPE; 597 goto UnlockAndExit; 598 } 599 600 /* Check for an existing internal object */ 601 602 ObjDesc = AcpiNsGetAttachedObject (Node); 603 if (!ObjDesc) 604 { 605 Status = AE_NOT_EXIST; 606 goto UnlockAndExit; 607 } 608 609 /* Object exists - make sure there's an existing handler */ 610 611 if (HandlerType & ACPI_SYSTEM_NOTIFY) 612 { 613 NotifyObj = ObjDesc->CommonNotify.SystemNotify; 614 if ((!NotifyObj) || 615 (NotifyObj->Notify.Handler != Handler)) 616 { 617 Status = AE_BAD_PARAMETER; 618 goto UnlockAndExit; 619 } 620 621 /* Remove the handler */ 622 623 ObjDesc->CommonNotify.SystemNotify = NULL; 624 AcpiUtRemoveReference (NotifyObj); 625 } 626 627 if (HandlerType & ACPI_DEVICE_NOTIFY) 628 { 629 NotifyObj = ObjDesc->CommonNotify.DeviceNotify; 630 if ((!NotifyObj) || 631 (NotifyObj->Notify.Handler != Handler)) 632 { 633 Status = AE_BAD_PARAMETER; 634 goto UnlockAndExit; 635 } 636 637 /* Remove the handler */ 638 639 ObjDesc->CommonNotify.DeviceNotify = NULL; 640 AcpiUtRemoveReference (NotifyObj); 641 } 642 } 643 644 645 UnlockAndExit: 646 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 647 return_ACPI_STATUS (Status); 648 } 649 650 651 /******************************************************************************* 652 * 653 * FUNCTION: AcpiInstallGpeHandler 654 * 655 * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 656 * defined GPEs) 657 * GpeNumber - The GPE number within the GPE block 658 * Type - Whether this GPE should be treated as an 659 * edge- or level-triggered interrupt. 660 * Address - Address of the handler 661 * Context - Value passed to the handler on each GPE 662 * 663 * RETURN: Status 664 * 665 * DESCRIPTION: Install a handler for a General Purpose Event. 666 * 667 ******************************************************************************/ 668 669 ACPI_STATUS 670 AcpiInstallGpeHandler ( 671 ACPI_HANDLE GpeDevice, 672 UINT32 GpeNumber, 673 UINT32 Type, 674 ACPI_EVENT_HANDLER Address, 675 void *Context) 676 { 677 ACPI_GPE_EVENT_INFO *GpeEventInfo; 678 ACPI_HANDLER_INFO *Handler; 679 ACPI_STATUS Status; 680 ACPI_CPU_FLAGS Flags; 681 682 683 ACPI_FUNCTION_TRACE ("AcpiInstallGpeHandler"); 684 685 686 /* Parameter validation */ 687 688 if ((!Address) || (Type > ACPI_GPE_XRUPT_TYPE_MASK)) 689 { 690 return_ACPI_STATUS (AE_BAD_PARAMETER); 691 } 692 693 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 694 if (ACPI_FAILURE (Status)) 695 { 696 return_ACPI_STATUS (Status); 697 } 698 699 /* Ensure that we have a valid GPE number */ 700 701 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 702 if (!GpeEventInfo) 703 { 704 Status = AE_BAD_PARAMETER; 705 goto UnlockAndExit; 706 } 707 708 /* Make sure that there isn't a handler there already */ 709 710 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) 711 { 712 Status = AE_ALREADY_EXISTS; 713 goto UnlockAndExit; 714 } 715 716 /* Allocate and init handler object */ 717 718 Handler = ACPI_MEM_CALLOCATE (sizeof (ACPI_HANDLER_INFO)); 719 if (!Handler) 720 { 721 Status = AE_NO_MEMORY; 722 goto UnlockAndExit; 723 } 724 725 Handler->Address = Address; 726 Handler->Context = Context; 727 Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode; 728 729 /* Disable the GPE before installing the handler */ 730 731 Status = AcpiEvDisableGpe (GpeEventInfo); 732 if (ACPI_FAILURE (Status)) 733 { 734 goto UnlockAndExit; 735 } 736 737 /* Install the handler */ 738 739 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 740 GpeEventInfo->Dispatch.Handler = Handler; 741 742 /* Setup up dispatch flags to indicate handler (vs. method) */ 743 744 GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); /* Clear bits */ 745 GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER); 746 747 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 748 749 750 UnlockAndExit: 751 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 752 return_ACPI_STATUS (Status); 753 } 754 755 756 /******************************************************************************* 757 * 758 * FUNCTION: AcpiRemoveGpeHandler 759 * 760 * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 761 * defined GPEs) 762 * GpeNumber - The event to remove a handler 763 * Address - Address of the handler 764 * 765 * RETURN: Status 766 * 767 * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent. 768 * 769 ******************************************************************************/ 770 771 ACPI_STATUS 772 AcpiRemoveGpeHandler ( 773 ACPI_HANDLE GpeDevice, 774 UINT32 GpeNumber, 775 ACPI_EVENT_HANDLER Address) 776 { 777 ACPI_GPE_EVENT_INFO *GpeEventInfo; 778 ACPI_HANDLER_INFO *Handler; 779 ACPI_STATUS Status; 780 ACPI_CPU_FLAGS Flags; 781 782 783 ACPI_FUNCTION_TRACE ("AcpiRemoveGpeHandler"); 784 785 786 /* Parameter validation */ 787 788 if (!Address) 789 { 790 return_ACPI_STATUS (AE_BAD_PARAMETER); 791 } 792 793 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 794 if (ACPI_FAILURE (Status)) 795 { 796 return_ACPI_STATUS (Status); 797 } 798 799 /* Ensure that we have a valid GPE number */ 800 801 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 802 if (!GpeEventInfo) 803 { 804 Status = AE_BAD_PARAMETER; 805 goto UnlockAndExit; 806 } 807 808 /* Make sure that a handler is indeed installed */ 809 810 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) != ACPI_GPE_DISPATCH_HANDLER) 811 { 812 Status = AE_NOT_EXIST; 813 goto UnlockAndExit; 814 } 815 816 /* Make sure that the installed handler is the same */ 817 818 if (GpeEventInfo->Dispatch.Handler->Address != Address) 819 { 820 Status = AE_BAD_PARAMETER; 821 goto UnlockAndExit; 822 } 823 824 /* Disable the GPE before removing the handler */ 825 826 Status = AcpiEvDisableGpe (GpeEventInfo); 827 if (ACPI_FAILURE (Status)) 828 { 829 goto UnlockAndExit; 830 } 831 832 /* Remove the handler */ 833 834 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 835 Handler = GpeEventInfo->Dispatch.Handler; 836 837 /* Restore Method node (if any), set dispatch flags */ 838 839 GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode; 840 GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */ 841 if (Handler->MethodNode) 842 { 843 GpeEventInfo->Flags |= ACPI_GPE_DISPATCH_METHOD; 844 } 845 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 846 847 /* Now we can free the handler object */ 848 849 ACPI_MEM_FREE (Handler); 850 851 852 UnlockAndExit: 853 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 854 return_ACPI_STATUS (Status); 855 } 856 857 858 /******************************************************************************* 859 * 860 * FUNCTION: AcpiAcquireGlobalLock 861 * 862 * PARAMETERS: Timeout - How long the caller is willing to wait 863 * Handle - Where the handle to the lock is returned 864 * (if acquired) 865 * 866 * RETURN: Status 867 * 868 * DESCRIPTION: Acquire the ACPI Global Lock 869 * 870 ******************************************************************************/ 871 872 ACPI_STATUS 873 AcpiAcquireGlobalLock ( 874 UINT16 Timeout, 875 UINT32 *Handle) 876 { 877 ACPI_STATUS Status; 878 879 880 if (!Handle) 881 { 882 return (AE_BAD_PARAMETER); 883 } 884 885 Status = AcpiExEnterInterpreter (); 886 if (ACPI_FAILURE (Status)) 887 { 888 return (Status); 889 } 890 891 Status = AcpiEvAcquireGlobalLock (Timeout); 892 AcpiExExitInterpreter (); 893 894 if (ACPI_SUCCESS (Status)) 895 { 896 AcpiGbl_GlobalLockHandle++; 897 *Handle = AcpiGbl_GlobalLockHandle; 898 } 899 900 return (Status); 901 } 902 903 904 /******************************************************************************* 905 * 906 * FUNCTION: AcpiReleaseGlobalLock 907 * 908 * PARAMETERS: Handle - Returned from AcpiAcquireGlobalLock 909 * 910 * RETURN: Status 911 * 912 * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid. 913 * 914 ******************************************************************************/ 915 916 ACPI_STATUS 917 AcpiReleaseGlobalLock ( 918 UINT32 Handle) 919 { 920 ACPI_STATUS Status; 921 922 923 if (Handle != AcpiGbl_GlobalLockHandle) 924 { 925 return (AE_NOT_ACQUIRED); 926 } 927 928 Status = AcpiEvReleaseGlobalLock (); 929 return (Status); 930 } 931 932 933