Home | History | Annotate | Line # | Download | only in tables
tbxface.c revision 1.4.6.2
      1 /******************************************************************************
      2  *
      3  * Module Name: tbxface - Public interfaces to the ACPI subsystem
      4  *                         ACPI table oriented interfaces
      5  *
      6  *****************************************************************************/
      7 
      8 /*
      9  * Copyright (C) 2000 - 2011, Intel Corp.
     10  * All rights reserved.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions, and the following disclaimer,
     17  *    without modification.
     18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     19  *    substantially similar to the "NO WARRANTY" disclaimer below
     20  *    ("Disclaimer") and any redistribution must be conditioned upon
     21  *    including a substantially similar Disclaimer requirement for further
     22  *    binary redistribution.
     23  * 3. Neither the names of the above-listed copyright holders nor the names
     24  *    of any contributors may be used to endorse or promote products derived
     25  *    from this software without specific prior written permission.
     26  *
     27  * Alternatively, this software may be distributed under the terms of the
     28  * GNU General Public License ("GPL") version 2 as published by the Free
     29  * Software Foundation.
     30  *
     31  * NO WARRANTY
     32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     42  * POSSIBILITY OF SUCH DAMAGES.
     43  */
     44 
     45 #define __TBXFACE_C__
     46 
     47 #include "acpi.h"
     48 #include "accommon.h"
     49 #include "acnamesp.h"
     50 #include "actables.h"
     51 
     52 #define _COMPONENT          ACPI_TABLES
     53         ACPI_MODULE_NAME    ("tbxface")
     54 
     55 /* Local prototypes */
     56 
     57 static ACPI_STATUS
     58 AcpiTbLoadNamespace (
     59     void);
     60 
     61 
     62 /*******************************************************************************
     63  *
     64  * FUNCTION:    AcpiAllocateRootTable
     65  *
     66  * PARAMETERS:  InitialTableCount   - Size of InitialTableArray, in number of
     67  *                                    ACPI_TABLE_DESC structures
     68  *
     69  * RETURN:      Status
     70  *
     71  * DESCRIPTION: Allocate a root table array. Used by iASL compiler and
     72  *              AcpiInitializeTables.
     73  *
     74  ******************************************************************************/
     75 
     76 ACPI_STATUS
     77 AcpiAllocateRootTable (
     78     UINT32                  InitialTableCount)
     79 {
     80 
     81     AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
     82     AcpiGbl_RootTableList.Flags = ACPI_ROOT_ALLOW_RESIZE;
     83 
     84     return (AcpiTbResizeRootTableList ());
     85 }
     86 
     87 
     88 /*******************************************************************************
     89  *
     90  * FUNCTION:    AcpiInitializeTables
     91  *
     92  * PARAMETERS:  InitialTableArray   - Pointer to an array of pre-allocated
     93  *                                    ACPI_TABLE_DESC structures. If NULL, the
     94  *                                    array is dynamically allocated.
     95  *              InitialTableCount   - Size of InitialTableArray, in number of
     96  *                                    ACPI_TABLE_DESC structures
     97  *              AllowRealloc        - Flag to tell Table Manager if resize of
     98  *                                    pre-allocated array is allowed. Ignored
     99  *                                    if InitialTableArray is NULL.
    100  *
    101  * RETURN:      Status
    102  *
    103  * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
    104  *
    105  * NOTE:        Allows static allocation of the initial table array in order
    106  *              to avoid the use of dynamic memory in confined environments
    107  *              such as the kernel boot sequence where it may not be available.
    108  *
    109  *              If the host OS memory managers are initialized, use NULL for
    110  *              InitialTableArray, and the table will be dynamically allocated.
    111  *
    112  ******************************************************************************/
    113 
    114 ACPI_STATUS
    115 AcpiInitializeTables (
    116     ACPI_TABLE_DESC         *InitialTableArray,
    117     UINT32                  InitialTableCount,
    118     BOOLEAN                 AllowResize)
    119 {
    120     ACPI_PHYSICAL_ADDRESS   RsdpAddress;
    121     ACPI_STATUS             Status;
    122 
    123 
    124     ACPI_FUNCTION_TRACE (AcpiInitializeTables);
    125 
    126 
    127     /*
    128      * Set up the Root Table Array
    129      * Allocate the table array if requested
    130      */
    131     if (!InitialTableArray)
    132     {
    133         Status = AcpiAllocateRootTable (InitialTableCount);
    134         if (ACPI_FAILURE (Status))
    135         {
    136             return_ACPI_STATUS (Status);
    137         }
    138     }
    139     else
    140     {
    141         /* Root Table Array has been statically allocated by the host */
    142 
    143         ACPI_MEMSET (InitialTableArray, 0,
    144             (ACPI_SIZE) InitialTableCount * sizeof (ACPI_TABLE_DESC));
    145 
    146         AcpiGbl_RootTableList.Tables = InitialTableArray;
    147         AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
    148         AcpiGbl_RootTableList.Flags = ACPI_ROOT_ORIGIN_UNKNOWN;
    149         if (AllowResize)
    150         {
    151             AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
    152         }
    153     }
    154 
    155     /* Get the address of the RSDP */
    156 
    157     RsdpAddress = AcpiOsGetRootPointer ();
    158     if (!RsdpAddress)
    159     {
    160         return_ACPI_STATUS (AE_NOT_FOUND);
    161     }
    162 
    163     /*
    164      * Get the root table (RSDT or XSDT) and extract all entries to the local
    165      * Root Table Array. This array contains the information of the RSDT/XSDT
    166      * in a common, more useable format.
    167      */
    168     Status = AcpiTbParseRootTable (RsdpAddress);
    169     return_ACPI_STATUS (Status);
    170 }
    171 
    172 ACPI_EXPORT_SYMBOL (AcpiInitializeTables)
    173 
    174 
    175 /*******************************************************************************
    176  *
    177  * FUNCTION:    AcpiReallocateRootTable
    178  *
    179  * PARAMETERS:  None
    180  *
    181  * RETURN:      Status
    182  *
    183  * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
    184  *              root list from the previously provided scratch area. Should
    185  *              be called once dynamic memory allocation is available in the
    186  *              kernel
    187  *
    188  ******************************************************************************/
    189 
    190 ACPI_STATUS
    191 AcpiReallocateRootTable (
    192     void)
    193 {
    194     ACPI_TABLE_DESC         *Tables;
    195     ACPI_SIZE               NewSize;
    196     ACPI_SIZE               CurrentSize;
    197 
    198 
    199     ACPI_FUNCTION_TRACE (AcpiReallocateRootTable);
    200 
    201 
    202     /*
    203      * Only reallocate the root table if the host provided a static buffer
    204      * for the table array in the call to AcpiInitializeTables.
    205      */
    206     if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
    207     {
    208         return_ACPI_STATUS (AE_SUPPORT);
    209     }
    210 
    211     /*
    212      * Get the current size of the root table and add the default
    213      * increment to create the new table size.
    214      */
    215     CurrentSize = (ACPI_SIZE)
    216         AcpiGbl_RootTableList.CurrentTableCount * sizeof (ACPI_TABLE_DESC);
    217 
    218     NewSize = CurrentSize +
    219         (ACPI_ROOT_TABLE_SIZE_INCREMENT * sizeof (ACPI_TABLE_DESC));
    220 
    221     /* Create new array and copy the old array */
    222 
    223     Tables = ACPI_ALLOCATE_ZEROED (NewSize);
    224     if (!Tables)
    225     {
    226         return_ACPI_STATUS (AE_NO_MEMORY);
    227     }
    228 
    229     ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, CurrentSize);
    230 
    231     /*
    232      * Update the root table descriptor. The new size will be the current
    233      * number of tables plus the increment, independent of the reserved
    234      * size of the original table list.
    235      */
    236     AcpiGbl_RootTableList.Tables = Tables;
    237     AcpiGbl_RootTableList.MaxTableCount =
    238         AcpiGbl_RootTableList.CurrentTableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
    239     AcpiGbl_RootTableList.Flags =
    240         ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE;
    241 
    242     return_ACPI_STATUS (AE_OK);
    243 }
    244 
    245 ACPI_EXPORT_SYMBOL (AcpiReallocateRootTable)
    246 
    247 
    248 /*******************************************************************************
    249  *
    250  * FUNCTION:    AcpiGetTableHeader
    251  *
    252  * PARAMETERS:  Signature           - ACPI signature of needed table
    253  *              Instance            - Which instance (for SSDTs)
    254  *              OutTableHeader      - The pointer to the table header to fill
    255  *
    256  * RETURN:      Status and pointer to mapped table header
    257  *
    258  * DESCRIPTION: Finds an ACPI table header.
    259  *
    260  ******************************************************************************/
    261 
    262 ACPI_STATUS
    263 AcpiGetTableHeader (
    264     ACPI_CONST_STRING       Signature,
    265     UINT32                  Instance,
    266     ACPI_TABLE_HEADER       *OutTableHeader)
    267 {
    268     UINT32                  i;
    269     UINT32                  j;
    270     ACPI_TABLE_HEADER       *Header;
    271     ACPI_STRING             USignature = __UNCONST(Signature);
    272 
    273     /* Parameter validation */
    274 
    275     if (!Signature || !OutTableHeader)
    276     {
    277         return (AE_BAD_PARAMETER);
    278     }
    279 
    280     /* Walk the root table list */
    281 
    282     for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
    283     {
    284         if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
    285                     USignature))
    286         {
    287             continue;
    288         }
    289 
    290         if (++j < Instance)
    291         {
    292             continue;
    293         }
    294 
    295         if (!AcpiGbl_RootTableList.Tables[i].Pointer)
    296         {
    297             if ((AcpiGbl_RootTableList.Tables[i].Flags &
    298                     ACPI_TABLE_ORIGIN_MASK) ==
    299                 ACPI_TABLE_ORIGIN_MAPPED)
    300             {
    301                 Header = AcpiOsMapMemory (
    302                             AcpiGbl_RootTableList.Tables[i].Address,
    303                             sizeof (ACPI_TABLE_HEADER));
    304                 if (!Header)
    305                 {
    306                     return AE_NO_MEMORY;
    307                 }
    308 
    309                 ACPI_MEMCPY (OutTableHeader, Header, sizeof(ACPI_TABLE_HEADER));
    310                 AcpiOsUnmapMemory (Header, sizeof(ACPI_TABLE_HEADER));
    311             }
    312             else
    313             {
    314                 return AE_NOT_FOUND;
    315             }
    316         }
    317         else
    318         {
    319             ACPI_MEMCPY (OutTableHeader,
    320                 AcpiGbl_RootTableList.Tables[i].Pointer,
    321                 sizeof(ACPI_TABLE_HEADER));
    322         }
    323 
    324         return (AE_OK);
    325     }
    326 
    327     return (AE_NOT_FOUND);
    328 }
    329 
    330 ACPI_EXPORT_SYMBOL (AcpiGetTableHeader)
    331 
    332 
    333 /*******************************************************************************
    334  *
    335  * FUNCTION:    AcpiGetTable
    336  *
    337  * PARAMETERS:  Signature           - ACPI signature of needed table
    338  *              Instance            - Which instance (for SSDTs)
    339  *              OutTable            - Where the pointer to the table is returned
    340  *
    341  * RETURN:      Status and pointer to table
    342  *
    343  * DESCRIPTION: Finds and verifies an ACPI table.
    344  *
    345  ******************************************************************************/
    346 
    347 ACPI_STATUS
    348 AcpiGetTable (
    349     ACPI_CONST_STRING       Signature,
    350     UINT32                  Instance,
    351     ACPI_TABLE_HEADER       **OutTable)
    352 {
    353     UINT32                  i;
    354     UINT32                  j;
    355     ACPI_STATUS             Status;
    356     ACPI_STRING             USignature = __UNCONST(Signature);
    357 
    358     /* Parameter validation */
    359 
    360     if (!Signature || !OutTable)
    361     {
    362         return (AE_BAD_PARAMETER);
    363     }
    364 
    365     /* Walk the root table list */
    366 
    367     for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
    368     {
    369         if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
    370                 USignature))
    371         {
    372             continue;
    373         }
    374 
    375         if (++j < Instance)
    376         {
    377             continue;
    378         }
    379 
    380         Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
    381         if (ACPI_SUCCESS (Status))
    382         {
    383             *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer;
    384         }
    385 
    386         return (Status);
    387     }
    388 
    389     return (AE_NOT_FOUND);
    390 }
    391 
    392 ACPI_EXPORT_SYMBOL (AcpiGetTable)
    393 
    394 
    395 /*******************************************************************************
    396  *
    397  * FUNCTION:    AcpiGetTableByIndex
    398  *
    399  * PARAMETERS:  TableIndex          - Table index
    400  *              Table               - Where the pointer to the table is returned
    401  *
    402  * RETURN:      Status and pointer to the table
    403  *
    404  * DESCRIPTION: Obtain a table by an index into the global table list.
    405  *
    406  ******************************************************************************/
    407 
    408 ACPI_STATUS
    409 AcpiGetTableByIndex (
    410     UINT32                  TableIndex,
    411     ACPI_TABLE_HEADER       **Table)
    412 {
    413     ACPI_STATUS             Status;
    414 
    415 
    416     ACPI_FUNCTION_TRACE (AcpiGetTableByIndex);
    417 
    418 
    419     /* Parameter validation */
    420 
    421     if (!Table)
    422     {
    423         return_ACPI_STATUS (AE_BAD_PARAMETER);
    424     }
    425 
    426     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    427 
    428     /* Validate index */
    429 
    430     if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
    431     {
    432         (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    433         return_ACPI_STATUS (AE_BAD_PARAMETER);
    434     }
    435 
    436     if (!AcpiGbl_RootTableList.Tables[TableIndex].Pointer)
    437     {
    438         /* Table is not mapped, map it */
    439 
    440         Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[TableIndex]);
    441         if (ACPI_FAILURE (Status))
    442         {
    443             (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    444             return_ACPI_STATUS (Status);
    445         }
    446     }
    447 
    448     *Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer;
    449     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    450     return_ACPI_STATUS (AE_OK);
    451 }
    452 
    453 ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex)
    454 
    455 
    456 /*******************************************************************************
    457  *
    458  * FUNCTION:    AcpiTbLoadNamespace
    459  *
    460  * PARAMETERS:  None
    461  *
    462  * RETURN:      Status
    463  *
    464  * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
    465  *              the RSDT/XSDT.
    466  *
    467  ******************************************************************************/
    468 
    469 static ACPI_STATUS
    470 AcpiTbLoadNamespace (
    471     void)
    472 {
    473     ACPI_STATUS             Status;
    474     UINT32                  i;
    475     ACPI_TABLE_HEADER       *NewDsdt;
    476 
    477 
    478     ACPI_FUNCTION_TRACE (TbLoadNamespace);
    479 
    480 
    481     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    482 
    483     /*
    484      * Load the namespace. The DSDT is required, but any SSDT and
    485      * PSDT tables are optional. Verify the DSDT.
    486      */
    487     if (!AcpiGbl_RootTableList.CurrentTableCount ||
    488         !ACPI_COMPARE_NAME (
    489             &(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature),
    490             ACPI_SIG_DSDT) ||
    491          ACPI_FAILURE (AcpiTbVerifyTable (
    492             &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT])))
    493     {
    494         Status = AE_NO_ACPI_TABLES;
    495         goto UnlockAndExit;
    496     }
    497 
    498     /*
    499      * Save the DSDT pointer for simple access. This is the mapped memory
    500      * address. We must take care here because the address of the .Tables
    501      * array can change dynamically as tables are loaded at run-time. Note:
    502      * .Pointer field is not validated until after call to AcpiTbVerifyTable.
    503      */
    504     AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer;
    505 
    506     /*
    507      * Optionally copy the entire DSDT to local memory (instead of simply
    508      * mapping it.) There are some BIOSs that corrupt or replace the original
    509      * DSDT, creating the need for this option. Default is FALSE, do not copy
    510      * the DSDT.
    511      */
    512     if (AcpiGbl_CopyDsdtLocally)
    513     {
    514         NewDsdt = AcpiTbCopyDsdt (ACPI_TABLE_INDEX_DSDT);
    515         if (NewDsdt)
    516         {
    517             AcpiGbl_DSDT = NewDsdt;
    518         }
    519     }
    520 
    521     /*
    522      * Save the original DSDT header for detection of table corruption
    523      * and/or replacement of the DSDT from outside the OS.
    524      */
    525     ACPI_MEMCPY (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
    526         sizeof (ACPI_TABLE_HEADER));
    527 
    528     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    529 
    530     /* Load and parse tables */
    531 
    532     Status = AcpiNsLoadTable (ACPI_TABLE_INDEX_DSDT, AcpiGbl_RootNode);
    533     if (ACPI_FAILURE (Status))
    534     {
    535         return_ACPI_STATUS (Status);
    536     }
    537 
    538     /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
    539 
    540     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    541     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
    542     {
    543         if ((!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
    544                     ACPI_SIG_SSDT) &&
    545              !ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
    546                     ACPI_SIG_PSDT)) ||
    547              ACPI_FAILURE (AcpiTbVerifyTable (
    548                 &AcpiGbl_RootTableList.Tables[i])))
    549         {
    550             continue;
    551         }
    552 
    553         /* Ignore errors while loading tables, get as many as possible */
    554 
    555         (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    556         (void) AcpiNsLoadTable (i, AcpiGbl_RootNode);
    557         (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    558     }
    559 
    560     ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
    561 
    562 UnlockAndExit:
    563     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    564     return_ACPI_STATUS (Status);
    565 }
    566 
    567 
    568 /*******************************************************************************
    569  *
    570  * FUNCTION:    AcpiLoadTables
    571  *
    572  * PARAMETERS:  None
    573  *
    574  * RETURN:      Status
    575  *
    576  * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
    577  *
    578  ******************************************************************************/
    579 
    580 ACPI_STATUS
    581 AcpiLoadTables (
    582     void)
    583 {
    584     ACPI_STATUS             Status;
    585 
    586 
    587     ACPI_FUNCTION_TRACE (AcpiLoadTables);
    588 
    589 
    590     /* Load the namespace from the tables */
    591 
    592     Status = AcpiTbLoadNamespace ();
    593     if (ACPI_FAILURE (Status))
    594     {
    595         ACPI_EXCEPTION ((AE_INFO, Status,
    596             "While loading namespace from ACPI tables"));
    597     }
    598 
    599     return_ACPI_STATUS (Status);
    600 }
    601 
    602 ACPI_EXPORT_SYMBOL (AcpiLoadTables)
    603 
    604 
    605 /*******************************************************************************
    606  *
    607  * FUNCTION:    AcpiInstallTableHandler
    608  *
    609  * PARAMETERS:  Handler         - Table event handler
    610  *              Context         - Value passed to the handler on each event
    611  *
    612  * RETURN:      Status
    613  *
    614  * DESCRIPTION: Install table event handler
    615  *
    616  ******************************************************************************/
    617 
    618 ACPI_STATUS
    619 AcpiInstallTableHandler (
    620     ACPI_TABLE_HANDLER      Handler,
    621     void                    *Context)
    622 {
    623     ACPI_STATUS             Status;
    624 
    625 
    626     ACPI_FUNCTION_TRACE (AcpiInstallTableHandler);
    627 
    628 
    629     if (!Handler)
    630     {
    631         return_ACPI_STATUS (AE_BAD_PARAMETER);
    632     }
    633 
    634     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    635     if (ACPI_FAILURE (Status))
    636     {
    637         return_ACPI_STATUS (Status);
    638     }
    639 
    640     /* Don't allow more than one handler */
    641 
    642     if (AcpiGbl_TableHandler)
    643     {
    644         Status = AE_ALREADY_EXISTS;
    645         goto Cleanup;
    646     }
    647 
    648     /* Install the handler */
    649 
    650     AcpiGbl_TableHandler = Handler;
    651     AcpiGbl_TableHandlerContext = Context;
    652 
    653 Cleanup:
    654     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    655     return_ACPI_STATUS (Status);
    656 }
    657 
    658 ACPI_EXPORT_SYMBOL (AcpiInstallTableHandler)
    659 
    660 
    661 /*******************************************************************************
    662  *
    663  * FUNCTION:    AcpiRemoveTableHandler
    664  *
    665  * PARAMETERS:  Handler         - Table event handler that was installed
    666  *                                previously.
    667  *
    668  * RETURN:      Status
    669  *
    670  * DESCRIPTION: Remove table event handler
    671  *
    672  ******************************************************************************/
    673 
    674 ACPI_STATUS
    675 AcpiRemoveTableHandler (
    676     ACPI_TABLE_HANDLER      Handler)
    677 {
    678     ACPI_STATUS             Status;
    679 
    680 
    681     ACPI_FUNCTION_TRACE (AcpiRemoveTableHandler);
    682 
    683 
    684     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    685     if (ACPI_FAILURE (Status))
    686     {
    687         return_ACPI_STATUS (Status);
    688     }
    689 
    690     /* Make sure that the installed handler is the same */
    691 
    692     if (!Handler ||
    693         Handler != AcpiGbl_TableHandler)
    694     {
    695         Status = AE_BAD_PARAMETER;
    696         goto Cleanup;
    697     }
    698 
    699     /* Remove the handler */
    700 
    701     AcpiGbl_TableHandler = NULL;
    702 
    703 Cleanup:
    704     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    705     return_ACPI_STATUS (Status);
    706 }
    707 
    708 ACPI_EXPORT_SYMBOL (AcpiRemoveTableHandler)
    709 
    710