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 - 2022, 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 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 #define EXPORT_ACPI_INTERFACES 153 154 #include <contrib/dev/acpica/include/acpi.h> 155 #include <contrib/dev/acpica/include/accommon.h> 156 #include <contrib/dev/acpica/include/acnamesp.h> 157 #include <contrib/dev/acpica/include/acevents.h> 158 #include <contrib/dev/acpica/include/acinterp.h> 159 160 #define _COMPONENT ACPI_EVENTS 161 ACPI_MODULE_NAME ("evxface") 162 163 #if (!ACPI_REDUCED_HARDWARE) 164 165 /* Local prototypes */ 166 167 static ACPI_STATUS 168 AcpiEvInstallGpeHandler ( 169 ACPI_HANDLE GpeDevice, 170 UINT32 GpeNumber, 171 UINT32 Type, 172 BOOLEAN IsRawHandler, 173 ACPI_GPE_HANDLER Address, 174 void *Context); 175 176 #endif 177 178 179 /******************************************************************************* 180 * 181 * FUNCTION: AcpiInstallNotifyHandler 182 * 183 * PARAMETERS: Device - The device for which notifies will be handled 184 * HandlerType - The type of handler: 185 * ACPI_SYSTEM_NOTIFY: System Handler (00-7F) 186 * ACPI_DEVICE_NOTIFY: Device Handler (80-FF) 187 * ACPI_ALL_NOTIFY: Both System and Device 188 * Handler - Address of the handler 189 * Context - Value passed to the handler on each GPE 190 * 191 * RETURN: Status 192 * 193 * DESCRIPTION: Install a handler for notifications on an ACPI Device, 194 * ThermalZone, or Processor object. 195 * 196 * NOTES: The Root namespace object may have only one handler for each 197 * type of notify (System/Device). Device/Thermal/Processor objects 198 * may have one device notify handler, and multiple system notify 199 * handlers. 200 * 201 ******************************************************************************/ 202 203 ACPI_STATUS 204 AcpiInstallNotifyHandler ( 205 ACPI_HANDLE Device, 206 UINT32 HandlerType, 207 ACPI_NOTIFY_HANDLER Handler, 208 void *Context) 209 { 210 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device); 211 ACPI_OPERAND_OBJECT *ObjDesc; 212 ACPI_OPERAND_OBJECT *HandlerObj; 213 ACPI_STATUS Status; 214 UINT32 i; 215 216 217 ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler); 218 219 220 /* Parameter validation */ 221 222 if ((!Device) || (!Handler) || (!HandlerType) || 223 (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 224 { 225 return_ACPI_STATUS (AE_BAD_PARAMETER); 226 } 227 228 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 229 if (ACPI_FAILURE (Status)) 230 { 231 return_ACPI_STATUS (Status); 232 } 233 234 /* 235 * Root Object: 236 * Registering a notify handler on the root object indicates that the 237 * caller wishes to receive notifications for all objects. Note that 238 * only one global handler can be registered per notify type. 239 * Ensure that a handler is not already installed. 240 */ 241 if (Device == ACPI_ROOT_OBJECT) 242 { 243 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 244 { 245 if (HandlerType & (i+1)) 246 { 247 if (AcpiGbl_GlobalNotify[i].Handler) 248 { 249 Status = AE_ALREADY_EXISTS; 250 goto UnlockAndExit; 251 } 252 253 AcpiGbl_GlobalNotify[i].Handler = Handler; 254 AcpiGbl_GlobalNotify[i].Context = Context; 255 } 256 } 257 258 goto UnlockAndExit; /* Global notify handler installed, all done */ 259 } 260 261 /* 262 * All Other Objects: 263 * Caller will only receive notifications specific to the target 264 * object. Note that only certain object types are allowed to 265 * receive notifications. 266 */ 267 268 /* Are Notifies allowed on this object? */ 269 270 if (!AcpiEvIsNotifyObject (Node)) 271 { 272 Status = AE_TYPE; 273 goto UnlockAndExit; 274 } 275 276 /* Check for an existing internal object, might not exist */ 277 278 ObjDesc = AcpiNsGetAttachedObject (Node); 279 if (!ObjDesc) 280 { 281 /* Create a new object */ 282 283 ObjDesc = AcpiUtCreateInternalObject (Node->Type); 284 if (!ObjDesc) 285 { 286 Status = AE_NO_MEMORY; 287 goto UnlockAndExit; 288 } 289 290 /* Attach new object to the Node, remove local reference */ 291 292 Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type); 293 AcpiUtRemoveReference (ObjDesc); 294 if (ACPI_FAILURE (Status)) 295 { 296 goto UnlockAndExit; 297 } 298 } 299 300 /* Ensure that the handler is not already installed in the lists */ 301 302 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 303 { 304 if (HandlerType & (i+1)) 305 { 306 HandlerObj = ObjDesc->CommonNotify.NotifyList[i]; 307 while (HandlerObj) 308 { 309 if (HandlerObj->Notify.Handler == Handler) 310 { 311 Status = AE_ALREADY_EXISTS; 312 goto UnlockAndExit; 313 } 314 315 HandlerObj = HandlerObj->Notify.Next[i]; 316 } 317 } 318 } 319 320 /* Create and populate a new notify handler object */ 321 322 HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY); 323 if (!HandlerObj) 324 { 325 Status = AE_NO_MEMORY; 326 goto UnlockAndExit; 327 } 328 329 HandlerObj->Notify.Node = Node; 330 HandlerObj->Notify.HandlerType = HandlerType; 331 HandlerObj->Notify.Handler = Handler; 332 HandlerObj->Notify.Context = Context; 333 334 /* Install the handler at the list head(s) */ 335 336 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 337 { 338 if (HandlerType & (i+1)) 339 { 340 HandlerObj->Notify.Next[i] = 341 ObjDesc->CommonNotify.NotifyList[i]; 342 343 ObjDesc->CommonNotify.NotifyList[i] = HandlerObj; 344 } 345 } 346 347 /* Add an extra reference if handler was installed in both lists */ 348 349 if (HandlerType == ACPI_ALL_NOTIFY) 350 { 351 AcpiUtAddReference (HandlerObj); 352 } 353 354 355 UnlockAndExit: 356 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 357 return_ACPI_STATUS (Status); 358 } 359 360 ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler) 361 362 363 /******************************************************************************* 364 * 365 * FUNCTION: AcpiRemoveNotifyHandler 366 * 367 * PARAMETERS: Device - The device for which the handler is installed 368 * HandlerType - The type of handler: 369 * ACPI_SYSTEM_NOTIFY: System Handler (00-7F) 370 * ACPI_DEVICE_NOTIFY: Device Handler (80-FF) 371 * ACPI_ALL_NOTIFY: Both System and Device 372 * Handler - Address of the handler 373 * 374 * RETURN: Status 375 * 376 * DESCRIPTION: Remove a handler for notifies on an ACPI device 377 * 378 ******************************************************************************/ 379 380 ACPI_STATUS 381 AcpiRemoveNotifyHandler ( 382 ACPI_HANDLE Device, 383 UINT32 HandlerType, 384 ACPI_NOTIFY_HANDLER Handler) 385 { 386 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device); 387 ACPI_OPERAND_OBJECT *ObjDesc; 388 ACPI_OPERAND_OBJECT *HandlerObj; 389 ACPI_OPERAND_OBJECT *PreviousHandlerObj; 390 ACPI_STATUS Status = AE_OK; 391 UINT32 i; 392 393 394 ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler); 395 396 397 /* Parameter validation */ 398 399 if ((!Device) || (!Handler) || (!HandlerType) || 400 (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 401 { 402 return_ACPI_STATUS (AE_BAD_PARAMETER); 403 } 404 405 /* Root Object. Global handlers are removed here */ 406 407 if (Device == ACPI_ROOT_OBJECT) 408 { 409 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 410 { 411 if (HandlerType & (i+1)) 412 { 413 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 414 if (ACPI_FAILURE (Status)) 415 { 416 return_ACPI_STATUS (Status); 417 } 418 419 if (!AcpiGbl_GlobalNotify[i].Handler || 420 (AcpiGbl_GlobalNotify[i].Handler != Handler)) 421 { 422 Status = AE_NOT_EXIST; 423 goto UnlockAndExit; 424 } 425 426 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 427 "Removing global notify handler\n")); 428 429 AcpiGbl_GlobalNotify[i].Handler = NULL; 430 AcpiGbl_GlobalNotify[i].Context = NULL; 431 432 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 433 434 /* Make sure all deferred notify tasks are completed */ 435 436 AcpiOsWaitEventsComplete (); 437 } 438 } 439 440 return_ACPI_STATUS (AE_OK); 441 } 442 443 /* All other objects: Are Notifies allowed on this object? */ 444 445 if (!AcpiEvIsNotifyObject (Node)) 446 { 447 return_ACPI_STATUS (AE_TYPE); 448 } 449 450 /* Must have an existing internal object */ 451 452 ObjDesc = AcpiNsGetAttachedObject (Node); 453 if (!ObjDesc) 454 { 455 return_ACPI_STATUS (AE_NOT_EXIST); 456 } 457 458 /* Internal object exists. Find the handler and remove it */ 459 460 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 461 { 462 if (HandlerType & (i+1)) 463 { 464 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 465 if (ACPI_FAILURE (Status)) 466 { 467 return_ACPI_STATUS (Status); 468 } 469 470 HandlerObj = ObjDesc->CommonNotify.NotifyList[i]; 471 PreviousHandlerObj = NULL; 472 473 /* Attempt to find the handler in the handler list */ 474 475 while (HandlerObj && 476 (HandlerObj->Notify.Handler != Handler)) 477 { 478 PreviousHandlerObj = HandlerObj; 479 HandlerObj = HandlerObj->Notify.Next[i]; 480 } 481 482 if (!HandlerObj) 483 { 484 Status = AE_NOT_EXIST; 485 goto UnlockAndExit; 486 } 487 488 /* Remove the handler object from the list */ 489 490 if (PreviousHandlerObj) /* Handler is not at the list head */ 491 { 492 PreviousHandlerObj->Notify.Next[i] = 493 HandlerObj->Notify.Next[i]; 494 } 495 else /* Handler is at the list head */ 496 { 497 ObjDesc->CommonNotify.NotifyList[i] = 498 HandlerObj->Notify.Next[i]; 499 } 500 501 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 502 503 /* Make sure all deferred notify tasks are completed */ 504 505 AcpiOsWaitEventsComplete (); 506 AcpiUtRemoveReference (HandlerObj); 507 } 508 } 509 510 return_ACPI_STATUS (Status); 511 512 513 UnlockAndExit: 514 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 515 return_ACPI_STATUS (Status); 516 } 517 518 ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler) 519 520 521 /******************************************************************************* 522 * 523 * FUNCTION: AcpiInstallExceptionHandler 524 * 525 * PARAMETERS: Handler - Pointer to the handler function for the 526 * event 527 * 528 * RETURN: Status 529 * 530 * DESCRIPTION: Saves the pointer to the handler function 531 * 532 ******************************************************************************/ 533 534 ACPI_STATUS 535 AcpiInstallExceptionHandler ( 536 ACPI_EXCEPTION_HANDLER Handler) 537 { 538 ACPI_STATUS Status; 539 540 541 ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler); 542 543 544 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 545 if (ACPI_FAILURE (Status)) 546 { 547 return_ACPI_STATUS (Status); 548 } 549 550 /* Don't allow two handlers. */ 551 552 if (AcpiGbl_ExceptionHandler) 553 { 554 Status = AE_ALREADY_EXISTS; 555 goto Cleanup; 556 } 557 558 /* Install the handler */ 559 560 AcpiGbl_ExceptionHandler = Handler; 561 562 Cleanup: 563 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 564 return_ACPI_STATUS (Status); 565 } 566 567 ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler) 568 569 570 #if (!ACPI_REDUCED_HARDWARE) 571 /******************************************************************************* 572 * 573 * FUNCTION: AcpiInstallSciHandler 574 * 575 * PARAMETERS: Address - Address of the handler 576 * Context - Value passed to the handler on each SCI 577 * 578 * RETURN: Status 579 * 580 * DESCRIPTION: Install a handler for a System Control Interrupt. 581 * 582 ******************************************************************************/ 583 584 ACPI_STATUS 585 AcpiInstallSciHandler ( 586 ACPI_SCI_HANDLER Address, 587 void *Context) 588 { 589 ACPI_SCI_HANDLER_INFO *NewSciHandler; 590 ACPI_SCI_HANDLER_INFO *SciHandler; 591 ACPI_CPU_FLAGS Flags; 592 ACPI_STATUS Status; 593 594 595 ACPI_FUNCTION_TRACE (AcpiInstallSciHandler); 596 597 598 if (!Address) 599 { 600 return_ACPI_STATUS (AE_BAD_PARAMETER); 601 } 602 603 /* Allocate and init a handler object */ 604 605 NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO)); 606 if (!NewSciHandler) 607 { 608 return_ACPI_STATUS (AE_NO_MEMORY); 609 } 610 611 NewSciHandler->Address = Address; 612 NewSciHandler->Context = Context; 613 614 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 615 if (ACPI_FAILURE (Status)) 616 { 617 goto Exit; 618 } 619 620 /* Lock list during installation */ 621 622 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 623 SciHandler = AcpiGbl_SciHandlerList; 624 625 /* Ensure handler does not already exist */ 626 627 while (SciHandler) 628 { 629 if (Address == SciHandler->Address) 630 { 631 Status = AE_ALREADY_EXISTS; 632 goto UnlockAndExit; 633 } 634 635 SciHandler = SciHandler->Next; 636 } 637 638 /* Install the new handler into the global list (at head) */ 639 640 NewSciHandler->Next = AcpiGbl_SciHandlerList; 641 AcpiGbl_SciHandlerList = NewSciHandler; 642 643 644 UnlockAndExit: 645 646 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 647 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 648 649 Exit: 650 if (ACPI_FAILURE (Status)) 651 { 652 ACPI_FREE (NewSciHandler); 653 } 654 return_ACPI_STATUS (Status); 655 } 656 657 ACPI_EXPORT_SYMBOL (AcpiInstallSciHandler) 658 659 660 /******************************************************************************* 661 * 662 * FUNCTION: AcpiRemoveSciHandler 663 * 664 * PARAMETERS: Address - Address of the handler 665 * 666 * RETURN: Status 667 * 668 * DESCRIPTION: Remove a handler for a System Control Interrupt. 669 * 670 ******************************************************************************/ 671 672 ACPI_STATUS 673 AcpiRemoveSciHandler ( 674 ACPI_SCI_HANDLER Address) 675 { 676 ACPI_SCI_HANDLER_INFO *PrevSciHandler; 677 ACPI_SCI_HANDLER_INFO *NextSciHandler; 678 ACPI_CPU_FLAGS Flags; 679 ACPI_STATUS Status; 680 681 682 ACPI_FUNCTION_TRACE (AcpiRemoveSciHandler); 683 684 685 if (!Address) 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 /* Remove the SCI handler with lock */ 697 698 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 699 700 PrevSciHandler = NULL; 701 NextSciHandler = AcpiGbl_SciHandlerList; 702 while (NextSciHandler) 703 { 704 if (NextSciHandler->Address == Address) 705 { 706 /* Unlink and free the SCI handler info block */ 707 708 if (PrevSciHandler) 709 { 710 PrevSciHandler->Next = NextSciHandler->Next; 711 } 712 else 713 { 714 AcpiGbl_SciHandlerList = NextSciHandler->Next; 715 } 716 717 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 718 ACPI_FREE (NextSciHandler); 719 goto UnlockAndExit; 720 } 721 722 PrevSciHandler = NextSciHandler; 723 NextSciHandler = NextSciHandler->Next; 724 } 725 726 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 727 Status = AE_NOT_EXIST; 728 729 730 UnlockAndExit: 731 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 732 return_ACPI_STATUS (Status); 733 } 734 735 ACPI_EXPORT_SYMBOL (AcpiRemoveSciHandler) 736 737 738 /******************************************************************************* 739 * 740 * FUNCTION: AcpiInstallGlobalEventHandler 741 * 742 * PARAMETERS: Handler - Pointer to the global event handler function 743 * Context - Value passed to the handler on each event 744 * 745 * RETURN: Status 746 * 747 * DESCRIPTION: Saves the pointer to the handler function. The global handler 748 * is invoked upon each incoming GPE and Fixed Event. It is 749 * invoked at interrupt level at the time of the event dispatch. 750 * Can be used to update event counters, etc. 751 * 752 ******************************************************************************/ 753 754 ACPI_STATUS 755 AcpiInstallGlobalEventHandler ( 756 ACPI_GBL_EVENT_HANDLER Handler, 757 void *Context) 758 { 759 ACPI_STATUS Status; 760 761 762 ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler); 763 764 765 /* Parameter validation */ 766 767 if (!Handler) 768 { 769 return_ACPI_STATUS (AE_BAD_PARAMETER); 770 } 771 772 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 773 if (ACPI_FAILURE (Status)) 774 { 775 return_ACPI_STATUS (Status); 776 } 777 778 /* Don't allow two handlers. */ 779 780 if (AcpiGbl_GlobalEventHandler) 781 { 782 Status = AE_ALREADY_EXISTS; 783 goto Cleanup; 784 } 785 786 AcpiGbl_GlobalEventHandler = Handler; 787 AcpiGbl_GlobalEventHandlerContext = Context; 788 789 790 Cleanup: 791 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 792 return_ACPI_STATUS (Status); 793 } 794 795 ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler) 796 797 798 /******************************************************************************* 799 * 800 * FUNCTION: AcpiInstallFixedEventHandler 801 * 802 * PARAMETERS: Event - Event type to enable. 803 * Handler - Pointer to the handler function for the 804 * event 805 * Context - Value passed to the handler on each GPE 806 * 807 * RETURN: Status 808 * 809 * DESCRIPTION: Saves the pointer to the handler function and then enables the 810 * event. 811 * 812 ******************************************************************************/ 813 814 ACPI_STATUS 815 AcpiInstallFixedEventHandler ( 816 UINT32 Event, 817 ACPI_EVENT_HANDLER Handler, 818 void *Context) 819 { 820 ACPI_STATUS Status; 821 822 823 ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler); 824 825 826 /* Parameter validation */ 827 828 if (Event > ACPI_EVENT_MAX) 829 { 830 return_ACPI_STATUS (AE_BAD_PARAMETER); 831 } 832 833 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 834 if (ACPI_FAILURE (Status)) 835 { 836 return_ACPI_STATUS (Status); 837 } 838 839 /* Do not allow multiple handlers */ 840 841 if (AcpiGbl_FixedEventHandlers[Event].Handler) 842 { 843 Status = AE_ALREADY_EXISTS; 844 goto Cleanup; 845 } 846 847 /* Install the handler before enabling the event */ 848 849 AcpiGbl_FixedEventHandlers[Event].Handler = Handler; 850 AcpiGbl_FixedEventHandlers[Event].Context = Context; 851 852 Status = AcpiEnableEvent (Event, 0); 853 if (ACPI_FAILURE (Status)) 854 { 855 ACPI_WARNING ((AE_INFO, 856 "Could not enable fixed event - %s (%u)", 857 AcpiUtGetEventName (Event), Event)); 858 859 /* Remove the handler */ 860 861 AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 862 AcpiGbl_FixedEventHandlers[Event].Context = NULL; 863 } 864 else 865 { 866 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 867 "Enabled fixed event %s (%X), Handler=%p\n", 868 AcpiUtGetEventName (Event), Event, Handler)); 869 } 870 871 872 Cleanup: 873 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 874 return_ACPI_STATUS (Status); 875 } 876 877 ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler) 878 879 880 /******************************************************************************* 881 * 882 * FUNCTION: AcpiRemoveFixedEventHandler 883 * 884 * PARAMETERS: Event - Event type to disable. 885 * Handler - Address of the handler 886 * 887 * RETURN: Status 888 * 889 * DESCRIPTION: Disables the event and unregisters the event handler. 890 * 891 ******************************************************************************/ 892 893 ACPI_STATUS 894 AcpiRemoveFixedEventHandler ( 895 UINT32 Event, 896 ACPI_EVENT_HANDLER Handler) 897 { 898 ACPI_STATUS Status = AE_OK; 899 900 901 ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler); 902 903 904 /* Parameter validation */ 905 906 if (Event > ACPI_EVENT_MAX) 907 { 908 return_ACPI_STATUS (AE_BAD_PARAMETER); 909 } 910 911 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 912 if (ACPI_FAILURE (Status)) 913 { 914 return_ACPI_STATUS (Status); 915 } 916 917 /* Disable the event before removing the handler */ 918 919 Status = AcpiDisableEvent (Event, 0); 920 921 /* Always Remove the handler */ 922 923 AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 924 AcpiGbl_FixedEventHandlers[Event].Context = NULL; 925 926 if (ACPI_FAILURE (Status)) 927 { 928 ACPI_WARNING ((AE_INFO, 929 "Could not disable fixed event - %s (%u)", 930 AcpiUtGetEventName (Event), Event)); 931 } 932 else 933 { 934 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 935 "Disabled fixed event - %s (%X)\n", 936 AcpiUtGetEventName (Event), Event)); 937 } 938 939 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 940 return_ACPI_STATUS (Status); 941 } 942 943 ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler) 944 945 946 /******************************************************************************* 947 * 948 * FUNCTION: AcpiEvInstallGpeHandler 949 * 950 * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 951 * defined GPEs) 952 * GpeNumber - The GPE number within the GPE block 953 * Type - Whether this GPE should be treated as an 954 * edge- or level-triggered interrupt. 955 * IsRawHandler - Whether this GPE should be handled using 956 * the special GPE handler mode. 957 * Address - Address of the handler 958 * Context - Value passed to the handler on each GPE 959 * 960 * RETURN: Status 961 * 962 * DESCRIPTION: Internal function to install a handler for a General Purpose 963 * Event. 964 * 965 ******************************************************************************/ 966 967 static ACPI_STATUS 968 AcpiEvInstallGpeHandler ( 969 ACPI_HANDLE GpeDevice, 970 UINT32 GpeNumber, 971 UINT32 Type, 972 BOOLEAN IsRawHandler, 973 ACPI_GPE_HANDLER Address, 974 void *Context) 975 { 976 ACPI_GPE_EVENT_INFO *GpeEventInfo; 977 ACPI_GPE_HANDLER_INFO *Handler; 978 ACPI_STATUS Status; 979 ACPI_CPU_FLAGS Flags; 980 981 982 ACPI_FUNCTION_TRACE (EvInstallGpeHandler); 983 984 985 /* Parameter validation */ 986 987 if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK)) 988 { 989 return_ACPI_STATUS (AE_BAD_PARAMETER); 990 } 991 992 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 993 if (ACPI_FAILURE (Status)) 994 { 995 return_ACPI_STATUS (Status); 996 } 997 998 /* Allocate and init handler object (before lock) */ 999 1000 Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO)); 1001 if (!Handler) 1002 { 1003 Status = AE_NO_MEMORY; 1004 goto UnlockAndExit; 1005 } 1006 1007 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 1008 1009 /* Ensure that we have a valid GPE number */ 1010 1011 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 1012 if (!GpeEventInfo) 1013 { 1014 Status = AE_BAD_PARAMETER; 1015 goto FreeAndExit; 1016 } 1017 1018 /* Make sure that there isn't a handler there already */ 1019 1020 if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 1021 ACPI_GPE_DISPATCH_HANDLER) || 1022 (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 1023 ACPI_GPE_DISPATCH_RAW_HANDLER)) 1024 { 1025 Status = AE_ALREADY_EXISTS; 1026 goto FreeAndExit; 1027 } 1028 1029 Handler->Address = Address; 1030 Handler->Context = Context; 1031 Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode; 1032 Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags & 1033 (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK)); 1034 1035 /* 1036 * If the GPE is associated with a method, it may have been enabled 1037 * automatically during initialization, in which case it has to be 1038 * disabled now to avoid spurious execution of the handler. 1039 */ 1040 if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == 1041 ACPI_GPE_DISPATCH_METHOD) || 1042 (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == 1043 ACPI_GPE_DISPATCH_NOTIFY)) && 1044 GpeEventInfo->RuntimeCount) 1045 { 1046 Handler->OriginallyEnabled = TRUE; 1047 (void) AcpiEvRemoveGpeReference (GpeEventInfo); 1048 1049 /* Sanity check of original type against new type */ 1050 1051 if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK)) 1052 { 1053 ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)")); 1054 } 1055 } 1056 1057 /* Install the handler */ 1058 1059 GpeEventInfo->Dispatch.Handler = Handler; 1060 1061 /* Setup up dispatch flags to indicate handler (vs. method/notify) */ 1062 1063 GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 1064 GpeEventInfo->Flags |= (UINT8) (Type | (IsRawHandler ? 1065 ACPI_GPE_DISPATCH_RAW_HANDLER : ACPI_GPE_DISPATCH_HANDLER)); 1066 1067 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 1068 1069 1070 UnlockAndExit: 1071 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 1072 return_ACPI_STATUS (Status); 1073 1074 FreeAndExit: 1075 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 1076 ACPI_FREE (Handler); 1077 goto UnlockAndExit; 1078 } 1079 1080 1081 /******************************************************************************* 1082 * 1083 * FUNCTION: AcpiInstallGpeHandler 1084 * 1085 * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 1086 * defined GPEs) 1087 * GpeNumber - The GPE number within the GPE block 1088 * Type - Whether this GPE should be treated as an 1089 * edge- or level-triggered interrupt. 1090 * Address - Address of the handler 1091 * Context - Value passed to the handler on each GPE 1092 * 1093 * RETURN: Status 1094 * 1095 * DESCRIPTION: Install a handler for a General Purpose Event. 1096 * 1097 ******************************************************************************/ 1098 1099 ACPI_STATUS 1100 AcpiInstallGpeHandler ( 1101 ACPI_HANDLE GpeDevice, 1102 UINT32 GpeNumber, 1103 UINT32 Type, 1104 ACPI_GPE_HANDLER Address, 1105 void *Context) 1106 { 1107 ACPI_STATUS Status; 1108 1109 1110 ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler); 1111 1112 1113 Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type, 1114 FALSE, Address, Context); 1115 1116 return_ACPI_STATUS (Status); 1117 } 1118 1119 ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler) 1120 1121 1122 /******************************************************************************* 1123 * 1124 * FUNCTION: AcpiInstallGpeRawHandler 1125 * 1126 * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 1127 * defined GPEs) 1128 * GpeNumber - The GPE number within the GPE block 1129 * Type - Whether this GPE should be treated as an 1130 * edge- or level-triggered interrupt. 1131 * Address - Address of the handler 1132 * Context - Value passed to the handler on each GPE 1133 * 1134 * RETURN: Status 1135 * 1136 * DESCRIPTION: Install a handler for a General Purpose Event. 1137 * 1138 ******************************************************************************/ 1139 1140 ACPI_STATUS 1141 AcpiInstallGpeRawHandler ( 1142 ACPI_HANDLE GpeDevice, 1143 UINT32 GpeNumber, 1144 UINT32 Type, 1145 ACPI_GPE_HANDLER Address, 1146 void *Context) 1147 { 1148 ACPI_STATUS Status; 1149 1150 1151 ACPI_FUNCTION_TRACE (AcpiInstallGpeRawHandler); 1152 1153 1154 Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type, 1155 TRUE, Address, Context); 1156 1157 return_ACPI_STATUS (Status); 1158 } 1159 1160 ACPI_EXPORT_SYMBOL (AcpiInstallGpeRawHandler) 1161 1162 1163 /******************************************************************************* 1164 * 1165 * FUNCTION: AcpiRemoveGpeHandler 1166 * 1167 * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 1168 * defined GPEs) 1169 * GpeNumber - The event to remove a handler 1170 * Address - Address of the handler 1171 * 1172 * RETURN: Status 1173 * 1174 * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent. 1175 * 1176 ******************************************************************************/ 1177 1178 ACPI_STATUS 1179 AcpiRemoveGpeHandler ( 1180 ACPI_HANDLE GpeDevice, 1181 UINT32 GpeNumber, 1182 ACPI_GPE_HANDLER Address) 1183 { 1184 ACPI_GPE_EVENT_INFO *GpeEventInfo; 1185 ACPI_GPE_HANDLER_INFO *Handler; 1186 ACPI_STATUS Status; 1187 ACPI_CPU_FLAGS Flags; 1188 1189 1190 ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler); 1191 1192 1193 /* Parameter validation */ 1194 1195 if (!Address) 1196 { 1197 return_ACPI_STATUS (AE_BAD_PARAMETER); 1198 } 1199 1200 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 1201 if (ACPI_FAILURE (Status)) 1202 { 1203 return_ACPI_STATUS (Status); 1204 } 1205 1206 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 1207 1208 /* Ensure that we have a valid GPE number */ 1209 1210 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 1211 if (!GpeEventInfo) 1212 { 1213 Status = AE_BAD_PARAMETER; 1214 goto UnlockAndExit; 1215 } 1216 1217 /* Make sure that a handler is indeed installed */ 1218 1219 if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) != 1220 ACPI_GPE_DISPATCH_HANDLER) && 1221 (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) != 1222 ACPI_GPE_DISPATCH_RAW_HANDLER)) 1223 { 1224 Status = AE_NOT_EXIST; 1225 goto UnlockAndExit; 1226 } 1227 1228 /* Make sure that the installed handler is the same */ 1229 1230 if (GpeEventInfo->Dispatch.Handler->Address != Address) 1231 { 1232 Status = AE_BAD_PARAMETER; 1233 goto UnlockAndExit; 1234 } 1235 1236 /* Remove the handler */ 1237 1238 Handler = GpeEventInfo->Dispatch.Handler; 1239 GpeEventInfo->Dispatch.Handler = NULL; 1240 1241 /* Restore Method node (if any), set dispatch flags */ 1242 1243 GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode; 1244 GpeEventInfo->Flags &= 1245 ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 1246 GpeEventInfo->Flags |= Handler->OriginalFlags; 1247 1248 /* 1249 * If the GPE was previously associated with a method and it was 1250 * enabled, it should be enabled at this point to restore the 1251 * post-initialization configuration. 1252 */ 1253 if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == 1254 ACPI_GPE_DISPATCH_METHOD) || 1255 (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == 1256 ACPI_GPE_DISPATCH_NOTIFY)) && 1257 Handler->OriginallyEnabled) 1258 { 1259 (void) AcpiEvAddGpeReference (GpeEventInfo, FALSE); 1260 if (ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo)) 1261 { 1262 /* Poll edge triggered GPEs to handle existing events */ 1263 1264 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 1265 (void) AcpiEvDetectGpe ( 1266 GpeDevice, GpeEventInfo, GpeNumber); 1267 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 1268 } 1269 } 1270 1271 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 1272 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 1273 1274 /* Make sure all deferred GPE tasks are completed */ 1275 1276 AcpiOsWaitEventsComplete (); 1277 1278 /* Now we can free the handler object */ 1279 1280 ACPI_FREE (Handler); 1281 return_ACPI_STATUS (Status); 1282 1283 UnlockAndExit: 1284 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 1285 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 1286 return_ACPI_STATUS (Status); 1287 } 1288 1289 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler) 1290 1291 1292 /******************************************************************************* 1293 * 1294 * FUNCTION: AcpiAcquireGlobalLock 1295 * 1296 * PARAMETERS: Timeout - How long the caller is willing to wait 1297 * Handle - Where the handle to the lock is returned 1298 * (if acquired) 1299 * 1300 * RETURN: Status 1301 * 1302 * DESCRIPTION: Acquire the ACPI Global Lock 1303 * 1304 * Note: Allows callers with the same thread ID to acquire the global lock 1305 * multiple times. In other words, externally, the behavior of the global lock 1306 * is identical to an AML mutex. On the first acquire, a new handle is 1307 * returned. On any subsequent calls to acquire by the same thread, the same 1308 * handle is returned. 1309 * 1310 ******************************************************************************/ 1311 1312 ACPI_STATUS 1313 AcpiAcquireGlobalLock ( 1314 UINT16 Timeout, 1315 UINT32 *Handle) 1316 { 1317 ACPI_STATUS Status; 1318 1319 1320 if (!Handle) 1321 { 1322 return (AE_BAD_PARAMETER); 1323 } 1324 1325 /* Must lock interpreter to prevent race conditions */ 1326 1327 AcpiExEnterInterpreter (); 1328 1329 Status = AcpiExAcquireMutexObject (Timeout, 1330 AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ()); 1331 1332 if (ACPI_SUCCESS (Status)) 1333 { 1334 /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */ 1335 1336 *Handle = AcpiGbl_GlobalLockHandle; 1337 } 1338 1339 AcpiExExitInterpreter (); 1340 return (Status); 1341 } 1342 1343 ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock) 1344 1345 1346 /******************************************************************************* 1347 * 1348 * FUNCTION: AcpiReleaseGlobalLock 1349 * 1350 * PARAMETERS: Handle - Returned from AcpiAcquireGlobalLock 1351 * 1352 * RETURN: Status 1353 * 1354 * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid. 1355 * 1356 ******************************************************************************/ 1357 1358 ACPI_STATUS 1359 AcpiReleaseGlobalLock ( 1360 UINT32 Handle) 1361 { 1362 ACPI_STATUS Status; 1363 1364 1365 if (!Handle || (Handle != AcpiGbl_GlobalLockHandle)) 1366 { 1367 return (AE_NOT_ACQUIRED); 1368 } 1369 1370 Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex); 1371 return (Status); 1372 } 1373 1374 ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock) 1375 1376 #endif /* !ACPI_REDUCED_HARDWARE */ 1377