evxface.c revision 216471
1469Ssjiang/****************************************************************************** 211884Sykantser * 3469Ssjiang * Module Name: evxface - External interfaces for ACPI events 4469Ssjiang * 5469Ssjiang *****************************************************************************/ 6469Ssjiang 7469Ssjiang/****************************************************************************** 8469Ssjiang * 9469Ssjiang * 1. Copyright Notice 10469Ssjiang * 11469Ssjiang * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. 12469Ssjiang * All rights reserved. 13469Ssjiang * 14469Ssjiang * 2. License 15469Ssjiang * 16469Ssjiang * 2.1. This is your license from Intel Corp. under its intellectual property 17469Ssjiang * rights. You may have additional license terms from the party that provided 18469Ssjiang * you this software, covering your right to use that party's intellectual 192362Sohair * property rights. 202362Sohair * 212362Sohair * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22469Ssjiang * copy of the source code appearing in this file ("Covered Code") an 23469Ssjiang * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24469Ssjiang * base code distributed originally by Intel ("Original Intel Code") to copy, 25469Ssjiang * make derivatives, distribute, use and display any portion of the Covered 26469Ssjiang * Code in any form, with the right to sublicense such rights; and 27469Ssjiang * 28469Ssjiang * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29469Ssjiang * license (with the right to sublicense), under only those claims of Intel 30469Ssjiang * patents that are infringed by the Original Intel Code, to make, use, sell, 31469Ssjiang * offer to sell, and import the Covered Code and derivative works thereof 32469Ssjiang * solely to the minimum extent necessary to exercise the above copyright 33469Ssjiang * license, and in no event shall the patent license extend to any additions 34469Ssjiang * to or modifications of the Original Intel Code. No other license or right 35469Ssjiang * is granted directly or by implication, estoppel or otherwise; 36469Ssjiang * 37469Ssjiang * The above copyright and patent license is granted only if the following 38469Ssjiang * conditions are met: 39469Ssjiang * 40469Ssjiang * 3. Conditions 41469Ssjiang * 42469Ssjiang * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43469Ssjiang * Redistribution of source code of any substantial portion of the Covered 44469Ssjiang * Code or modification with rights to further distribute source must include 45469Ssjiang * the above Copyright Notice, the above License, this list of Conditions, 46469Ssjiang * and the following Disclaimer and Export Compliance provision. In addition, 47469Ssjiang * Licensee must cause all Covered Code to which Licensee contributes to 48469Ssjiang * contain a file documenting the changes Licensee made to create that Covered 49469Ssjiang * Code and the date of any change. Licensee must include in that file the 50469Ssjiang * documentation of any changes made by any predecessor Licensee. Licensee 51469Ssjiang * must include a prominent statement that the modification is derived, 52469Ssjiang * directly or indirectly, from Original Intel Code. 53469Ssjiang * 54469Ssjiang * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55469Ssjiang * Redistribution of source code of any substantial portion of the Covered 56469Ssjiang * Code or modification without rights to further distribute source must 57469Ssjiang * include the following Disclaimer and Export Compliance provision in the 58469Ssjiang * documentation and/or other materials provided with distribution. In 59469Ssjiang * addition, Licensee may not authorize further sublicense of source of any 60469Ssjiang * portion of the Covered Code, and must include terms to the effect that the 61469Ssjiang * license from Licensee to its licensee is limited to the intellectual 62469Ssjiang * property embodied in the software Licensee provides to its licensee, and 63469Ssjiang * not to intellectual property embodied in modifications its licensee may 64469Ssjiang * make. 65469Ssjiang * 66469Ssjiang * 3.3. Redistribution of Executable. Redistribution in executable form of any 67469Ssjiang * substantial portion of the Covered Code or modification must reproduce the 68469Ssjiang * above Copyright Notice, and the following Disclaimer and Export Compliance 69469Ssjiang * provision in the documentation and/or other materials provided with the 70469Ssjiang * distribution. 71469Ssjiang * 72469Ssjiang * 3.4. Intel retains all right, title, and interest in and to the Original 73469Ssjiang * Intel Code. 74469Ssjiang * 75469Ssjiang * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76469Ssjiang * Intel shall be used in advertising or otherwise to promote the sale, use or 77469Ssjiang * other dealings in products derived from or relating to the Covered Code 78469Ssjiang * without prior written authorization from Intel. 79469Ssjiang * 80469Ssjiang * 4. Disclaimer and Export Compliance 81469Ssjiang * 82469Ssjiang * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83469Ssjiang * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84469Ssjiang * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85469Ssjiang * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86469Ssjiang * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87469Ssjiang * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88469Ssjiang * PARTICULAR PURPOSE. 89469Ssjiang * 90469Ssjiang * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91469Ssjiang * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92469Ssjiang * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93469Ssjiang * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94469Ssjiang * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95469Ssjiang * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96469Ssjiang * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97469Ssjiang * LIMITED REMEDY. 98469Ssjiang * 99469Ssjiang * 4.3. Licensee shall not export, either directly or indirectly, any of this 10016613Sdfuchs * software or system incorporating such software without first obtaining any 101469Ssjiang * required license or other approval from the U. S. Department of Commerce or 102469Ssjiang * any other agency or department of the United States Government. In the 103469Ssjiang * event Licensee exports any such software from the United States or 104469Ssjiang * re-exports any such software from a foreign destination, Licensee shall 105469Ssjiang * ensure that the distribution and export/re-export of the software is in 106469Ssjiang * compliance with all laws, regulations, orders, or other restrictions of the 107469Ssjiang * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108469Ssjiang * any of its subsidiaries will export/re-export any technical data, process, 109469Ssjiang * software, or service, directly or indirectly, to any country for which the 110469Ssjiang * United States government or any agency thereof requires an export license, 111469Ssjiang * other governmental approval, or letter of assurance, without first obtaining 112469Ssjiang * such license, approval or letter. 113469Ssjiang * 114469Ssjiang *****************************************************************************/ 115469Ssjiang 116469Ssjiang 117469Ssjiang#define __EVXFACE_C__ 118469Ssjiang 119469Ssjiang#include <contrib/dev/acpica/include/acpi.h> 120469Ssjiang#include <contrib/dev/acpica/include/accommon.h> 121469Ssjiang#include <contrib/dev/acpica/include/acnamesp.h> 122469Ssjiang#include <contrib/dev/acpica/include/acevents.h> 123469Ssjiang#include <contrib/dev/acpica/include/acinterp.h> 124469Ssjiang 125469Ssjiang#define _COMPONENT ACPI_EVENTS 126469Ssjiang ACPI_MODULE_NAME ("evxface") 127469Ssjiang 128469Ssjiang 129469Ssjiang/******************************************************************************* 130469Ssjiang * 131469Ssjiang * FUNCTION: AcpiInstallExceptionHandler 132469Ssjiang * 133469Ssjiang * PARAMETERS: Handler - Pointer to the handler function for the 134469Ssjiang * event 135469Ssjiang * 136469Ssjiang * RETURN: Status 137469Ssjiang * 138469Ssjiang * DESCRIPTION: Saves the pointer to the handler function 139469Ssjiang * 140469Ssjiang ******************************************************************************/ 141469Ssjiang 142469SsjiangACPI_STATUS 143469SsjiangAcpiInstallExceptionHandler ( 144469Ssjiang ACPI_EXCEPTION_HANDLER Handler) 145469Ssjiang{ 146469Ssjiang ACPI_STATUS Status; 147469Ssjiang 148469Ssjiang 149469Ssjiang ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler); 150469Ssjiang 151469Ssjiang 152469Ssjiang Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 153469Ssjiang if (ACPI_FAILURE (Status)) 154469Ssjiang { 155469Ssjiang return_ACPI_STATUS (Status); 156469Ssjiang } 157469Ssjiang 158469Ssjiang /* Don't allow two handlers. */ 159469Ssjiang 160469Ssjiang if (AcpiGbl_ExceptionHandler) 161469Ssjiang { 162469Ssjiang Status = AE_ALREADY_EXISTS; 163469Ssjiang goto Cleanup; 164469Ssjiang } 165469Ssjiang 166469Ssjiang /* Install the handler */ 167469Ssjiang 168469Ssjiang AcpiGbl_ExceptionHandler = Handler; 169469Ssjiang 170469SsjiangCleanup: 171469Ssjiang (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 172469Ssjiang return_ACPI_STATUS (Status); 173469Ssjiang} 174469Ssjiang 175469SsjiangACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler) 176469Ssjiang 177469Ssjiang 178469Ssjiang/******************************************************************************* 179469Ssjiang * 180469Ssjiang * FUNCTION: AcpiInstallGlobalEventHandler 181469Ssjiang * 182469Ssjiang * PARAMETERS: Handler - Pointer to the global event handler function 183469Ssjiang * Context - Value passed to the handler on each event 184469Ssjiang * 185469Ssjiang * RETURN: Status 186469Ssjiang * 187469Ssjiang * DESCRIPTION: Saves the pointer to the handler function. The global handler 188469Ssjiang * is invoked upon each incoming GPE and Fixed Event. It is 189469Ssjiang * invoked at interrupt level at the time of the event dispatch. 190469Ssjiang * Can be used to update event counters, etc. 191469Ssjiang * 192469Ssjiang ******************************************************************************/ 193469Ssjiang 194469SsjiangACPI_STATUS 195469SsjiangAcpiInstallGlobalEventHandler ( 196469Ssjiang ACPI_GBL_EVENT_HANDLER Handler, 197469Ssjiang void *Context) 198469Ssjiang{ 199469Ssjiang ACPI_STATUS Status; 200469Ssjiang 201469Ssjiang 202469Ssjiang ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler); 203469Ssjiang 204469Ssjiang 205469Ssjiang /* Parameter validation */ 206469Ssjiang 207469Ssjiang if (!Handler) 208469Ssjiang { 209469Ssjiang return_ACPI_STATUS (AE_BAD_PARAMETER); 210469Ssjiang } 211469Ssjiang 212469Ssjiang Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 213469Ssjiang if (ACPI_FAILURE (Status)) 214469Ssjiang { 215469Ssjiang return_ACPI_STATUS (Status); 216469Ssjiang } 217469Ssjiang 218469Ssjiang /* Don't allow two handlers. */ 219469Ssjiang 220469Ssjiang if (AcpiGbl_GlobalEventHandler) 221469Ssjiang { 222469Ssjiang Status = AE_ALREADY_EXISTS; 223469Ssjiang goto Cleanup; 224469Ssjiang } 225469Ssjiang 226469Ssjiang AcpiGbl_GlobalEventHandler = Handler; 227469Ssjiang AcpiGbl_GlobalEventHandlerContext = Context; 228469Ssjiang 229469Ssjiang 230469SsjiangCleanup: 231469Ssjiang (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 232469Ssjiang return_ACPI_STATUS (Status); 233469Ssjiang} 234469Ssjiang 235469SsjiangACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler) 236469Ssjiang 237469Ssjiang 238469Ssjiang/******************************************************************************* 239469Ssjiang * 240469Ssjiang * FUNCTION: AcpiInstallFixedEventHandler 241469Ssjiang * 242469Ssjiang * PARAMETERS: Event - Event type to enable. 243469Ssjiang * Handler - Pointer to the handler function for the 244469Ssjiang * event 245469Ssjiang * Context - Value passed to the handler on each GPE 246469Ssjiang * 247469Ssjiang * RETURN: Status 248469Ssjiang * 249469Ssjiang * DESCRIPTION: Saves the pointer to the handler function and then enables the 250469Ssjiang * event. 251469Ssjiang * 252469Ssjiang ******************************************************************************/ 253469Ssjiang 254469SsjiangACPI_STATUS 255469SsjiangAcpiInstallFixedEventHandler ( 256469Ssjiang UINT32 Event, 257469Ssjiang ACPI_EVENT_HANDLER Handler, 258469Ssjiang void *Context) 259469Ssjiang{ 260469Ssjiang ACPI_STATUS Status; 261469Ssjiang 262469Ssjiang 263469Ssjiang ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler); 264469Ssjiang 265469Ssjiang 266469Ssjiang /* Parameter validation */ 267469Ssjiang 268469Ssjiang if (Event > ACPI_EVENT_MAX) 269469Ssjiang { 270469Ssjiang return_ACPI_STATUS (AE_BAD_PARAMETER); 271469Ssjiang } 272469Ssjiang 273469Ssjiang Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 274469Ssjiang if (ACPI_FAILURE (Status)) 275469Ssjiang { 276469Ssjiang return_ACPI_STATUS (Status); 277469Ssjiang } 278469Ssjiang 279469Ssjiang /* Don't allow two handlers. */ 280469Ssjiang 281469Ssjiang if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler) 282469Ssjiang { 283469Ssjiang Status = AE_ALREADY_EXISTS; 284469Ssjiang goto Cleanup; 285469Ssjiang } 286469Ssjiang 287469Ssjiang /* Install the handler before enabling the event */ 288469Ssjiang 289469Ssjiang AcpiGbl_FixedEventHandlers[Event].Handler = Handler; 290469Ssjiang AcpiGbl_FixedEventHandlers[Event].Context = Context; 291469Ssjiang 292469Ssjiang Status = AcpiEnableEvent (Event, 0); 293469Ssjiang if (ACPI_FAILURE (Status)) 294469Ssjiang { 295469Ssjiang ACPI_WARNING ((AE_INFO, "Could not enable fixed event 0x%X", Event)); 296469Ssjiang 297469Ssjiang /* Remove the handler */ 298469Ssjiang 299469Ssjiang AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 300469Ssjiang AcpiGbl_FixedEventHandlers[Event].Context = NULL; 301469Ssjiang } 302469Ssjiang else 303469Ssjiang { 304469Ssjiang ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 305469Ssjiang "Enabled fixed event %X, Handler=%p\n", Event, Handler)); 306469Ssjiang } 307469Ssjiang 308469Ssjiang 309469SsjiangCleanup: 310469Ssjiang (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 311469Ssjiang return_ACPI_STATUS (Status); 312469Ssjiang} 313469Ssjiang 314469SsjiangACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler) 315469Ssjiang 316469Ssjiang 317469Ssjiang/******************************************************************************* 318469Ssjiang * 319469Ssjiang * FUNCTION: AcpiRemoveFixedEventHandler 320469Ssjiang * 321469Ssjiang * PARAMETERS: Event - Event type to disable. 322469Ssjiang * Handler - Address of the handler 323469Ssjiang * 324469Ssjiang * RETURN: Status 325469Ssjiang * 326469Ssjiang * DESCRIPTION: Disables the event and unregisters the event handler. 327469Ssjiang * 328469Ssjiang ******************************************************************************/ 329469Ssjiang 330469SsjiangACPI_STATUS 331469SsjiangAcpiRemoveFixedEventHandler ( 332469Ssjiang UINT32 Event, 333469Ssjiang ACPI_EVENT_HANDLER Handler) 334469Ssjiang{ 335469Ssjiang ACPI_STATUS Status = AE_OK; 336469Ssjiang 337469Ssjiang 338469Ssjiang ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler); 339469Ssjiang 340469Ssjiang 341469Ssjiang /* Parameter validation */ 342469Ssjiang 343469Ssjiang if (Event > ACPI_EVENT_MAX) 344469Ssjiang { 345469Ssjiang return_ACPI_STATUS (AE_BAD_PARAMETER); 346469Ssjiang } 347469Ssjiang 348469Ssjiang Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 349469Ssjiang if (ACPI_FAILURE (Status)) 350469Ssjiang { 351469Ssjiang return_ACPI_STATUS (Status); 352469Ssjiang } 353469Ssjiang 354469Ssjiang /* Disable the event before removing the handler */ 355469Ssjiang 356469Ssjiang Status = AcpiDisableEvent (Event, 0); 357469Ssjiang 358469Ssjiang /* Always Remove the handler */ 359469Ssjiang 360469Ssjiang AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 361469Ssjiang AcpiGbl_FixedEventHandlers[Event].Context = NULL; 362469Ssjiang 363469Ssjiang if (ACPI_FAILURE (Status)) 364469Ssjiang { 365469Ssjiang ACPI_WARNING ((AE_INFO, 366469Ssjiang "Could not write to fixed event enable register 0x%X", Event)); 367469Ssjiang } 368469Ssjiang else 369469Ssjiang { 370469Ssjiang ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X\n", Event)); 371469Ssjiang } 372469Ssjiang 373469Ssjiang (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 374469Ssjiang return_ACPI_STATUS (Status); 375469Ssjiang} 376469Ssjiang 377469SsjiangACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler) 378469Ssjiang 379469Ssjiang 380469Ssjiang/******************************************************************************* 381469Ssjiang * 382469Ssjiang * FUNCTION: AcpiInstallNotifyHandler 383469Ssjiang * 384469Ssjiang * PARAMETERS: Device - The device for which notifies will be handled 385469Ssjiang * HandlerType - The type of handler: 386469Ssjiang * ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f) 387469Ssjiang * ACPI_DEVICE_NOTIFY: DriverHandler (80-ff) 388469Ssjiang * ACPI_ALL_NOTIFY: both system and device 389469Ssjiang * Handler - Address of the handler 390469Ssjiang * Context - Value passed to the handler on each GPE 391469Ssjiang * 392469Ssjiang * RETURN: Status 393469Ssjiang * 394469Ssjiang * DESCRIPTION: Install a handler for notifies on an ACPI device 395469Ssjiang * 396469Ssjiang ******************************************************************************/ 397469Ssjiang 398469SsjiangACPI_STATUS 399469SsjiangAcpiInstallNotifyHandler ( 400469Ssjiang ACPI_HANDLE Device, 401469Ssjiang UINT32 HandlerType, 402469Ssjiang ACPI_NOTIFY_HANDLER Handler, 403469Ssjiang void *Context) 404469Ssjiang{ 405469Ssjiang ACPI_OPERAND_OBJECT *ObjDesc; 406469Ssjiang ACPI_OPERAND_OBJECT *NotifyObj; 407469Ssjiang ACPI_NAMESPACE_NODE *Node; 408469Ssjiang ACPI_STATUS Status; 409469Ssjiang 410469Ssjiang 411469Ssjiang ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler); 412469Ssjiang 413469Ssjiang 414469Ssjiang /* Parameter validation */ 415469Ssjiang 416469Ssjiang if ((!Device) || 417469Ssjiang (!Handler) || 418469Ssjiang (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 419469Ssjiang { 420469Ssjiang return_ACPI_STATUS (AE_BAD_PARAMETER); 421469Ssjiang } 422469Ssjiang 423469Ssjiang Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 424469Ssjiang if (ACPI_FAILURE (Status)) 425469Ssjiang { 426469Ssjiang return_ACPI_STATUS (Status); 427469Ssjiang } 428469Ssjiang 429469Ssjiang /* Convert and validate the device handle */ 430469Ssjiang 431469Ssjiang Node = AcpiNsValidateHandle (Device); 432469Ssjiang if (!Node) 433469Ssjiang { 434469Ssjiang Status = AE_BAD_PARAMETER; 435469Ssjiang goto UnlockAndExit; 436469Ssjiang } 437469Ssjiang 438469Ssjiang /* 439469Ssjiang * Root Object: 440469Ssjiang * Registering a notify handler on the root object indicates that the 441469Ssjiang * caller wishes to receive notifications for all objects. Note that 442469Ssjiang * only one <external> global handler can be regsitered (per notify type). 443469Ssjiang */ 444469Ssjiang if (Device == ACPI_ROOT_OBJECT) 445469Ssjiang { 446469Ssjiang /* Make sure the handler is not already installed */ 447469Ssjiang 448469Ssjiang if (((HandlerType & ACPI_SYSTEM_NOTIFY) && 449469Ssjiang AcpiGbl_SystemNotify.Handler) || 450469Ssjiang ((HandlerType & ACPI_DEVICE_NOTIFY) && 451469Ssjiang AcpiGbl_DeviceNotify.Handler)) 452469Ssjiang { 453469Ssjiang Status = AE_ALREADY_EXISTS; 454469Ssjiang goto UnlockAndExit; 455469Ssjiang } 456469Ssjiang 457469Ssjiang if (HandlerType & ACPI_SYSTEM_NOTIFY) 458469Ssjiang { 459469Ssjiang AcpiGbl_SystemNotify.Node = Node; 460469Ssjiang AcpiGbl_SystemNotify.Handler = Handler; 461469Ssjiang AcpiGbl_SystemNotify.Context = Context; 462469Ssjiang } 463469Ssjiang 464469Ssjiang if (HandlerType & ACPI_DEVICE_NOTIFY) 465469Ssjiang { 466469Ssjiang AcpiGbl_DeviceNotify.Node = Node; 467469Ssjiang AcpiGbl_DeviceNotify.Handler = Handler; 468469Ssjiang AcpiGbl_DeviceNotify.Context = Context; 469469Ssjiang } 470469Ssjiang 471469Ssjiang /* Global notify handler installed */ 472469Ssjiang } 473469Ssjiang 474469Ssjiang /* 475469Ssjiang * All Other Objects: 476469Ssjiang * Caller will only receive notifications specific to the target object. 477469Ssjiang * Note that only certain object types can receive notifications. 478469Ssjiang */ 479469Ssjiang else 480469Ssjiang { 481469Ssjiang /* Notifies allowed on this object? */ 482469Ssjiang 483469Ssjiang if (!AcpiEvIsNotifyObject (Node)) 484469Ssjiang { 485469Ssjiang Status = AE_TYPE; 486469Ssjiang goto UnlockAndExit; 487469Ssjiang } 488469Ssjiang 489469Ssjiang /* Check for an existing internal object */ 490469Ssjiang 491469Ssjiang ObjDesc = AcpiNsGetAttachedObject (Node); 492469Ssjiang if (ObjDesc) 493469Ssjiang { 494469Ssjiang /* Object exists - make sure there's no handler */ 495469Ssjiang 496469Ssjiang if (((HandlerType & ACPI_SYSTEM_NOTIFY) && 497469Ssjiang ObjDesc->CommonNotify.SystemNotify) || 498469Ssjiang ((HandlerType & ACPI_DEVICE_NOTIFY) && 499469Ssjiang ObjDesc->CommonNotify.DeviceNotify)) 500469Ssjiang { 501469Ssjiang Status = AE_ALREADY_EXISTS; 502469Ssjiang goto UnlockAndExit; 503469Ssjiang } 504469Ssjiang } 505469Ssjiang else 506469Ssjiang { 507469Ssjiang /* Create a new object */ 508469Ssjiang 509469Ssjiang ObjDesc = AcpiUtCreateInternalObject (Node->Type); 510469Ssjiang if (!ObjDesc) 511469Ssjiang { 512469Ssjiang Status = AE_NO_MEMORY; 513469Ssjiang goto UnlockAndExit; 514469Ssjiang } 515469Ssjiang 516469Ssjiang /* Attach new object to the Node */ 517469Ssjiang 518469Ssjiang Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type); 519469Ssjiang 520469Ssjiang /* Remove local reference to the object */ 521469Ssjiang 522469Ssjiang AcpiUtRemoveReference (ObjDesc); 523469Ssjiang if (ACPI_FAILURE (Status)) 524469Ssjiang { 525469Ssjiang goto UnlockAndExit; 526469Ssjiang } 527469Ssjiang } 528469Ssjiang 529469Ssjiang /* Install the handler */ 530469Ssjiang 531469Ssjiang NotifyObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY); 532469Ssjiang if (!NotifyObj) 533469Ssjiang { 534469Ssjiang Status = AE_NO_MEMORY; 535469Ssjiang goto UnlockAndExit; 536469Ssjiang } 537469Ssjiang 538469Ssjiang NotifyObj->Notify.Node = Node; 539469Ssjiang NotifyObj->Notify.Handler = Handler; 540469Ssjiang NotifyObj->Notify.Context = Context; 541469Ssjiang 542469Ssjiang if (HandlerType & ACPI_SYSTEM_NOTIFY) 543469Ssjiang { 544469Ssjiang ObjDesc->CommonNotify.SystemNotify = NotifyObj; 545469Ssjiang } 546469Ssjiang 547469Ssjiang if (HandlerType & ACPI_DEVICE_NOTIFY) 548469Ssjiang { 549469Ssjiang ObjDesc->CommonNotify.DeviceNotify = NotifyObj; 550469Ssjiang } 551469Ssjiang 552469Ssjiang if (HandlerType == ACPI_ALL_NOTIFY) 553469Ssjiang { 554469Ssjiang /* Extra ref if installed in both */ 555469Ssjiang 556469Ssjiang AcpiUtAddReference (NotifyObj); 557469Ssjiang } 558469Ssjiang } 559469Ssjiang 560469Ssjiang 561469SsjiangUnlockAndExit: 562469Ssjiang (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 563469Ssjiang return_ACPI_STATUS (Status); 564469Ssjiang} 565469Ssjiang 566469SsjiangACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler) 567469Ssjiang 568469Ssjiang 569469Ssjiang/******************************************************************************* 570469Ssjiang * 571469Ssjiang * FUNCTION: AcpiRemoveNotifyHandler 572469Ssjiang * 573469Ssjiang * PARAMETERS: Device - The device for which notifies will be handled 574469Ssjiang * HandlerType - The type of handler: 575469Ssjiang * ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f) 576469Ssjiang * ACPI_DEVICE_NOTIFY: DriverHandler (80-ff) 577469Ssjiang * ACPI_ALL_NOTIFY: both system and device 578469Ssjiang * Handler - Address of the handler 579469Ssjiang * 580469Ssjiang * RETURN: Status 581469Ssjiang * 582469Ssjiang * DESCRIPTION: Remove a handler for notifies on an ACPI device 583469Ssjiang * 584469Ssjiang ******************************************************************************/ 585469Ssjiang 586469SsjiangACPI_STATUS 587469SsjiangAcpiRemoveNotifyHandler ( 588469Ssjiang ACPI_HANDLE Device, 589469Ssjiang UINT32 HandlerType, 590469Ssjiang ACPI_NOTIFY_HANDLER Handler) 591469Ssjiang{ 592469Ssjiang ACPI_OPERAND_OBJECT *NotifyObj; 593469Ssjiang ACPI_OPERAND_OBJECT *ObjDesc; 594469Ssjiang ACPI_NAMESPACE_NODE *Node; 595469Ssjiang ACPI_STATUS Status; 596469Ssjiang 597469Ssjiang 598469Ssjiang ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler); 599469Ssjiang 600469Ssjiang 601469Ssjiang /* Parameter validation */ 602469Ssjiang 603469Ssjiang if ((!Device) || 604469Ssjiang (!Handler) || 605469Ssjiang (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 606469Ssjiang { 607469Ssjiang return_ACPI_STATUS (AE_BAD_PARAMETER); 608469Ssjiang } 609469Ssjiang 610469Ssjiang Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 611469Ssjiang if (ACPI_FAILURE (Status)) 612469Ssjiang { 613469Ssjiang return_ACPI_STATUS (Status); 614469Ssjiang } 615469Ssjiang 616469Ssjiang /* Convert and validate the device handle */ 617469Ssjiang 618469Ssjiang Node = AcpiNsValidateHandle (Device); 619469Ssjiang if (!Node) 620469Ssjiang { 621469Ssjiang Status = AE_BAD_PARAMETER; 622469Ssjiang goto UnlockAndExit; 623469Ssjiang } 624469Ssjiang 625469Ssjiang /* Root Object */ 626469Ssjiang 627469Ssjiang if (Device == ACPI_ROOT_OBJECT) 628469Ssjiang { 629469Ssjiang ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 630469Ssjiang "Removing notify handler for namespace root object\n")); 631469Ssjiang 632469Ssjiang if (((HandlerType & ACPI_SYSTEM_NOTIFY) && 633469Ssjiang !AcpiGbl_SystemNotify.Handler) || 634469Ssjiang ((HandlerType & ACPI_DEVICE_NOTIFY) && 635469Ssjiang !AcpiGbl_DeviceNotify.Handler)) 636469Ssjiang { 637469Ssjiang Status = AE_NOT_EXIST; 638469Ssjiang goto UnlockAndExit; 639469Ssjiang } 640469Ssjiang 641469Ssjiang if (HandlerType & ACPI_SYSTEM_NOTIFY) 642469Ssjiang { 643469Ssjiang AcpiGbl_SystemNotify.Node = NULL; 644469Ssjiang AcpiGbl_SystemNotify.Handler = NULL; 645469Ssjiang AcpiGbl_SystemNotify.Context = NULL; 646469Ssjiang } 647469Ssjiang 648469Ssjiang if (HandlerType & ACPI_DEVICE_NOTIFY) 649469Ssjiang { 650469Ssjiang AcpiGbl_DeviceNotify.Node = NULL; 651469Ssjiang AcpiGbl_DeviceNotify.Handler = NULL; 652469Ssjiang AcpiGbl_DeviceNotify.Context = NULL; 653469Ssjiang } 654469Ssjiang } 655469Ssjiang 656469Ssjiang /* All Other Objects */ 657469Ssjiang 658469Ssjiang else 659469Ssjiang { 660469Ssjiang /* Notifies allowed on this object? */ 661469Ssjiang 662469Ssjiang if (!AcpiEvIsNotifyObject (Node)) 663469Ssjiang { 664469Ssjiang Status = AE_TYPE; 665469Ssjiang goto UnlockAndExit; 666469Ssjiang } 667469Ssjiang 668469Ssjiang /* Check for an existing internal object */ 669469Ssjiang 670469Ssjiang ObjDesc = AcpiNsGetAttachedObject (Node); 671469Ssjiang if (!ObjDesc) 672469Ssjiang { 673469Ssjiang Status = AE_NOT_EXIST; 674469Ssjiang goto UnlockAndExit; 675469Ssjiang } 676469Ssjiang 677469Ssjiang /* Object exists - make sure there's an existing handler */ 678469Ssjiang 679469Ssjiang if (HandlerType & ACPI_SYSTEM_NOTIFY) 680469Ssjiang { 681469Ssjiang NotifyObj = ObjDesc->CommonNotify.SystemNotify; 682469Ssjiang if (!NotifyObj) 683469Ssjiang { 684469Ssjiang Status = AE_NOT_EXIST; 685469Ssjiang goto UnlockAndExit; 686469Ssjiang } 687469Ssjiang 688469Ssjiang if (NotifyObj->Notify.Handler != Handler) 689469Ssjiang { 690469Ssjiang Status = AE_BAD_PARAMETER; 691469Ssjiang goto UnlockAndExit; 692469Ssjiang } 693469Ssjiang 694469Ssjiang /* Remove the handler */ 695469Ssjiang 696469Ssjiang ObjDesc->CommonNotify.SystemNotify = NULL; 697469Ssjiang AcpiUtRemoveReference (NotifyObj); 698469Ssjiang } 699469Ssjiang 700469Ssjiang if (HandlerType & ACPI_DEVICE_NOTIFY) 701469Ssjiang { 702469Ssjiang NotifyObj = ObjDesc->CommonNotify.DeviceNotify; 703469Ssjiang if (!NotifyObj) 704469Ssjiang { 705469Ssjiang Status = AE_NOT_EXIST; 706469Ssjiang goto UnlockAndExit; 707469Ssjiang } 708469Ssjiang 709469Ssjiang if (NotifyObj->Notify.Handler != Handler) 710469Ssjiang { 711469Ssjiang Status = AE_BAD_PARAMETER; 712469Ssjiang goto UnlockAndExit; 713469Ssjiang } 714469Ssjiang 715469Ssjiang /* Remove the handler */ 716469Ssjiang 717469Ssjiang ObjDesc->CommonNotify.DeviceNotify = NULL; 718469Ssjiang AcpiUtRemoveReference (NotifyObj); 719469Ssjiang } 720469Ssjiang } 721469Ssjiang 722469Ssjiang 723469SsjiangUnlockAndExit: 724469Ssjiang (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 725469Ssjiang return_ACPI_STATUS (Status); 726469Ssjiang} 727469Ssjiang 728469SsjiangACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler) 729469Ssjiang 730469Ssjiang 731469Ssjiang/******************************************************************************* 732469Ssjiang * 733469Ssjiang * FUNCTION: AcpiInstallGpeHandler 734469Ssjiang * 735469Ssjiang * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 736469Ssjiang * defined GPEs) 737469Ssjiang * GpeNumber - The GPE number within the GPE block 738469Ssjiang * Type - Whether this GPE should be treated as an 739469Ssjiang * edge- or level-triggered interrupt. 740469Ssjiang * Address - Address of the handler 741469Ssjiang * Context - Value passed to the handler on each GPE 742469Ssjiang * 743469Ssjiang * RETURN: Status 744469Ssjiang * 745469Ssjiang * DESCRIPTION: Install a handler for a General Purpose Event. 746469Ssjiang * 747469Ssjiang ******************************************************************************/ 748469Ssjiang 749469SsjiangACPI_STATUS 750469SsjiangAcpiInstallGpeHandler ( 751469Ssjiang ACPI_HANDLE GpeDevice, 752469Ssjiang UINT32 GpeNumber, 753469Ssjiang UINT32 Type, 754469Ssjiang ACPI_GPE_HANDLER Address, 755469Ssjiang void *Context) 756469Ssjiang{ 757469Ssjiang ACPI_GPE_EVENT_INFO *GpeEventInfo; 758469Ssjiang ACPI_GPE_HANDLER_INFO *Handler; 759469Ssjiang ACPI_STATUS Status; 760469Ssjiang ACPI_CPU_FLAGS Flags; 761469Ssjiang 762469Ssjiang 763469Ssjiang ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler); 764469Ssjiang 765469Ssjiang 766469Ssjiang /* Parameter validation */ 767469Ssjiang 768469Ssjiang if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK)) 769469Ssjiang { 770469Ssjiang return_ACPI_STATUS (AE_BAD_PARAMETER); 771469Ssjiang } 772469Ssjiang 773469Ssjiang Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 774469Ssjiang if (ACPI_FAILURE (Status)) 775469Ssjiang { 776469Ssjiang return_ACPI_STATUS (Status); 777469Ssjiang } 778469Ssjiang 779469Ssjiang /* Allocate and init handler object (before lock) */ 780469Ssjiang 781469Ssjiang Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO)); 782469Ssjiang if (!Handler) 783469Ssjiang { 784469Ssjiang Status = AE_NO_MEMORY; 785469Ssjiang goto UnlockAndExit; 786469Ssjiang } 787469Ssjiang 788469Ssjiang Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 789469Ssjiang 790469Ssjiang /* Ensure that we have a valid GPE number */ 791469Ssjiang 792469Ssjiang GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 793469Ssjiang if (!GpeEventInfo) 794469Ssjiang { 795469Ssjiang Status = AE_BAD_PARAMETER; 796469Ssjiang goto FreeAndExit; 797469Ssjiang } 798469Ssjiang 799469Ssjiang /* Make sure that there isn't a handler there already */ 800469Ssjiang 801469Ssjiang if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 802469Ssjiang ACPI_GPE_DISPATCH_HANDLER) 803469Ssjiang { 804469Ssjiang Status = AE_ALREADY_EXISTS; 805469Ssjiang goto FreeAndExit; 806469Ssjiang } 807469Ssjiang 808469Ssjiang Handler->Address = Address; 809469Ssjiang Handler->Context = Context; 810469Ssjiang Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode; 811469Ssjiang Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags & 812469Ssjiang (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK)); 813469Ssjiang 814469Ssjiang /* 815469Ssjiang * If the GPE is associated with a method, it may have been enabled 816469Ssjiang * automatically during initialization, in which case it has to be 817469Ssjiang * disabled now to avoid spurious execution of the handler. 818469Ssjiang */ 819469Ssjiang if (((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) || 820469Ssjiang (Handler->OriginalFlags & ACPI_GPE_DISPATCH_NOTIFY)) && 821469Ssjiang GpeEventInfo->RuntimeCount) 822469Ssjiang { 823469Ssjiang Handler->OriginallyEnabled = TRUE; 824469Ssjiang (void) AcpiEvRemoveGpeReference (GpeEventInfo); 825469Ssjiang 826469Ssjiang /* Sanity check of original type against new type */ 827469Ssjiang 828469Ssjiang if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK)) 829469Ssjiang { 830469Ssjiang ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)")); 831469Ssjiang } 832469Ssjiang } 833469Ssjiang 834469Ssjiang /* Install the handler */ 835469Ssjiang 836469Ssjiang GpeEventInfo->Dispatch.Handler = Handler; 837469Ssjiang 838469Ssjiang /* Setup up dispatch flags to indicate handler (vs. method/notify) */ 839469Ssjiang 840469Ssjiang GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 841469Ssjiang GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER); 842469Ssjiang 843469Ssjiang AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 844469Ssjiang 845469Ssjiang 846469SsjiangUnlockAndExit: 847469Ssjiang (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 848469Ssjiang return_ACPI_STATUS (Status); 849469Ssjiang 850469SsjiangFreeAndExit: 851469Ssjiang AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 852469Ssjiang ACPI_FREE (Handler); 853469Ssjiang goto UnlockAndExit; 854469Ssjiang} 855469Ssjiang 856469SsjiangACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler) 857469Ssjiang 858469Ssjiang 859469Ssjiang/******************************************************************************* 860469Ssjiang * 861469Ssjiang * FUNCTION: AcpiRemoveGpeHandler 862469Ssjiang * 863469Ssjiang * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 864469Ssjiang * defined GPEs) 865469Ssjiang * GpeNumber - The event to remove a handler 866469Ssjiang * Address - Address of the handler 867469Ssjiang * 868469Ssjiang * RETURN: Status 869469Ssjiang * 870469Ssjiang * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent. 871469Ssjiang * 872469Ssjiang ******************************************************************************/ 873469Ssjiang 874469SsjiangACPI_STATUS 875469SsjiangAcpiRemoveGpeHandler ( 876469Ssjiang ACPI_HANDLE GpeDevice, 877469Ssjiang UINT32 GpeNumber, 878469Ssjiang ACPI_GPE_HANDLER Address) 879469Ssjiang{ 880469Ssjiang ACPI_GPE_EVENT_INFO *GpeEventInfo; 881469Ssjiang ACPI_GPE_HANDLER_INFO *Handler; 882469Ssjiang ACPI_STATUS Status; 883469Ssjiang ACPI_CPU_FLAGS Flags; 884469Ssjiang 885469Ssjiang 886469Ssjiang ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler); 887469Ssjiang 888469Ssjiang 889469Ssjiang /* Parameter validation */ 890469Ssjiang 891469Ssjiang if (!Address) 892469Ssjiang { 893469Ssjiang return_ACPI_STATUS (AE_BAD_PARAMETER); 894469Ssjiang } 895469Ssjiang 896469Ssjiang Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 897469Ssjiang if (ACPI_FAILURE (Status)) 898469Ssjiang { 899469Ssjiang return_ACPI_STATUS (Status); 900469Ssjiang } 901469Ssjiang 902469Ssjiang Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 903469Ssjiang 904469Ssjiang /* Ensure that we have a valid GPE number */ 905469Ssjiang 906469Ssjiang GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 907469Ssjiang if (!GpeEventInfo) 908469Ssjiang { 909469Ssjiang Status = AE_BAD_PARAMETER; 910469Ssjiang goto UnlockAndExit; 911469Ssjiang } 912469Ssjiang 913469Ssjiang /* Make sure that a handler is indeed installed */ 914469Ssjiang 915469Ssjiang if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) != 916469Ssjiang ACPI_GPE_DISPATCH_HANDLER) 917469Ssjiang { 918469Ssjiang Status = AE_NOT_EXIST; 919469Ssjiang goto UnlockAndExit; 920469Ssjiang } 921469Ssjiang 922469Ssjiang /* Make sure that the installed handler is the same */ 923469Ssjiang 924469Ssjiang if (GpeEventInfo->Dispatch.Handler->Address != Address) 925469Ssjiang { 926469Ssjiang Status = AE_BAD_PARAMETER; 927469Ssjiang goto UnlockAndExit; 928469Ssjiang } 929469Ssjiang 930469Ssjiang /* Remove the handler */ 931469Ssjiang 932469Ssjiang Handler = GpeEventInfo->Dispatch.Handler; 933469Ssjiang 934469Ssjiang /* Restore Method node (if any), set dispatch flags */ 935469Ssjiang 936469Ssjiang GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode; 937469Ssjiang GpeEventInfo->Flags &= 938469Ssjiang ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 939469Ssjiang GpeEventInfo->Flags |= Handler->OriginalFlags; 940469Ssjiang 941469Ssjiang /* 942469Ssjiang * If the GPE was previously associated with a method and it was 943469Ssjiang * enabled, it should be enabled at this point to restore the 944469Ssjiang * post-initialization configuration. 945469Ssjiang */ 946469Ssjiang if ((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) && 947469Ssjiang Handler->OriginallyEnabled) 948469Ssjiang { 949469Ssjiang (void) AcpiEvAddGpeReference (GpeEventInfo); 950469Ssjiang } 951469Ssjiang 952469Ssjiang /* Now we can free the handler object */ 953469Ssjiang 954469Ssjiang ACPI_FREE (Handler); 955469Ssjiang 956469Ssjiang 957469SsjiangUnlockAndExit: 958469Ssjiang AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 959469Ssjiang (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 960469Ssjiang return_ACPI_STATUS (Status); 961469Ssjiang} 962469Ssjiang 963469SsjiangACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler) 964469Ssjiang 965469Ssjiang 966469Ssjiang/******************************************************************************* 967469Ssjiang * 968469Ssjiang * FUNCTION: AcpiAcquireGlobalLock 969469Ssjiang * 970469Ssjiang * PARAMETERS: Timeout - How long the caller is willing to wait 971469Ssjiang * Handle - Where the handle to the lock is returned 972469Ssjiang * (if acquired) 973469Ssjiang * 974469Ssjiang * RETURN: Status 975469Ssjiang * 976469Ssjiang * DESCRIPTION: Acquire the ACPI Global Lock 977469Ssjiang * 978469Ssjiang * Note: Allows callers with the same thread ID to acquire the global lock 979469Ssjiang * multiple times. In other words, externally, the behavior of the global lock 980469Ssjiang * is identical to an AML mutex. On the first acquire, a new handle is 981469Ssjiang * returned. On any subsequent calls to acquire by the same thread, the same 982469Ssjiang * handle is returned. 983469Ssjiang * 984469Ssjiang ******************************************************************************/ 985469Ssjiang 986469SsjiangACPI_STATUS 987469SsjiangAcpiAcquireGlobalLock ( 988469Ssjiang UINT16 Timeout, 989469Ssjiang UINT32 *Handle) 990469Ssjiang{ 991469Ssjiang ACPI_STATUS Status; 992469Ssjiang 993469Ssjiang 994469Ssjiang if (!Handle) 995469Ssjiang { 996469Ssjiang return (AE_BAD_PARAMETER); 997469Ssjiang } 998469Ssjiang 999469Ssjiang /* Must lock interpreter to prevent race conditions */ 1000469Ssjiang 1001469Ssjiang AcpiExEnterInterpreter (); 1002469Ssjiang 1003469Ssjiang Status = AcpiExAcquireMutexObject (Timeout, 1004469Ssjiang AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ()); 1005469Ssjiang 1006469Ssjiang if (ACPI_SUCCESS (Status)) 1007469Ssjiang { 1008469Ssjiang /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */ 1009469Ssjiang 1010469Ssjiang *Handle = AcpiGbl_GlobalLockHandle; 1011469Ssjiang } 1012469Ssjiang 1013469Ssjiang AcpiExExitInterpreter (); 1014469Ssjiang return (Status); 1015469Ssjiang} 1016469Ssjiang 1017469SsjiangACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock) 1018469Ssjiang 1019469Ssjiang 1020469Ssjiang/******************************************************************************* 1021469Ssjiang * 1022469Ssjiang * FUNCTION: AcpiReleaseGlobalLock 1023469Ssjiang * 1024469Ssjiang * PARAMETERS: Handle - Returned from AcpiAcquireGlobalLock 1025469Ssjiang * 1026469Ssjiang * RETURN: Status 1027469Ssjiang * 1028469Ssjiang * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid. 1029469Ssjiang * 1030469Ssjiang ******************************************************************************/ 1031469Ssjiang 1032469SsjiangACPI_STATUS 1033469SsjiangAcpiReleaseGlobalLock ( 1034469Ssjiang UINT32 Handle) 1035469Ssjiang{ 1036469Ssjiang ACPI_STATUS Status; 1037469Ssjiang 1038469Ssjiang 1039469Ssjiang if (!Handle || (Handle != AcpiGbl_GlobalLockHandle)) 1040469Ssjiang { 1041469Ssjiang return (AE_NOT_ACQUIRED); 1042469Ssjiang } 1043469Ssjiang 1044469Ssjiang Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex); 1045469Ssjiang return (Status); 1046469Ssjiang} 1047469Ssjiang 1048469SsjiangACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock) 1049469Ssjiang 1050469Ssjiang