evxface.c revision 216471
1/****************************************************************************** 2 * 3 * Module Name: evxface - External interfaces for ACPI events 4 * 5 *****************************************************************************/ 6 7/****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116 117#define __EVXFACE_C__ 118 119#include <contrib/dev/acpica/include/acpi.h> 120#include <contrib/dev/acpica/include/accommon.h> 121#include <contrib/dev/acpica/include/acnamesp.h> 122#include <contrib/dev/acpica/include/acevents.h> 123#include <contrib/dev/acpica/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 175ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler) 176 177 178/******************************************************************************* 179 * 180 * FUNCTION: AcpiInstallGlobalEventHandler 181 * 182 * PARAMETERS: Handler - Pointer to the global event handler function 183 * Context - Value passed to the handler on each event 184 * 185 * RETURN: Status 186 * 187 * DESCRIPTION: Saves the pointer to the handler function. The global handler 188 * is invoked upon each incoming GPE and Fixed Event. It is 189 * invoked at interrupt level at the time of the event dispatch. 190 * Can be used to update event counters, etc. 191 * 192 ******************************************************************************/ 193 194ACPI_STATUS 195AcpiInstallGlobalEventHandler ( 196 ACPI_GBL_EVENT_HANDLER Handler, 197 void *Context) 198{ 199 ACPI_STATUS Status; 200 201 202 ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler); 203 204 205 /* Parameter validation */ 206 207 if (!Handler) 208 { 209 return_ACPI_STATUS (AE_BAD_PARAMETER); 210 } 211 212 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 213 if (ACPI_FAILURE (Status)) 214 { 215 return_ACPI_STATUS (Status); 216 } 217 218 /* Don't allow two handlers. */ 219 220 if (AcpiGbl_GlobalEventHandler) 221 { 222 Status = AE_ALREADY_EXISTS; 223 goto Cleanup; 224 } 225 226 AcpiGbl_GlobalEventHandler = Handler; 227 AcpiGbl_GlobalEventHandlerContext = Context; 228 229 230Cleanup: 231 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 232 return_ACPI_STATUS (Status); 233} 234 235ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler) 236 237 238/******************************************************************************* 239 * 240 * FUNCTION: AcpiInstallFixedEventHandler 241 * 242 * PARAMETERS: Event - Event type to enable. 243 * Handler - Pointer to the handler function for the 244 * event 245 * Context - Value passed to the handler on each GPE 246 * 247 * RETURN: Status 248 * 249 * DESCRIPTION: Saves the pointer to the handler function and then enables the 250 * event. 251 * 252 ******************************************************************************/ 253 254ACPI_STATUS 255AcpiInstallFixedEventHandler ( 256 UINT32 Event, 257 ACPI_EVENT_HANDLER Handler, 258 void *Context) 259{ 260 ACPI_STATUS Status; 261 262 263 ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler); 264 265 266 /* Parameter validation */ 267 268 if (Event > ACPI_EVENT_MAX) 269 { 270 return_ACPI_STATUS (AE_BAD_PARAMETER); 271 } 272 273 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 274 if (ACPI_FAILURE (Status)) 275 { 276 return_ACPI_STATUS (Status); 277 } 278 279 /* Don't allow two handlers. */ 280 281 if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler) 282 { 283 Status = AE_ALREADY_EXISTS; 284 goto Cleanup; 285 } 286 287 /* Install the handler before enabling the event */ 288 289 AcpiGbl_FixedEventHandlers[Event].Handler = Handler; 290 AcpiGbl_FixedEventHandlers[Event].Context = Context; 291 292 Status = AcpiEnableEvent (Event, 0); 293 if (ACPI_FAILURE (Status)) 294 { 295 ACPI_WARNING ((AE_INFO, "Could not enable fixed event 0x%X", Event)); 296 297 /* Remove the handler */ 298 299 AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 300 AcpiGbl_FixedEventHandlers[Event].Context = NULL; 301 } 302 else 303 { 304 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 305 "Enabled fixed event %X, Handler=%p\n", Event, Handler)); 306 } 307 308 309Cleanup: 310 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 311 return_ACPI_STATUS (Status); 312} 313 314ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler) 315 316 317/******************************************************************************* 318 * 319 * FUNCTION: AcpiRemoveFixedEventHandler 320 * 321 * PARAMETERS: Event - Event type to disable. 322 * Handler - Address of the handler 323 * 324 * RETURN: Status 325 * 326 * DESCRIPTION: Disables the event and unregisters the event handler. 327 * 328 ******************************************************************************/ 329 330ACPI_STATUS 331AcpiRemoveFixedEventHandler ( 332 UINT32 Event, 333 ACPI_EVENT_HANDLER Handler) 334{ 335 ACPI_STATUS Status = AE_OK; 336 337 338 ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler); 339 340 341 /* Parameter validation */ 342 343 if (Event > ACPI_EVENT_MAX) 344 { 345 return_ACPI_STATUS (AE_BAD_PARAMETER); 346 } 347 348 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 349 if (ACPI_FAILURE (Status)) 350 { 351 return_ACPI_STATUS (Status); 352 } 353 354 /* Disable the event before removing the handler */ 355 356 Status = AcpiDisableEvent (Event, 0); 357 358 /* Always Remove the handler */ 359 360 AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 361 AcpiGbl_FixedEventHandlers[Event].Context = NULL; 362 363 if (ACPI_FAILURE (Status)) 364 { 365 ACPI_WARNING ((AE_INFO, 366 "Could not write to fixed event enable register 0x%X", Event)); 367 } 368 else 369 { 370 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X\n", Event)); 371 } 372 373 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 374 return_ACPI_STATUS (Status); 375} 376 377ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler) 378 379 380/******************************************************************************* 381 * 382 * FUNCTION: AcpiInstallNotifyHandler 383 * 384 * PARAMETERS: Device - The device for which notifies will be handled 385 * HandlerType - The type of handler: 386 * ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f) 387 * ACPI_DEVICE_NOTIFY: DriverHandler (80-ff) 388 * ACPI_ALL_NOTIFY: both system and device 389 * Handler - Address of the handler 390 * Context - Value passed to the handler on each GPE 391 * 392 * RETURN: Status 393 * 394 * DESCRIPTION: Install a handler for notifies on an ACPI device 395 * 396 ******************************************************************************/ 397 398ACPI_STATUS 399AcpiInstallNotifyHandler ( 400 ACPI_HANDLE Device, 401 UINT32 HandlerType, 402 ACPI_NOTIFY_HANDLER Handler, 403 void *Context) 404{ 405 ACPI_OPERAND_OBJECT *ObjDesc; 406 ACPI_OPERAND_OBJECT *NotifyObj; 407 ACPI_NAMESPACE_NODE *Node; 408 ACPI_STATUS Status; 409 410 411 ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler); 412 413 414 /* Parameter validation */ 415 416 if ((!Device) || 417 (!Handler) || 418 (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 419 { 420 return_ACPI_STATUS (AE_BAD_PARAMETER); 421 } 422 423 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 424 if (ACPI_FAILURE (Status)) 425 { 426 return_ACPI_STATUS (Status); 427 } 428 429 /* Convert and validate the device handle */ 430 431 Node = AcpiNsValidateHandle (Device); 432 if (!Node) 433 { 434 Status = AE_BAD_PARAMETER; 435 goto UnlockAndExit; 436 } 437 438 /* 439 * Root Object: 440 * Registering a notify handler on the root object indicates that the 441 * caller wishes to receive notifications for all objects. Note that 442 * only one <external> global handler can be regsitered (per notify type). 443 */ 444 if (Device == ACPI_ROOT_OBJECT) 445 { 446 /* Make sure the handler is not already installed */ 447 448 if (((HandlerType & ACPI_SYSTEM_NOTIFY) && 449 AcpiGbl_SystemNotify.Handler) || 450 ((HandlerType & ACPI_DEVICE_NOTIFY) && 451 AcpiGbl_DeviceNotify.Handler)) 452 { 453 Status = AE_ALREADY_EXISTS; 454 goto UnlockAndExit; 455 } 456 457 if (HandlerType & ACPI_SYSTEM_NOTIFY) 458 { 459 AcpiGbl_SystemNotify.Node = Node; 460 AcpiGbl_SystemNotify.Handler = Handler; 461 AcpiGbl_SystemNotify.Context = Context; 462 } 463 464 if (HandlerType & ACPI_DEVICE_NOTIFY) 465 { 466 AcpiGbl_DeviceNotify.Node = Node; 467 AcpiGbl_DeviceNotify.Handler = Handler; 468 AcpiGbl_DeviceNotify.Context = Context; 469 } 470 471 /* Global notify handler installed */ 472 } 473 474 /* 475 * All Other Objects: 476 * Caller will only receive notifications specific to the target object. 477 * Note that only certain object types can receive notifications. 478 */ 479 else 480 { 481 /* Notifies allowed on this object? */ 482 483 if (!AcpiEvIsNotifyObject (Node)) 484 { 485 Status = AE_TYPE; 486 goto UnlockAndExit; 487 } 488 489 /* Check for an existing internal object */ 490 491 ObjDesc = AcpiNsGetAttachedObject (Node); 492 if (ObjDesc) 493 { 494 /* Object exists - make sure there's no handler */ 495 496 if (((HandlerType & ACPI_SYSTEM_NOTIFY) && 497 ObjDesc->CommonNotify.SystemNotify) || 498 ((HandlerType & ACPI_DEVICE_NOTIFY) && 499 ObjDesc->CommonNotify.DeviceNotify)) 500 { 501 Status = AE_ALREADY_EXISTS; 502 goto UnlockAndExit; 503 } 504 } 505 else 506 { 507 /* Create a new object */ 508 509 ObjDesc = AcpiUtCreateInternalObject (Node->Type); 510 if (!ObjDesc) 511 { 512 Status = AE_NO_MEMORY; 513 goto UnlockAndExit; 514 } 515 516 /* Attach new object to the Node */ 517 518 Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type); 519 520 /* Remove local reference to the object */ 521 522 AcpiUtRemoveReference (ObjDesc); 523 if (ACPI_FAILURE (Status)) 524 { 525 goto UnlockAndExit; 526 } 527 } 528 529 /* Install the handler */ 530 531 NotifyObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY); 532 if (!NotifyObj) 533 { 534 Status = AE_NO_MEMORY; 535 goto UnlockAndExit; 536 } 537 538 NotifyObj->Notify.Node = Node; 539 NotifyObj->Notify.Handler = Handler; 540 NotifyObj->Notify.Context = Context; 541 542 if (HandlerType & ACPI_SYSTEM_NOTIFY) 543 { 544 ObjDesc->CommonNotify.SystemNotify = NotifyObj; 545 } 546 547 if (HandlerType & ACPI_DEVICE_NOTIFY) 548 { 549 ObjDesc->CommonNotify.DeviceNotify = NotifyObj; 550 } 551 552 if (HandlerType == ACPI_ALL_NOTIFY) 553 { 554 /* Extra ref if installed in both */ 555 556 AcpiUtAddReference (NotifyObj); 557 } 558 } 559 560 561UnlockAndExit: 562 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 563 return_ACPI_STATUS (Status); 564} 565 566ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler) 567 568 569/******************************************************************************* 570 * 571 * FUNCTION: AcpiRemoveNotifyHandler 572 * 573 * PARAMETERS: Device - The device for which notifies will be handled 574 * HandlerType - The type of handler: 575 * ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f) 576 * ACPI_DEVICE_NOTIFY: DriverHandler (80-ff) 577 * ACPI_ALL_NOTIFY: both system and device 578 * Handler - Address of the handler 579 * 580 * RETURN: Status 581 * 582 * DESCRIPTION: Remove a handler for notifies on an ACPI device 583 * 584 ******************************************************************************/ 585 586ACPI_STATUS 587AcpiRemoveNotifyHandler ( 588 ACPI_HANDLE Device, 589 UINT32 HandlerType, 590 ACPI_NOTIFY_HANDLER Handler) 591{ 592 ACPI_OPERAND_OBJECT *NotifyObj; 593 ACPI_OPERAND_OBJECT *ObjDesc; 594 ACPI_NAMESPACE_NODE *Node; 595 ACPI_STATUS Status; 596 597 598 ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler); 599 600 601 /* Parameter validation */ 602 603 if ((!Device) || 604 (!Handler) || 605 (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 606 { 607 return_ACPI_STATUS (AE_BAD_PARAMETER); 608 } 609 610 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 611 if (ACPI_FAILURE (Status)) 612 { 613 return_ACPI_STATUS (Status); 614 } 615 616 /* Convert and validate the device handle */ 617 618 Node = AcpiNsValidateHandle (Device); 619 if (!Node) 620 { 621 Status = AE_BAD_PARAMETER; 622 goto UnlockAndExit; 623 } 624 625 /* Root Object */ 626 627 if (Device == ACPI_ROOT_OBJECT) 628 { 629 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 630 "Removing notify handler for namespace root object\n")); 631 632 if (((HandlerType & ACPI_SYSTEM_NOTIFY) && 633 !AcpiGbl_SystemNotify.Handler) || 634 ((HandlerType & ACPI_DEVICE_NOTIFY) && 635 !AcpiGbl_DeviceNotify.Handler)) 636 { 637 Status = AE_NOT_EXIST; 638 goto UnlockAndExit; 639 } 640 641 if (HandlerType & ACPI_SYSTEM_NOTIFY) 642 { 643 AcpiGbl_SystemNotify.Node = NULL; 644 AcpiGbl_SystemNotify.Handler = NULL; 645 AcpiGbl_SystemNotify.Context = NULL; 646 } 647 648 if (HandlerType & ACPI_DEVICE_NOTIFY) 649 { 650 AcpiGbl_DeviceNotify.Node = NULL; 651 AcpiGbl_DeviceNotify.Handler = NULL; 652 AcpiGbl_DeviceNotify.Context = NULL; 653 } 654 } 655 656 /* All Other Objects */ 657 658 else 659 { 660 /* Notifies allowed on this object? */ 661 662 if (!AcpiEvIsNotifyObject (Node)) 663 { 664 Status = AE_TYPE; 665 goto UnlockAndExit; 666 } 667 668 /* Check for an existing internal object */ 669 670 ObjDesc = AcpiNsGetAttachedObject (Node); 671 if (!ObjDesc) 672 { 673 Status = AE_NOT_EXIST; 674 goto UnlockAndExit; 675 } 676 677 /* Object exists - make sure there's an existing handler */ 678 679 if (HandlerType & ACPI_SYSTEM_NOTIFY) 680 { 681 NotifyObj = ObjDesc->CommonNotify.SystemNotify; 682 if (!NotifyObj) 683 { 684 Status = AE_NOT_EXIST; 685 goto UnlockAndExit; 686 } 687 688 if (NotifyObj->Notify.Handler != Handler) 689 { 690 Status = AE_BAD_PARAMETER; 691 goto UnlockAndExit; 692 } 693 694 /* Remove the handler */ 695 696 ObjDesc->CommonNotify.SystemNotify = NULL; 697 AcpiUtRemoveReference (NotifyObj); 698 } 699 700 if (HandlerType & ACPI_DEVICE_NOTIFY) 701 { 702 NotifyObj = ObjDesc->CommonNotify.DeviceNotify; 703 if (!NotifyObj) 704 { 705 Status = AE_NOT_EXIST; 706 goto UnlockAndExit; 707 } 708 709 if (NotifyObj->Notify.Handler != Handler) 710 { 711 Status = AE_BAD_PARAMETER; 712 goto UnlockAndExit; 713 } 714 715 /* Remove the handler */ 716 717 ObjDesc->CommonNotify.DeviceNotify = NULL; 718 AcpiUtRemoveReference (NotifyObj); 719 } 720 } 721 722 723UnlockAndExit: 724 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 725 return_ACPI_STATUS (Status); 726} 727 728ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler) 729 730 731/******************************************************************************* 732 * 733 * FUNCTION: AcpiInstallGpeHandler 734 * 735 * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 736 * defined GPEs) 737 * GpeNumber - The GPE number within the GPE block 738 * Type - Whether this GPE should be treated as an 739 * edge- or level-triggered interrupt. 740 * Address - Address of the handler 741 * Context - Value passed to the handler on each GPE 742 * 743 * RETURN: Status 744 * 745 * DESCRIPTION: Install a handler for a General Purpose Event. 746 * 747 ******************************************************************************/ 748 749ACPI_STATUS 750AcpiInstallGpeHandler ( 751 ACPI_HANDLE GpeDevice, 752 UINT32 GpeNumber, 753 UINT32 Type, 754 ACPI_GPE_HANDLER Address, 755 void *Context) 756{ 757 ACPI_GPE_EVENT_INFO *GpeEventInfo; 758 ACPI_GPE_HANDLER_INFO *Handler; 759 ACPI_STATUS Status; 760 ACPI_CPU_FLAGS Flags; 761 762 763 ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler); 764 765 766 /* Parameter validation */ 767 768 if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK)) 769 { 770 return_ACPI_STATUS (AE_BAD_PARAMETER); 771 } 772 773 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 774 if (ACPI_FAILURE (Status)) 775 { 776 return_ACPI_STATUS (Status); 777 } 778 779 /* Allocate and init handler object (before lock) */ 780 781 Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO)); 782 if (!Handler) 783 { 784 Status = AE_NO_MEMORY; 785 goto UnlockAndExit; 786 } 787 788 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 789 790 /* Ensure that we have a valid GPE number */ 791 792 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 793 if (!GpeEventInfo) 794 { 795 Status = AE_BAD_PARAMETER; 796 goto FreeAndExit; 797 } 798 799 /* Make sure that there isn't a handler there already */ 800 801 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 802 ACPI_GPE_DISPATCH_HANDLER) 803 { 804 Status = AE_ALREADY_EXISTS; 805 goto FreeAndExit; 806 } 807 808 Handler->Address = Address; 809 Handler->Context = Context; 810 Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode; 811 Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags & 812 (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK)); 813 814 /* 815 * If the GPE is associated with a method, it may have been enabled 816 * automatically during initialization, in which case it has to be 817 * disabled now to avoid spurious execution of the handler. 818 */ 819 if (((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) || 820 (Handler->OriginalFlags & ACPI_GPE_DISPATCH_NOTIFY)) && 821 GpeEventInfo->RuntimeCount) 822 { 823 Handler->OriginallyEnabled = TRUE; 824 (void) AcpiEvRemoveGpeReference (GpeEventInfo); 825 826 /* Sanity check of original type against new type */ 827 828 if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK)) 829 { 830 ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)")); 831 } 832 } 833 834 /* Install the handler */ 835 836 GpeEventInfo->Dispatch.Handler = Handler; 837 838 /* Setup up dispatch flags to indicate handler (vs. method/notify) */ 839 840 GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 841 GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER); 842 843 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 844 845 846UnlockAndExit: 847 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 848 return_ACPI_STATUS (Status); 849 850FreeAndExit: 851 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 852 ACPI_FREE (Handler); 853 goto UnlockAndExit; 854} 855 856ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler) 857 858 859/******************************************************************************* 860 * 861 * FUNCTION: AcpiRemoveGpeHandler 862 * 863 * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 864 * defined GPEs) 865 * GpeNumber - The event to remove a handler 866 * Address - Address of the handler 867 * 868 * RETURN: Status 869 * 870 * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent. 871 * 872 ******************************************************************************/ 873 874ACPI_STATUS 875AcpiRemoveGpeHandler ( 876 ACPI_HANDLE GpeDevice, 877 UINT32 GpeNumber, 878 ACPI_GPE_HANDLER Address) 879{ 880 ACPI_GPE_EVENT_INFO *GpeEventInfo; 881 ACPI_GPE_HANDLER_INFO *Handler; 882 ACPI_STATUS Status; 883 ACPI_CPU_FLAGS Flags; 884 885 886 ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler); 887 888 889 /* Parameter validation */ 890 891 if (!Address) 892 { 893 return_ACPI_STATUS (AE_BAD_PARAMETER); 894 } 895 896 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 897 if (ACPI_FAILURE (Status)) 898 { 899 return_ACPI_STATUS (Status); 900 } 901 902 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 903 904 /* Ensure that we have a valid GPE number */ 905 906 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 907 if (!GpeEventInfo) 908 { 909 Status = AE_BAD_PARAMETER; 910 goto UnlockAndExit; 911 } 912 913 /* Make sure that a handler is indeed installed */ 914 915 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) != 916 ACPI_GPE_DISPATCH_HANDLER) 917 { 918 Status = AE_NOT_EXIST; 919 goto UnlockAndExit; 920 } 921 922 /* Make sure that the installed handler is the same */ 923 924 if (GpeEventInfo->Dispatch.Handler->Address != Address) 925 { 926 Status = AE_BAD_PARAMETER; 927 goto UnlockAndExit; 928 } 929 930 /* Remove the handler */ 931 932 Handler = GpeEventInfo->Dispatch.Handler; 933 934 /* Restore Method node (if any), set dispatch flags */ 935 936 GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode; 937 GpeEventInfo->Flags &= 938 ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 939 GpeEventInfo->Flags |= Handler->OriginalFlags; 940 941 /* 942 * If the GPE was previously associated with a method and it was 943 * enabled, it should be enabled at this point to restore the 944 * post-initialization configuration. 945 */ 946 if ((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) && 947 Handler->OriginallyEnabled) 948 { 949 (void) AcpiEvAddGpeReference (GpeEventInfo); 950 } 951 952 /* Now we can free the handler object */ 953 954 ACPI_FREE (Handler); 955 956 957UnlockAndExit: 958 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 959 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 960 return_ACPI_STATUS (Status); 961} 962 963ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler) 964 965 966/******************************************************************************* 967 * 968 * FUNCTION: AcpiAcquireGlobalLock 969 * 970 * PARAMETERS: Timeout - How long the caller is willing to wait 971 * Handle - Where the handle to the lock is returned 972 * (if acquired) 973 * 974 * RETURN: Status 975 * 976 * DESCRIPTION: Acquire the ACPI Global Lock 977 * 978 * Note: Allows callers with the same thread ID to acquire the global lock 979 * multiple times. In other words, externally, the behavior of the global lock 980 * is identical to an AML mutex. On the first acquire, a new handle is 981 * returned. On any subsequent calls to acquire by the same thread, the same 982 * handle is returned. 983 * 984 ******************************************************************************/ 985 986ACPI_STATUS 987AcpiAcquireGlobalLock ( 988 UINT16 Timeout, 989 UINT32 *Handle) 990{ 991 ACPI_STATUS Status; 992 993 994 if (!Handle) 995 { 996 return (AE_BAD_PARAMETER); 997 } 998 999 /* Must lock interpreter to prevent race conditions */ 1000 1001 AcpiExEnterInterpreter (); 1002 1003 Status = AcpiExAcquireMutexObject (Timeout, 1004 AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ()); 1005 1006 if (ACPI_SUCCESS (Status)) 1007 { 1008 /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */ 1009 1010 *Handle = AcpiGbl_GlobalLockHandle; 1011 } 1012 1013 AcpiExExitInterpreter (); 1014 return (Status); 1015} 1016 1017ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock) 1018 1019 1020/******************************************************************************* 1021 * 1022 * FUNCTION: AcpiReleaseGlobalLock 1023 * 1024 * PARAMETERS: Handle - Returned from AcpiAcquireGlobalLock 1025 * 1026 * RETURN: Status 1027 * 1028 * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid. 1029 * 1030 ******************************************************************************/ 1031 1032ACPI_STATUS 1033AcpiReleaseGlobalLock ( 1034 UINT32 Handle) 1035{ 1036 ACPI_STATUS Status; 1037 1038 1039 if (!Handle || (Handle != AcpiGbl_GlobalLockHandle)) 1040 { 1041 return (AE_NOT_ACQUIRED); 1042 } 1043 1044 Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex); 1045 return (Status); 1046} 1047 1048ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock) 1049 1050