1 /******************************************************************************
   2  *
   3  * Module Name: utxface - External interfaces for "global" ACPI functions
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 
  45 #define __UTXFACE_C__
  46 
  47 #include "acpi.h"
  48 #include "accommon.h"
  49 #include "acevents.h"
  50 #include "acnamesp.h"
  51 #include "acdebug.h"
  52 #include "actables.h"
  53 
  54 #define _COMPONENT          ACPI_UTILITIES
  55         ACPI_MODULE_NAME    ("utxface")
  56 
  57 
  58 #ifndef ACPI_ASL_COMPILER
  59 
  60 /*******************************************************************************
  61  *
  62  * FUNCTION:    AcpiInitializeSubsystem
  63  *
  64  * PARAMETERS:  None
  65  *
  66  * RETURN:      Status
  67  *
  68  * DESCRIPTION: Initializes all global variables.  This is the first function
  69  *              called, so any early initialization belongs here.
  70  *
  71  ******************************************************************************/
  72 
  73 ACPI_STATUS
  74 AcpiInitializeSubsystem (
  75     void)
  76 {
  77     ACPI_STATUS             Status;
  78 
  79 
  80     ACPI_FUNCTION_TRACE (AcpiInitializeSubsystem);
  81 
  82 
  83     AcpiGbl_StartupFlags = ACPI_SUBSYSTEM_INITIALIZE;
  84     ACPI_DEBUG_EXEC (AcpiUtInitStackPtrTrace ());
  85 
  86     /* Initialize the OS-Dependent layer */
  87 
  88     Status = AcpiOsInitialize ();
  89     if (ACPI_FAILURE (Status))
  90     {
  91         ACPI_EXCEPTION ((AE_INFO, Status, "During OSL initialization"));
  92         return_ACPI_STATUS (Status);
  93     }
  94 
  95     /* Initialize all globals used by the subsystem */
  96 
  97     Status = AcpiUtInitGlobals ();
  98     if (ACPI_FAILURE (Status))
  99     {
 100         ACPI_EXCEPTION ((AE_INFO, Status, "During initialization of globals"));
 101         return_ACPI_STATUS (Status);
 102     }
 103 
 104     /* Create the default mutex objects */
 105 
 106     Status = AcpiUtMutexInitialize ();
 107     if (ACPI_FAILURE (Status))
 108     {
 109         ACPI_EXCEPTION ((AE_INFO, Status, "During Global Mutex creation"));
 110         return_ACPI_STATUS (Status);
 111     }
 112 
 113     /*
 114      * Initialize the namespace manager and
 115      * the root of the namespace tree
 116      */
 117     Status = AcpiNsRootInitialize ();
 118     if (ACPI_FAILURE (Status))
 119     {
 120         ACPI_EXCEPTION ((AE_INFO, Status, "During Namespace initialization"));
 121         return_ACPI_STATUS (Status);
 122     }
 123 
 124     /* Initialize the global OSI interfaces list with the static names */
 125 
 126     Status = AcpiUtInitializeInterfaces ();
 127     if (ACPI_FAILURE (Status))
 128     {
 129         ACPI_EXCEPTION ((AE_INFO, Status, "During OSI interfaces initialization"));
 130         return_ACPI_STATUS (Status);
 131     }
 132 
 133     /* If configured, initialize the AML debugger */
 134 
 135     ACPI_DEBUGGER_EXEC (Status = AcpiDbInitialize ());
 136     return_ACPI_STATUS (Status);
 137 }
 138 
 139 ACPI_EXPORT_SYMBOL (AcpiInitializeSubsystem)
 140 
 141 
 142 /*******************************************************************************
 143  *
 144  * FUNCTION:    AcpiEnableSubsystem
 145  *
 146  * PARAMETERS:  Flags           - Init/enable Options
 147  *
 148  * RETURN:      Status
 149  *
 150  * DESCRIPTION: Completes the subsystem initialization including hardware.
 151  *              Puts system into ACPI mode if it isn't already.
 152  *
 153  ******************************************************************************/
 154 
 155 ACPI_STATUS
 156 AcpiEnableSubsystem (
 157     UINT32                  Flags)
 158 {
 159     ACPI_STATUS             Status = AE_OK;
 160 
 161 
 162     ACPI_FUNCTION_TRACE (AcpiEnableSubsystem);
 163 
 164 
 165     /* Enable ACPI mode */
 166 
 167     if (!(Flags & ACPI_NO_ACPI_ENABLE))
 168     {
 169         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Going into ACPI mode\n"));
 170 
 171         AcpiGbl_OriginalMode = AcpiHwGetMode();
 172 
 173         Status = AcpiEnable ();
 174         if (ACPI_FAILURE (Status))
 175         {
 176             ACPI_WARNING ((AE_INFO, "AcpiEnable failed"));
 177             return_ACPI_STATUS (Status);
 178         }
 179     }
 180 
 181     /*
 182      * Obtain a permanent mapping for the FACS. This is required for the
 183      * Global Lock and the Firmware Waking Vector
 184      */
 185     Status = AcpiTbInitializeFacs ();
 186     if (ACPI_FAILURE (Status))
 187     {
 188         ACPI_WARNING ((AE_INFO, "Could not map the FACS table"));
 189         return_ACPI_STATUS (Status);
 190     }
 191 
 192     /*
 193      * Install the default OpRegion handlers.  These are installed unless
 194      * other handlers have already been installed via the
 195      * InstallAddressSpaceHandler interface.
 196      */
 197     if (!(Flags & ACPI_NO_ADDRESS_SPACE_INIT))
 198     {
 199         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 200             "[Init] Installing default address space handlers\n"));
 201 
 202         Status = AcpiEvInstallRegionHandlers ();
 203         if (ACPI_FAILURE (Status))
 204         {
 205             return_ACPI_STATUS (Status);
 206         }
 207     }
 208 
 209     /*
 210      * Initialize ACPI Event handling (Fixed and General Purpose)
 211      *
 212      * Note1: We must have the hardware and events initialized before we can
 213      * execute any control methods safely. Any control method can require
 214      * ACPI hardware support, so the hardware must be fully initialized before
 215      * any method execution!
 216      *
 217      * Note2: Fixed events are initialized and enabled here. GPEs are
 218      * initialized, but cannot be enabled until after the hardware is
 219      * completely initialized (SCI and GlobalLock activated) and the various
 220      * initialization control methods are run (_REG, _STA, _INI) on the
 221      * entire namespace.
 222      */
 223     if (!(Flags & ACPI_NO_EVENT_INIT))
 224     {
 225         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 226             "[Init] Initializing ACPI events\n"));
 227 
 228         Status = AcpiEvInitializeEvents ();
 229         if (ACPI_FAILURE (Status))
 230         {
 231             return_ACPI_STATUS (Status);
 232         }
 233     }
 234 
 235     /*
 236      * Install the SCI handler and Global Lock handler. This completes the
 237      * hardware initialization.
 238      */
 239     if (!(Flags & ACPI_NO_HANDLER_INIT))
 240     {
 241         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 242             "[Init] Installing SCI/GL handlers\n"));
 243 
 244         Status = AcpiEvInstallXruptHandlers ();
 245         if (ACPI_FAILURE (Status))
 246         {
 247             return_ACPI_STATUS (Status);
 248         }
 249     }
 250 
 251     return_ACPI_STATUS (Status);
 252 }
 253 
 254 ACPI_EXPORT_SYMBOL (AcpiEnableSubsystem)
 255 
 256 
 257 /*******************************************************************************
 258  *
 259  * FUNCTION:    AcpiInitializeObjects
 260  *
 261  * PARAMETERS:  Flags           - Init/enable Options
 262  *
 263  * RETURN:      Status
 264  *
 265  * DESCRIPTION: Completes namespace initialization by initializing device
 266  *              objects and executing AML code for Regions, buffers, etc.
 267  *
 268  ******************************************************************************/
 269 
 270 ACPI_STATUS
 271 AcpiInitializeObjects (
 272     UINT32                  Flags)
 273 {
 274     ACPI_STATUS             Status = AE_OK;
 275 
 276 
 277     ACPI_FUNCTION_TRACE (AcpiInitializeObjects);
 278 
 279 
 280     /*
 281      * Run all _REG methods
 282      *
 283      * Note: Any objects accessed by the _REG methods will be automatically
 284      * initialized, even if they contain executable AML (see the call to
 285      * AcpiNsInitializeObjects below).
 286      */
 287     if (!(Flags & ACPI_NO_ADDRESS_SPACE_INIT))
 288     {
 289         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 290             "[Init] Executing _REG OpRegion methods\n"));
 291 
 292         Status = AcpiEvInitializeOpRegions ();
 293         if (ACPI_FAILURE (Status))
 294         {
 295             return_ACPI_STATUS (Status);
 296         }
 297     }
 298 
 299     /*
 300      * Execute any module-level code that was detected during the table load
 301      * phase. Although illegal since ACPI 2.0, there are many machines that
 302      * contain this type of code. Each block of detected executable AML code
 303      * outside of any control method is wrapped with a temporary control
 304      * method object and placed on a global list. The methods on this list
 305      * are executed below.
 306      */
 307     AcpiNsExecModuleCodeList ();
 308 
 309     /*
 310      * Initialize the objects that remain uninitialized. This runs the
 311      * executable AML that may be part of the declaration of these objects:
 312      * OperationRegions, BufferFields, Buffers, and Packages.
 313      */
 314     if (!(Flags & ACPI_NO_OBJECT_INIT))
 315     {
 316         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 317             "[Init] Completing Initialization of ACPI Objects\n"));
 318 
 319         Status = AcpiNsInitializeObjects ();
 320         if (ACPI_FAILURE (Status))
 321         {
 322             return_ACPI_STATUS (Status);
 323         }
 324     }
 325 
 326     /*
 327      * Initialize all device objects in the namespace. This runs the device
 328      * _STA and _INI methods.
 329      */
 330     if (!(Flags & ACPI_NO_DEVICE_INIT))
 331     {
 332         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 333             "[Init] Initializing ACPI Devices\n"));
 334 
 335         Status = AcpiNsInitializeDevices ();
 336         if (ACPI_FAILURE (Status))
 337         {
 338             return_ACPI_STATUS (Status);
 339         }
 340     }
 341 
 342     /*
 343      * Empty the caches (delete the cached objects) on the assumption that
 344      * the table load filled them up more than they will be at runtime --
 345      * thus wasting non-paged memory.
 346      */
 347     Status = AcpiPurgeCachedObjects ();
 348 
 349     AcpiGbl_StartupFlags |= ACPI_INITIALIZED_OK;
 350     return_ACPI_STATUS (Status);
 351 }
 352 
 353 ACPI_EXPORT_SYMBOL (AcpiInitializeObjects)
 354 
 355 
 356 #endif
 357 
 358 /*******************************************************************************
 359  *
 360  * FUNCTION:    AcpiTerminate
 361  *
 362  * PARAMETERS:  None
 363  *
 364  * RETURN:      Status
 365  *
 366  * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources.
 367  *
 368  ******************************************************************************/
 369 
 370 ACPI_STATUS
 371 AcpiTerminate (
 372     void)
 373 {
 374     ACPI_STATUS         Status;
 375 
 376 
 377     ACPI_FUNCTION_TRACE (AcpiTerminate);
 378 
 379 
 380     /* Just exit if subsystem is already shutdown */
 381 
 382     if (AcpiGbl_Shutdown)
 383     {
 384         ACPI_ERROR ((AE_INFO, "ACPI Subsystem is already terminated"));
 385         return_ACPI_STATUS (AE_OK);
 386     }
 387 
 388     /* Subsystem appears active, go ahead and shut it down */
 389 
 390     AcpiGbl_Shutdown = TRUE;
 391     AcpiGbl_StartupFlags = 0;
 392     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
 393 
 394     /* Terminate the AML Debugger if present */
 395 
 396     ACPI_DEBUGGER_EXEC (AcpiGbl_DbTerminateThreads = TRUE);
 397 
 398     /* Shutdown and free all resources */
 399 
 400     AcpiUtSubsystemShutdown ();
 401 
 402     /* Free the mutex objects */
 403 
 404     AcpiUtMutexTerminate ();
 405 
 406 
 407 #ifdef ACPI_DEBUGGER
 408 
 409     /* Shut down the debugger */
 410 
 411     AcpiDbTerminate ();
 412 #endif
 413 
 414     /* Now we can shutdown the OS-dependent layer */
 415 
 416     Status = AcpiOsTerminate ();
 417     return_ACPI_STATUS (Status);
 418 }
 419 
 420 ACPI_EXPORT_SYMBOL (AcpiTerminate)
 421 
 422 
 423 #ifndef ACPI_ASL_COMPILER
 424 /*******************************************************************************
 425  *
 426  * FUNCTION:    AcpiSubsystemStatus
 427  *
 428  * PARAMETERS:  None
 429  *
 430  * RETURN:      Status of the ACPI subsystem
 431  *
 432  * DESCRIPTION: Other drivers that use the ACPI subsystem should call this
 433  *              before making any other calls, to ensure the subsystem
 434  *              initialized successfully.
 435  *
 436  ******************************************************************************/
 437 
 438 ACPI_STATUS
 439 AcpiSubsystemStatus (
 440     void)
 441 {
 442 
 443     if (AcpiGbl_StartupFlags & ACPI_INITIALIZED_OK)
 444     {
 445         return (AE_OK);
 446     }
 447     else
 448     {
 449         return (AE_ERROR);
 450     }
 451 }
 452 
 453 ACPI_EXPORT_SYMBOL (AcpiSubsystemStatus)
 454 
 455 
 456 /*******************************************************************************
 457  *
 458  * FUNCTION:    AcpiGetSystemInfo
 459  *
 460  * PARAMETERS:  OutBuffer       - A buffer to receive the resources for the
 461  *                                device
 462  *
 463  * RETURN:      Status          - the status of the call
 464  *
 465  * DESCRIPTION: This function is called to get information about the current
 466  *              state of the ACPI subsystem.  It will return system information
 467  *              in the OutBuffer.
 468  *
 469  *              If the function fails an appropriate status will be returned
 470  *              and the value of OutBuffer is undefined.
 471  *
 472  ******************************************************************************/
 473 
 474 ACPI_STATUS
 475 AcpiGetSystemInfo (
 476     ACPI_BUFFER             *OutBuffer)
 477 {
 478     ACPI_SYSTEM_INFO        *InfoPtr;
 479     ACPI_STATUS             Status;
 480 
 481 
 482     ACPI_FUNCTION_TRACE (AcpiGetSystemInfo);
 483 
 484 
 485     /* Parameter validation */
 486 
 487     Status = AcpiUtValidateBuffer (OutBuffer);
 488     if (ACPI_FAILURE (Status))
 489     {
 490         return_ACPI_STATUS (Status);
 491     }
 492 
 493     /* Validate/Allocate/Clear caller buffer */
 494 
 495     Status = AcpiUtInitializeBuffer (OutBuffer, sizeof (ACPI_SYSTEM_INFO));
 496     if (ACPI_FAILURE (Status))
 497     {
 498         return_ACPI_STATUS (Status);
 499     }
 500 
 501     /*
 502      * Populate the return buffer
 503      */
 504     InfoPtr = (ACPI_SYSTEM_INFO *) OutBuffer->Pointer;
 505 
 506     InfoPtr->AcpiCaVersion = ACPI_CA_VERSION;
 507 
 508     /* System flags (ACPI capabilities) */
 509 
 510     InfoPtr->Flags = ACPI_SYS_MODE_ACPI;
 511 
 512     /* Timer resolution - 24 or 32 bits  */
 513 
 514     if (AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER)
 515     {
 516         InfoPtr->TimerResolution = 24;
 517     }
 518     else
 519     {
 520         InfoPtr->TimerResolution = 32;
 521     }
 522 
 523     /* Clear the reserved fields */
 524 
 525     InfoPtr->Reserved1 = 0;
 526     InfoPtr->Reserved2 = 0;
 527 
 528     /* Current debug levels */
 529 
 530     InfoPtr->DebugLayer = AcpiDbgLayer;
 531     InfoPtr->DebugLevel = AcpiDbgLevel;
 532 
 533     return_ACPI_STATUS (AE_OK);
 534 }
 535 
 536 ACPI_EXPORT_SYMBOL (AcpiGetSystemInfo)
 537 
 538 
 539 /*******************************************************************************
 540  *
 541  * FUNCTION:    AcpiGetStatistics
 542  *
 543  * PARAMETERS:  Stats           - Where the statistics are returned
 544  *
 545  * RETURN:      Status          - the status of the call
 546  *
 547  * DESCRIPTION: Get the contents of the various system counters
 548  *
 549  ******************************************************************************/
 550 
 551 ACPI_STATUS
 552 AcpiGetStatistics (
 553     ACPI_STATISTICS         *Stats)
 554 {
 555     ACPI_FUNCTION_TRACE (AcpiGetStatistics);
 556 
 557 
 558     /* Parameter validation */
 559 
 560     if (!Stats)
 561     {
 562         return_ACPI_STATUS (AE_BAD_PARAMETER);
 563     }
 564 
 565     /* Various interrupt-based event counters */
 566 
 567     Stats->SciCount = AcpiSciCount;
 568     Stats->GpeCount = AcpiGpeCount;
 569 
 570     ACPI_MEMCPY (Stats->FixedEventCount, AcpiFixedEventCount,
 571         sizeof (AcpiFixedEventCount));
 572 
 573 
 574     /* Other counters */
 575 
 576     Stats->MethodCount = AcpiMethodCount;
 577 
 578     return_ACPI_STATUS (AE_OK);
 579 }
 580 
 581 ACPI_EXPORT_SYMBOL (AcpiGetStatistics)
 582 
 583 
 584 /*****************************************************************************
 585  *
 586  * FUNCTION:    AcpiInstallInitializationHandler
 587  *
 588  * PARAMETERS:  Handler             - Callback procedure
 589  *              Function            - Not (currently) used, see below
 590  *
 591  * RETURN:      Status
 592  *
 593  * DESCRIPTION: Install an initialization handler
 594  *
 595  * TBD: When a second function is added, must save the Function also.
 596  *
 597  ****************************************************************************/
 598 
 599 ACPI_STATUS
 600 AcpiInstallInitializationHandler (
 601     ACPI_INIT_HANDLER       Handler,
 602     UINT32                  Function)
 603 {
 604 
 605     if (!Handler)
 606     {
 607         return (AE_BAD_PARAMETER);
 608     }
 609 
 610     if (AcpiGbl_InitHandler)
 611     {
 612         return (AE_ALREADY_EXISTS);
 613     }
 614 
 615     AcpiGbl_InitHandler = Handler;
 616     return AE_OK;
 617 }
 618 
 619 ACPI_EXPORT_SYMBOL (AcpiInstallInitializationHandler)
 620 
 621 
 622 /*****************************************************************************
 623  *
 624  * FUNCTION:    AcpiPurgeCachedObjects
 625  *
 626  * PARAMETERS:  None
 627  *
 628  * RETURN:      Status
 629  *
 630  * DESCRIPTION: Empty all caches (delete the cached objects)
 631  *
 632  ****************************************************************************/
 633 
 634 ACPI_STATUS
 635 AcpiPurgeCachedObjects (
 636     void)
 637 {
 638     ACPI_FUNCTION_TRACE (AcpiPurgeCachedObjects);
 639 
 640     (void) AcpiOsPurgeCache (AcpiGbl_StateCache);
 641     (void) AcpiOsPurgeCache (AcpiGbl_OperandCache);
 642     (void) AcpiOsPurgeCache (AcpiGbl_PsNodeCache);
 643     (void) AcpiOsPurgeCache (AcpiGbl_PsNodeExtCache);
 644     return_ACPI_STATUS (AE_OK);
 645 }
 646 
 647 ACPI_EXPORT_SYMBOL (AcpiPurgeCachedObjects)
 648 
 649 
 650 /*****************************************************************************
 651  *
 652  * FUNCTION:    AcpiInstallInterface
 653  *
 654  * PARAMETERS:  InterfaceName       - The interface to install
 655  *
 656  * RETURN:      Status
 657  *
 658  * DESCRIPTION: Install an _OSI interface to the global list
 659  *
 660  ****************************************************************************/
 661 
 662 ACPI_STATUS
 663 AcpiInstallInterface (
 664     ACPI_STRING             InterfaceName)
 665 {
 666     ACPI_STATUS             Status;
 667     ACPI_INTERFACE_INFO     *InterfaceInfo;
 668 
 669 
 670     /* Parameter validation */
 671 
 672     if (!InterfaceName || (ACPI_STRLEN (InterfaceName) == 0))
 673     {
 674         return (AE_BAD_PARAMETER);
 675     }
 676 
 677     (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
 678 
 679     /* Check if the interface name is already in the global list */
 680 
 681     InterfaceInfo = AcpiUtGetInterface (InterfaceName);
 682     if (InterfaceInfo)
 683     {
 684         /*
 685          * The interface already exists in the list. This is OK if the
 686          * interface has been marked invalid -- just clear the bit.
 687          */
 688         if (InterfaceInfo->Flags & ACPI_OSI_INVALID)
 689         {
 690             InterfaceInfo->Flags &= ~ACPI_OSI_INVALID;
 691             Status = AE_OK;
 692         }
 693         else
 694         {
 695             Status = AE_ALREADY_EXISTS;
 696         }
 697     }
 698     else
 699     {
 700         /* New interface name, install into the global list */
 701 
 702         Status = AcpiUtInstallInterface (InterfaceName);
 703     }
 704 
 705     AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
 706     return (Status);
 707 }
 708 
 709 ACPI_EXPORT_SYMBOL (AcpiInstallInterface)
 710 
 711 
 712 /*****************************************************************************
 713  *
 714  * FUNCTION:    AcpiRemoveInterface
 715  *
 716  * PARAMETERS:  InterfaceName       - The interface to remove
 717  *
 718  * RETURN:      Status
 719  *
 720  * DESCRIPTION: Remove an _OSI interface from the global list
 721  *
 722  ****************************************************************************/
 723 
 724 ACPI_STATUS
 725 AcpiRemoveInterface (
 726     ACPI_STRING             InterfaceName)
 727 {
 728     ACPI_STATUS             Status;
 729 
 730 
 731     /* Parameter validation */
 732 
 733     if (!InterfaceName || (ACPI_STRLEN (InterfaceName) == 0))
 734     {
 735         return (AE_BAD_PARAMETER);
 736     }
 737 
 738     (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
 739 
 740     Status = AcpiUtRemoveInterface (InterfaceName);
 741 
 742     AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
 743     return (Status);
 744 }
 745 
 746 ACPI_EXPORT_SYMBOL (AcpiRemoveInterface)
 747 
 748 
 749 /*****************************************************************************
 750  *
 751  * FUNCTION:    AcpiInstallInterfaceHandler
 752  *
 753  * PARAMETERS:  Handler             - The _OSI interface handler to install
 754  *                                    NULL means "remove existing handler"
 755  *
 756  * RETURN:      Status
 757  *
 758  * DESCRIPTION: Install a handler for the predefined _OSI ACPI method.
 759  *              invoked during execution of the internal implementation of
 760  *              _OSI. A NULL handler simply removes any existing handler.
 761  *
 762  ****************************************************************************/
 763 
 764 ACPI_STATUS
 765 AcpiInstallInterfaceHandler (
 766     ACPI_INTERFACE_HANDLER  Handler)
 767 {
 768     ACPI_STATUS             Status = AE_OK;
 769 
 770 
 771     (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
 772 
 773     if (Handler && AcpiGbl_InterfaceHandler)
 774     {
 775         Status = AE_ALREADY_EXISTS;
 776     }
 777     else
 778     {
 779         AcpiGbl_InterfaceHandler = Handler;
 780     }
 781 
 782     AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
 783     return (Status);
 784 }
 785 
 786 ACPI_EXPORT_SYMBOL (AcpiInstallInterfaceHandler)
 787 
 788 #endif /* !ACPI_ASL_COMPILER */
 789