evxface.c revision 151937
1289694Sngie/****************************************************************************** 2289694Sngie * 3289694Sngie * Module Name: evxface - External interfaces for ACPI events 4289694Sngie * $Revision: 1.152 $ 5289694Sngie * 6289694Sngie *****************************************************************************/ 7289694Sngie 8289694Sngie/****************************************************************************** 9289694Sngie * 10289694Sngie * 1. Copyright Notice 11289694Sngie * 12289694Sngie * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp. 13289694Sngie * All rights reserved. 14289694Sngie * 15289694Sngie * 2. License 16289694Sngie * 17289694Sngie * 2.1. This is your license from Intel Corp. under its intellectual property 18289694Sngie * rights. You may have additional license terms from the party that provided 19289694Sngie * you this software, covering your right to use that party's intellectual 20289694Sngie * property rights. 21289694Sngie * 22289694Sngie * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23289694Sngie * copy of the source code appearing in this file ("Covered Code") an 24289694Sngie * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25289694Sngie * base code distributed originally by Intel ("Original Intel Code") to copy, 26289694Sngie * make derivatives, distribute, use and display any portion of the Covered 27289694Sngie * Code in any form, with the right to sublicense such rights; and 28289694Sngie * 29289694Sngie * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30290586Sngie * license (with the right to sublicense), under only those claims of Intel 31290586Sngie * patents that are infringed by the Original Intel Code, to make, use, sell, 32290586Sngie * offer to sell, and import the Covered Code and derivative works thereof 33290586Sngie * solely to the minimum extent necessary to exercise the above copyright 34290586Sngie * license, and in no event shall the patent license extend to any additions 35290586Sngie * to or modifications of the Original Intel Code. No other license or right 36290586Sngie * is granted directly or by implication, estoppel or otherwise; 37289694Sngie * 38289694Sngie * The above copyright and patent license is granted only if the following 39290586Sngie * conditions are met: 40289694Sngie * 41290586Sngie * 3. Conditions 42290586Sngie * 43290586Sngie * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44289694Sngie * Redistribution of source code of any substantial prton of the Covered 45290586Sngie * Code or modification with rights to further distribute source must include 46290586Sngie * the above Copyright Notice, the above License, this list of Conditions, 47290586Sngie * and the following Disclaimer and Export Compliance provision. In addition, 48290586Sngie * Licensee must cause all Covered Code to which Licensee contributes to 49290586Sngie * contain a file documenting the changes Licensee made to create that Covered 50290586Sngie * Code and the date of any change. Licensee must include in that file the 51290586Sngie * documentation of any changes made by any predecessor Licensee. Licensee 52290586Sngie * must include a prominent statement that the modification is derived, 53290586Sngie * directly or indirectly, from Original Intel Code. 54290586Sngie * 55290586Sngie * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56290586Sngie * Redistribution of source code of any substantial portion of the Covered 57290586Sngie * Code or modification without rights to further distribute source must 58290586Sngie * include the following Disclaimer and Export Compliance provision in the 59290586Sngie * documentation and/or other materials provided with distribution. In 60290586Sngie * addition, Licensee may not authorize further sublicense of source of any 61290586Sngie * portion of the Covered Code, and must include terms to the effect that the 62290586Sngie * license from Licensee to its licensee is limited to the intellectual 63290586Sngie * property embodied in the software Licensee provides to its licensee, and 64290586Sngie * not to intellectual property embodied in modifications its licensee may 65290586Sngie * make. 66290586Sngie * 67290586Sngie * 3.3. Redistribution of Executable. Redistribution in executable form of any 68290586Sngie * substantial portion of the Covered Code or modification must reproduce the 69289694Sngie * above Copyright Notice, and the following Disclaimer and Export Compliance 70289694Sngie * provision in the documentation and/or other materials provided with the 71290586Sngie * distribution. 72290586Sngie * 73290586Sngie * 3.4. Intel retains all right, title, and interest in and to the Original 74290586Sngie * Intel Code. 75290586Sngie * 76289694Sngie * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77290586Sngie * Intel shall be used in advertising or otherwise to promote the sale, use or 78290586Sngie * other dealings in products derived from or relating to the Covered Code 79290586Sngie * without prior written authorization from Intel. 80290586Sngie * 81290586Sngie * 4. Disclaimer and Export Compliance 82290586Sngie * 83290586Sngie * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84290586Sngie * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85290586Sngie * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86290586Sngie * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87290586Sngie * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88290586Sngie * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89290586Sngie * PARTICULAR PURPOSE. 90290586Sngie * 91290586Sngie * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92290586Sngie * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93290586Sngie * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94290586Sngie * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95290586Sngie * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96290586Sngie * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97290586Sngie * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98290586Sngie * LIMITED REMEDY. 99290586Sngie * 100290586Sngie * 4.3. Licensee shall not export, either directly or indirectly, any of this 101290586Sngie * software or system incorporating such software without first obtaining any 102290586Sngie * required license or other approval from the U. S. Department of Commerce or 103290586Sngie * any other agency or department of the United States Government. In the 104290586Sngie * event Licensee exports any such software from the United States or 105290586Sngie * re-exports any such software from a foreign destination, Licensee shall 106290586Sngie * ensure that the distribution and export/re-export of the software is in 107290586Sngie * compliance with all laws, regulations, orders, or other restrictions of the 108290586Sngie * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109290586Sngie * any of its subsidiaries will export/re-export any technical data, process, 110290586Sngie * software, or service, directly or indirectly, to any country for which the 111290586Sngie * United States government or any agency thereof requires an export license, 112290586Sngie * other governmental approval, or letter of assurance, without first obtaining 113290586Sngie * such license, approval or letter. 114290586Sngie * 115290586Sngie *****************************************************************************/ 116290594Sngie 117290586Sngie 118290586Sngie#define __EVXFACE_C__ 119290586Sngie 120290586Sngie#include <contrib/dev/acpica/acpi.h> 121290586Sngie#include <contrib/dev/acpica/acnamesp.h> 122290586Sngie#include <contrib/dev/acpica/acevents.h> 123290586Sngie#include <contrib/dev/acpica/acinterp.h> 124290586Sngie 125290586Sngie#define _COMPONENT ACPI_EVENTS 126290586Sngie ACPI_MODULE_NAME ("evxface") 127290586Sngie 128290586Sngie 129290586Sngie/******************************************************************************* 130290586Sngie * 131290586Sngie * FUNCTION: AcpiInstallExceptionHandler 132290586Sngie * 133290586Sngie * PARAMETERS: Handler - Pointer to the handler function for the 134290586Sngie * event 135290586Sngie * 136290586Sngie * RETURN: Status 137290586Sngie * 138290586Sngie * DESCRIPTION: Saves the pointer to the handler function 139290586Sngie * 140290586Sngie ******************************************************************************/ 141290586Sngie 142290586SngieACPI_STATUS 143290586SngieAcpiInstallExceptionHandler ( 144290586Sngie ACPI_EXCEPTION_HANDLER Handler) 145290586Sngie{ 146290586Sngie ACPI_STATUS Status; 147290586Sngie 148290586Sngie 149290586Sngie ACPI_FUNCTION_TRACE ("AcpiInstallExceptionHandler"); 150290586Sngie 151290586Sngie 152290586Sngie Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 153290586Sngie if (ACPI_FAILURE (Status)) 154290586Sngie { 155290586Sngie return_ACPI_STATUS (Status); 156290586Sngie } 157290586Sngie 158289694Sngie /* Don't allow two handlers. */ 159290586Sngie 160290586Sngie if (AcpiGbl_ExceptionHandler) 161290586Sngie { 162290586Sngie Status = AE_ALREADY_EXISTS; 163290586Sngie goto Cleanup; 164290586Sngie } 165290586Sngie 166290586Sngie /* Install the handler */ 167290586Sngie 168290586Sngie AcpiGbl_ExceptionHandler = Handler; 169290586Sngie 170290586SngieCleanup: 171290586Sngie (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 172290586Sngie return_ACPI_STATUS (Status); 173290586Sngie} 174289694Sngie 175290586Sngie 176290586Sngie/******************************************************************************* 177290586Sngie * 178290586Sngie * FUNCTION: AcpiInstallFixedEventHandler 179290586Sngie * 180290586Sngie * PARAMETERS: Event - Event type to enable. 181290586Sngie * Handler - Pointer to the handler function for the 182289694Sngie * event 183290586Sngie * Context - Value passed to the handler on each GPE 184289694Sngie * 185290586Sngie * RETURN: Status 186290586Sngie * 187289694Sngie * DESCRIPTION: Saves the pointer to the handler function and then enables the 188290586Sngie * event. 189290586Sngie * 190290586Sngie ******************************************************************************/ 191290586Sngie 192289694SngieACPI_STATUS 193290586SngieAcpiInstallFixedEventHandler ( 194290586Sngie UINT32 Event, 195290586Sngie ACPI_EVENT_HANDLER Handler, 196290586Sngie void *Context) 197290586Sngie{ 198290586Sngie ACPI_STATUS Status; 199290586Sngie 200290586Sngie 201290586Sngie ACPI_FUNCTION_TRACE ("AcpiInstallFixedEventHandler"); 202290586Sngie 203290586Sngie 204290586Sngie /* Parameter validation */ 205289694Sngie 206290586Sngie if (Event > ACPI_EVENT_MAX) 207290586Sngie { 208290586Sngie return_ACPI_STATUS (AE_BAD_PARAMETER); 209290586Sngie } 210289694Sngie 211290594Sngie Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 212290594Sngie if (ACPI_FAILURE (Status)) 213290594Sngie { 214290594Sngie return_ACPI_STATUS (Status); 215290594Sngie } 216290594Sngie 217290594Sngie /* Don't allow two handlers. */ 218290594Sngie 219290594Sngie if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler) 220290594Sngie { 221290594Sngie Status = AE_ALREADY_EXISTS; 222290594Sngie goto Cleanup; 223290594Sngie } 224290594Sngie 225290594Sngie /* Install the handler before enabling the event */ 226290594Sngie 227290594Sngie AcpiGbl_FixedEventHandlers[Event].Handler = Handler; 228290594Sngie AcpiGbl_FixedEventHandlers[Event].Context = Context; 229290594Sngie 230290594Sngie Status = AcpiEnableEvent (Event, 0); 231290594Sngie if (ACPI_FAILURE (Status)) 232290594Sngie { 233290594Sngie ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n")); 234290594Sngie 235290594Sngie /* Remove the handler */ 236290594Sngie 237290594Sngie AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 238290594Sngie AcpiGbl_FixedEventHandlers[Event].Context = NULL; 239290594Sngie } 240290594Sngie else 241290594Sngie { 242290594Sngie ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 243290594Sngie "Enabled fixed event %X, Handler=%p\n", Event, Handler)); 244290594Sngie } 245290594Sngie 246290594Sngie 247290594SngieCleanup: 248290594Sngie (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 249290594Sngie return_ACPI_STATUS (Status); 250290594Sngie} 251290594Sngie 252290594Sngie 253290594Sngie/******************************************************************************* 254290594Sngie * 255290594Sngie * FUNCTION: AcpiRemoveFixedEventHandler 256290594Sngie * 257290594Sngie * PARAMETERS: Event - Event type to disable. 258290594Sngie * Handler - Address of the handler 259290594Sngie * 260290594Sngie * RETURN: Status 261290594Sngie * 262290594Sngie * DESCRIPTION: Disables the event and unregisters the event handler. 263290594Sngie * 264290594Sngie ******************************************************************************/ 265290594Sngie 266290586SngieACPI_STATUS 267290586SngieAcpiRemoveFixedEventHandler ( 268290586Sngie UINT32 Event, 269290586Sngie ACPI_EVENT_HANDLER Handler) 270290586Sngie{ 271290586Sngie ACPI_STATUS Status = AE_OK; 272290586Sngie 273290586Sngie 274290586Sngie ACPI_FUNCTION_TRACE ("AcpiRemoveFixedEventHandler"); 275290586Sngie 276290586Sngie 277290586Sngie /* Parameter validation */ 278290586Sngie 279290586Sngie if (Event > ACPI_EVENT_MAX) 280290586Sngie { 281290586Sngie return_ACPI_STATUS (AE_BAD_PARAMETER); 282290586Sngie } 283290586Sngie 284290586Sngie Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 285290586Sngie if (ACPI_FAILURE (Status)) 286290586Sngie { 287290586Sngie return_ACPI_STATUS (Status); 288290586Sngie } 289290586Sngie 290290586Sngie /* Disable the event before removing the handler */ 291290586Sngie 292290586Sngie Status = AcpiDisableEvent (Event, 0); 293290586Sngie 294290586Sngie /* Always Remove the handler */ 295290586Sngie 296290586Sngie AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 297290586Sngie AcpiGbl_FixedEventHandlers[Event].Context = NULL; 298290586Sngie 299290586Sngie if (ACPI_FAILURE (Status)) 300290586Sngie { 301290586Sngie ACPI_DEBUG_PRINT ((ACPI_DB_WARN, 302290586Sngie "Could not write to fixed event enable register.\n")); 303290586Sngie } 304290586Sngie else 305290586Sngie { 306290586Sngie ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X.\n", Event)); 307290586Sngie } 308290586Sngie 309290586Sngie (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 310290586Sngie return_ACPI_STATUS (Status); 311290586Sngie} 312290586Sngie 313290586Sngie 314290586Sngie/******************************************************************************* 315290586Sngie * 316290586Sngie * FUNCTION: AcpiInstallNotifyHandler 317290586Sngie * 318290586Sngie * PARAMETERS: Device - The device for which notifies will be handled 319290586Sngie * HandlerType - The type of handler: 320290586Sngie * ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f) 321290586Sngie * ACPI_DEVICE_NOTIFY: DriverHandler (80-ff) 322290586Sngie * ACPI_ALL_NOTIFY: both system and device 323290586Sngie * Handler - Address of the handler 324290586Sngie * Context - Value passed to the handler on each GPE 325290586Sngie * 326290586Sngie * RETURN: Status 327290586Sngie * 328290586Sngie * DESCRIPTION: Install a handler for notifies on an ACPI device 329290592Sngie * 330290592Sngie ******************************************************************************/ 331290592Sngie 332290592SngieACPI_STATUS 333290592SngieAcpiInstallNotifyHandler ( 334290592Sngie ACPI_HANDLE Device, 335290592Sngie UINT32 HandlerType, 336290592Sngie ACPI_NOTIFY_HANDLER Handler, 337290592Sngie void *Context) 338290592Sngie{ 339290592Sngie ACPI_OPERAND_OBJECT *ObjDesc; 340290592Sngie ACPI_OPERAND_OBJECT *NotifyObj; 341290592Sngie ACPI_NAMESPACE_NODE *Node; 342290592Sngie ACPI_STATUS Status; 343290592Sngie 344290592Sngie 345290592Sngie ACPI_FUNCTION_TRACE ("AcpiInstallNotifyHandler"); 346290592Sngie 347290592Sngie 348290592Sngie /* Parameter validation */ 349290592Sngie 350290592Sngie if ((!Device) || 351290592Sngie (!Handler) || 352290592Sngie (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 353290592Sngie { 354290592Sngie return_ACPI_STATUS (AE_BAD_PARAMETER); 355289694Sngie } 356289694Sngie 357290586Sngie Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 358290586Sngie if (ACPI_FAILURE (Status)) 359289694Sngie { 360290586Sngie return_ACPI_STATUS (Status); 361290586Sngie } 362290586Sngie 363290586Sngie /* Convert and validate the device handle */ 364290586Sngie 365290586Sngie Node = AcpiNsMapHandleToNode (Device); 366290594Sngie if (!Node) 367290594Sngie { 368290594Sngie Status = AE_BAD_PARAMETER; 369290586Sngie goto UnlockAndExit; 370290586Sngie } 371290586Sngie 372290592Sngie /* 373289694Sngie * Root Object: 374 * Registering a notify handler on the root object indicates that the 375 * caller wishes to receive notifications for all objects. Note that 376 * only one <external> global handler can be regsitered (per notify type). 377 */ 378 if (Device == ACPI_ROOT_OBJECT) 379 { 380 /* Make sure the handler is not already installed */ 381 382 if (((HandlerType & ACPI_SYSTEM_NOTIFY) && 383 AcpiGbl_SystemNotify.Handler) || 384 ((HandlerType & ACPI_DEVICE_NOTIFY) && 385 AcpiGbl_DeviceNotify.Handler)) 386 { 387 Status = AE_ALREADY_EXISTS; 388 goto UnlockAndExit; 389 } 390 391 if (HandlerType & ACPI_SYSTEM_NOTIFY) 392 { 393 AcpiGbl_SystemNotify.Node = Node; 394 AcpiGbl_SystemNotify.Handler = Handler; 395 AcpiGbl_SystemNotify.Context = Context; 396 } 397 398 if (HandlerType & ACPI_DEVICE_NOTIFY) 399 { 400 AcpiGbl_DeviceNotify.Node = Node; 401 AcpiGbl_DeviceNotify.Handler = Handler; 402 AcpiGbl_DeviceNotify.Context = Context; 403 } 404 405 /* Global notify handler installed */ 406 } 407 408 /* 409 * All Other Objects: 410 * Caller will only receive notifications specific to the target object. 411 * Note that only certain object types can receive notifications. 412 */ 413 else 414 { 415 /* Notifies allowed on this object? */ 416 417 if (!AcpiEvIsNotifyObject (Node)) 418 { 419 Status = AE_TYPE; 420 goto UnlockAndExit; 421 } 422 423 /* Check for an existing internal object */ 424 425 ObjDesc = AcpiNsGetAttachedObject (Node); 426 if (ObjDesc) 427 { 428 /* Object exists - make sure there's no handler */ 429 430 if (((HandlerType & ACPI_SYSTEM_NOTIFY) && 431 ObjDesc->CommonNotify.SystemNotify) || 432 ((HandlerType & ACPI_DEVICE_NOTIFY) && 433 ObjDesc->CommonNotify.DeviceNotify)) 434 { 435 Status = AE_ALREADY_EXISTS; 436 goto UnlockAndExit; 437 } 438 } 439 else 440 { 441 /* Create a new object */ 442 443 ObjDesc = AcpiUtCreateInternalObject (Node->Type); 444 if (!ObjDesc) 445 { 446 Status = AE_NO_MEMORY; 447 goto UnlockAndExit; 448 } 449 450 /* Attach new object to the Node */ 451 452 Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type); 453 454 /* Remove local reference to the object */ 455 456 AcpiUtRemoveReference (ObjDesc); 457 if (ACPI_FAILURE (Status)) 458 { 459 goto UnlockAndExit; 460 } 461 } 462 463 /* Install the handler */ 464 465 NotifyObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY); 466 if (!NotifyObj) 467 { 468 Status = AE_NO_MEMORY; 469 goto UnlockAndExit; 470 } 471 472 NotifyObj->Notify.Node = Node; 473 NotifyObj->Notify.Handler = Handler; 474 NotifyObj->Notify.Context = Context; 475 476 if (HandlerType & ACPI_SYSTEM_NOTIFY) 477 { 478 ObjDesc->CommonNotify.SystemNotify = NotifyObj; 479 } 480 481 if (HandlerType & ACPI_DEVICE_NOTIFY) 482 { 483 ObjDesc->CommonNotify.DeviceNotify = NotifyObj; 484 } 485 486 if (HandlerType == ACPI_ALL_NOTIFY) 487 { 488 /* Extra ref if installed in both */ 489 490 AcpiUtAddReference (NotifyObj); 491 } 492 } 493 494 495UnlockAndExit: 496 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 497 return_ACPI_STATUS (Status); 498} 499 500 501/******************************************************************************* 502 * 503 * FUNCTION: AcpiRemoveNotifyHandler 504 * 505 * PARAMETERS: Device - The device for which notifies will be handled 506 * HandlerType - The type of handler: 507 * ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f) 508 * ACPI_DEVICE_NOTIFY: DriverHandler (80-ff) 509 * ACPI_ALL_NOTIFY: both system and device 510 * Handler - Address of the handler 511 * 512 * RETURN: Status 513 * 514 * DESCRIPTION: Remove a handler for notifies on an ACPI device 515 * 516 ******************************************************************************/ 517 518ACPI_STATUS 519AcpiRemoveNotifyHandler ( 520 ACPI_HANDLE Device, 521 UINT32 HandlerType, 522 ACPI_NOTIFY_HANDLER Handler) 523{ 524 ACPI_OPERAND_OBJECT *NotifyObj; 525 ACPI_OPERAND_OBJECT *ObjDesc; 526 ACPI_NAMESPACE_NODE *Node; 527 ACPI_STATUS Status; 528 529 530 ACPI_FUNCTION_TRACE ("AcpiRemoveNotifyHandler"); 531 532 533 /* Parameter validation */ 534 535 if ((!Device) || 536 (!Handler) || 537 (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 538 { 539 return_ACPI_STATUS (AE_BAD_PARAMETER); 540 } 541 542 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 543 if (ACPI_FAILURE (Status)) 544 { 545 return_ACPI_STATUS (Status); 546 } 547 548 /* Convert and validate the device handle */ 549 550 Node = AcpiNsMapHandleToNode (Device); 551 if (!Node) 552 { 553 Status = AE_BAD_PARAMETER; 554 goto UnlockAndExit; 555 } 556 557 /* Root Object */ 558 559 if (Device == ACPI_ROOT_OBJECT) 560 { 561 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 562 "Removing notify handler for 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 645UnlockAndExit: 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 669ACPI_STATUS 670AcpiInstallGpeHandler ( 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_NATIVE_UINT 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 750UnlockAndExit: 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 771ACPI_STATUS 772AcpiRemoveGpeHandler ( 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_NATIVE_UINT 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 852UnlockAndExit: 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 872ACPI_STATUS 873AcpiAcquireGlobalLock ( 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 916ACPI_STATUS 917AcpiReleaseGlobalLock ( 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