Home | History | Annotate | Line # | Download | only in tables
tbinstal.c revision 1.1.1.2.8.2
      1 /******************************************************************************
      2  *
      3  * Module Name: tbinstal - ACPI table installation and removal
      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 __TBINSTAL_C__
     46 
     47 #include "acpi.h"
     48 #include "accommon.h"
     49 #include "acnamesp.h"
     50 #include "actables.h"
     51 
     52 
     53 #define _COMPONENT          ACPI_TABLES
     54         ACPI_MODULE_NAME    ("tbinstal")
     55 
     56 
     57 /******************************************************************************
     58  *
     59  * FUNCTION:    AcpiTbVerifyTable
     60  *
     61  * PARAMETERS:  TableDesc           - table
     62  *
     63  * RETURN:      Status
     64  *
     65  * DESCRIPTION: this function is called to verify and map table
     66  *
     67  *****************************************************************************/
     68 
     69 ACPI_STATUS
     70 AcpiTbVerifyTable (
     71     ACPI_TABLE_DESC         *TableDesc)
     72 {
     73     ACPI_STATUS             Status = AE_OK;
     74 
     75 
     76     ACPI_FUNCTION_TRACE (TbVerifyTable);
     77 
     78 
     79     /* Map the table if necessary */
     80 
     81     if (!TableDesc->Pointer)
     82     {
     83         if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) ==
     84             ACPI_TABLE_ORIGIN_MAPPED)
     85         {
     86             TableDesc->Pointer = AcpiOsMapMemory (
     87                 TableDesc->Address, TableDesc->Length);
     88         }
     89 
     90         if (!TableDesc->Pointer)
     91         {
     92             return_ACPI_STATUS (AE_NO_MEMORY);
     93         }
     94     }
     95 
     96     /* FACS is the odd table, has no standard ACPI header and no checksum */
     97 
     98     if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS))
     99     {
    100         /* Always calculate checksum, ignore bad checksum if requested */
    101 
    102         Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
    103     }
    104 
    105     return_ACPI_STATUS (Status);
    106 }
    107 
    108 
    109 /*******************************************************************************
    110  *
    111  * FUNCTION:    AcpiTbAddTable
    112  *
    113  * PARAMETERS:  TableDesc           - Table descriptor
    114  *              TableIndex          - Where the table index is returned
    115  *
    116  * RETURN:      Status
    117  *
    118  * DESCRIPTION: This function is called to add an ACPI table. It is used to
    119  *              dynamically load tables via the Load and LoadTable AML
    120  *              operators.
    121  *
    122  ******************************************************************************/
    123 
    124 ACPI_STATUS
    125 AcpiTbAddTable (
    126     ACPI_TABLE_DESC         *TableDesc,
    127     UINT32                  *TableIndex)
    128 {
    129     UINT32                  i;
    130     ACPI_STATUS             Status = AE_OK;
    131     ACPI_TABLE_HEADER       *OverrideTable = NULL;
    132 
    133 
    134     ACPI_FUNCTION_TRACE (TbAddTable);
    135 
    136 
    137     if (!TableDesc->Pointer)
    138     {
    139         Status = AcpiTbVerifyTable (TableDesc);
    140         if (ACPI_FAILURE (Status) || !TableDesc->Pointer)
    141         {
    142             return_ACPI_STATUS (Status);
    143         }
    144     }
    145 
    146     /*
    147      * Originally, we checked the table signature for "SSDT" or "PSDT" here.
    148      * Next, we added support for OEMx tables, signature "OEM".
    149      * Valid tables were encountered with a null signature, so we've just
    150      * given up on validating the signature, since it seems to be a waste
    151      * of code. The original code was removed (05/2008).
    152      */
    153 
    154     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    155 
    156     /* Check if table is already registered */
    157 
    158     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
    159     {
    160         if (!AcpiGbl_RootTableList.Tables[i].Pointer)
    161         {
    162             Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
    163             if (ACPI_FAILURE (Status) ||
    164                 !AcpiGbl_RootTableList.Tables[i].Pointer)
    165             {
    166                 continue;
    167             }
    168         }
    169 
    170         /*
    171          * Check for a table match on the entire table length,
    172          * not just the header.
    173          */
    174         if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length)
    175         {
    176             continue;
    177         }
    178 
    179         if (ACPI_MEMCMP (TableDesc->Pointer,
    180                 AcpiGbl_RootTableList.Tables[i].Pointer,
    181                 AcpiGbl_RootTableList.Tables[i].Length))
    182         {
    183             continue;
    184         }
    185 
    186         /*
    187          * Note: the current mechanism does not unregister a table if it is
    188          * dynamically unloaded. The related namespace entries are deleted,
    189          * but the table remains in the root table list.
    190          *
    191          * The assumption here is that the number of different tables that
    192          * will be loaded is actually small, and there is minimal overhead
    193          * in just keeping the table in case it is needed again.
    194          *
    195          * If this assumption changes in the future (perhaps on large
    196          * machines with many table load/unload operations), tables will
    197          * need to be unregistered when they are unloaded, and slots in the
    198          * root table list should be reused when empty.
    199          */
    200 
    201         /*
    202          * Table is already registered.
    203          * We can delete the table that was passed as a parameter.
    204          */
    205         AcpiTbDeleteTable (TableDesc);
    206         *TableIndex = i;
    207 
    208         if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED)
    209         {
    210             /* Table is still loaded, this is an error */
    211 
    212             Status = AE_ALREADY_EXISTS;
    213             goto Release;
    214         }
    215         else
    216         {
    217             /* Table was unloaded, allow it to be reloaded */
    218 
    219             TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer;
    220             TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address;
    221             Status = AE_OK;
    222             goto PrintHeader;
    223         }
    224     }
    225 
    226     /*
    227      * ACPI Table Override:
    228      * Allow the host to override dynamically loaded tables.
    229      */
    230     Status = AcpiOsTableOverride (TableDesc->Pointer, &OverrideTable);
    231     if (ACPI_SUCCESS (Status) && OverrideTable)
    232     {
    233         ACPI_INFO ((AE_INFO,
    234             "%4.4s @ 0x%p Table override, replaced with:",
    235             TableDesc->Pointer->Signature,
    236             ACPI_CAST_PTR (void, TableDesc->Address)));
    237 
    238         /* We can delete the table that was passed as a parameter */
    239 
    240         AcpiTbDeleteTable (TableDesc);
    241 
    242         /* Setup descriptor for the new table */
    243 
    244         TableDesc->Address = ACPI_PTR_TO_PHYSADDR (OverrideTable);
    245         TableDesc->Pointer = OverrideTable;
    246         TableDesc->Length = OverrideTable->Length;
    247         TableDesc->Flags = ACPI_TABLE_ORIGIN_OVERRIDE;
    248     }
    249 
    250     /* Add the table to the global root table list */
    251 
    252     Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer,
    253                 TableDesc->Length, TableDesc->Flags, TableIndex);
    254     if (ACPI_FAILURE (Status))
    255     {
    256         goto Release;
    257     }
    258 
    259 PrintHeader:
    260     AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
    261 
    262 Release:
    263     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    264     return_ACPI_STATUS (Status);
    265 }
    266 
    267 
    268 /*******************************************************************************
    269  *
    270  * FUNCTION:    AcpiTbResizeRootTableList
    271  *
    272  * PARAMETERS:  None
    273  *
    274  * RETURN:      Status
    275  *
    276  * DESCRIPTION: Expand the size of global table array
    277  *
    278  ******************************************************************************/
    279 
    280 ACPI_STATUS
    281 AcpiTbResizeRootTableList (
    282     void)
    283 {
    284     ACPI_TABLE_DESC         *Tables;
    285 
    286 
    287     ACPI_FUNCTION_TRACE (TbResizeRootTableList);
    288 
    289 
    290     /* AllowResize flag is a parameter to AcpiInitializeTables */
    291 
    292     if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
    293     {
    294         ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
    295         return_ACPI_STATUS (AE_SUPPORT);
    296     }
    297 
    298     /* Increase the Table Array size */
    299 
    300     Tables = ACPI_ALLOCATE_ZEROED (
    301         ((ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount +
    302             ACPI_ROOT_TABLE_SIZE_INCREMENT) *
    303         sizeof (ACPI_TABLE_DESC));
    304     if (!Tables)
    305     {
    306         ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
    307         return_ACPI_STATUS (AE_NO_MEMORY);
    308     }
    309 
    310     /* Copy and free the previous table array */
    311 
    312     if (AcpiGbl_RootTableList.Tables)
    313     {
    314         ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables,
    315             (ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount * sizeof (ACPI_TABLE_DESC));
    316 
    317         if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
    318         {
    319             ACPI_FREE (AcpiGbl_RootTableList.Tables);
    320         }
    321     }
    322 
    323     AcpiGbl_RootTableList.Tables = Tables;
    324     AcpiGbl_RootTableList.MaxTableCount += ACPI_ROOT_TABLE_SIZE_INCREMENT;
    325     AcpiGbl_RootTableList.Flags |= (UINT8) ACPI_ROOT_ORIGIN_ALLOCATED;
    326 
    327     return_ACPI_STATUS (AE_OK);
    328 }
    329 
    330 
    331 /*******************************************************************************
    332  *
    333  * FUNCTION:    AcpiTbStoreTable
    334  *
    335  * PARAMETERS:  Address             - Table address
    336  *              Table               - Table header
    337  *              Length              - Table length
    338  *              Flags               - flags
    339  *
    340  * RETURN:      Status and table index.
    341  *
    342  * DESCRIPTION: Add an ACPI table to the global table list
    343  *
    344  ******************************************************************************/
    345 
    346 ACPI_STATUS
    347 AcpiTbStoreTable (
    348     ACPI_PHYSICAL_ADDRESS   Address,
    349     ACPI_TABLE_HEADER       *Table,
    350     UINT32                  Length,
    351     UINT8                   Flags,
    352     UINT32                  *TableIndex)
    353 {
    354     ACPI_STATUS             Status;
    355     ACPI_TABLE_DESC         *NewTable;
    356 
    357 
    358     /* Ensure that there is room for the table in the Root Table List */
    359 
    360     if (AcpiGbl_RootTableList.CurrentTableCount >=
    361         AcpiGbl_RootTableList.MaxTableCount)
    362     {
    363         Status = AcpiTbResizeRootTableList();
    364         if (ACPI_FAILURE (Status))
    365         {
    366             return (Status);
    367         }
    368     }
    369 
    370     NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount];
    371 
    372     /* Initialize added table */
    373 
    374     NewTable->Address = Address;
    375     NewTable->Pointer = Table;
    376     NewTable->Length = Length;
    377     NewTable->OwnerId = 0;
    378     NewTable->Flags = Flags;
    379 
    380     ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature);
    381 
    382     *TableIndex = AcpiGbl_RootTableList.CurrentTableCount;
    383     AcpiGbl_RootTableList.CurrentTableCount++;
    384     return (AE_OK);
    385 }
    386 
    387 
    388 /*******************************************************************************
    389  *
    390  * FUNCTION:    AcpiTbDeleteTable
    391  *
    392  * PARAMETERS:  TableIndex          - Table index
    393  *
    394  * RETURN:      None
    395  *
    396  * DESCRIPTION: Delete one internal ACPI table
    397  *
    398  ******************************************************************************/
    399 
    400 void
    401 AcpiTbDeleteTable (
    402     ACPI_TABLE_DESC         *TableDesc)
    403 {
    404 
    405     /* Table must be mapped or allocated */
    406 
    407     if (!TableDesc->Pointer)
    408     {
    409         return;
    410     }
    411 
    412     switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
    413     {
    414     case ACPI_TABLE_ORIGIN_MAPPED:
    415         AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length);
    416         break;
    417 
    418     case ACPI_TABLE_ORIGIN_ALLOCATED:
    419         ACPI_FREE (TableDesc->Pointer);
    420         break;
    421 
    422     default:
    423         break;
    424     }
    425 
    426     TableDesc->Pointer = NULL;
    427 }
    428 
    429 
    430 /*******************************************************************************
    431  *
    432  * FUNCTION:    AcpiTbTerminate
    433  *
    434  * PARAMETERS:  None
    435  *
    436  * RETURN:      None
    437  *
    438  * DESCRIPTION: Delete all internal ACPI tables
    439  *
    440  ******************************************************************************/
    441 
    442 void
    443 AcpiTbTerminate (
    444     void)
    445 {
    446     UINT32                  i;
    447 
    448 
    449     ACPI_FUNCTION_TRACE (TbTerminate);
    450 
    451 
    452     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    453 
    454     /* Delete the individual tables */
    455 
    456     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
    457     {
    458         AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]);
    459     }
    460 
    461     /*
    462      * Delete the root table array if allocated locally. Array cannot be
    463      * mapped, so we don't need to check for that flag.
    464      */
    465     if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
    466     {
    467         ACPI_FREE (AcpiGbl_RootTableList.Tables);
    468     }
    469 
    470     AcpiGbl_RootTableList.Tables = NULL;
    471     AcpiGbl_RootTableList.Flags = 0;
    472     AcpiGbl_RootTableList.CurrentTableCount = 0;
    473 
    474     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
    475     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    476 }
    477 
    478 
    479 /*******************************************************************************
    480  *
    481  * FUNCTION:    AcpiTbDeleteNamespaceByOwner
    482  *
    483  * PARAMETERS:  TableIndex          - Table index
    484  *
    485  * RETURN:      Status
    486  *
    487  * DESCRIPTION: Delete all namespace objects created when this table was loaded.
    488  *
    489  ******************************************************************************/
    490 
    491 ACPI_STATUS
    492 AcpiTbDeleteNamespaceByOwner (
    493     UINT32                  TableIndex)
    494 {
    495     ACPI_OWNER_ID           OwnerId;
    496     ACPI_STATUS             Status;
    497 
    498 
    499     ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
    500 
    501 
    502     Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    503     if (ACPI_FAILURE (Status))
    504     {
    505         return_ACPI_STATUS (Status);
    506     }
    507 
    508     if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
    509     {
    510         /* The table index does not exist */
    511 
    512         (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    513         return_ACPI_STATUS (AE_NOT_EXIST);
    514     }
    515 
    516     /* Get the owner ID for this table, used to delete namespace nodes */
    517 
    518     OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
    519     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    520 
    521     /*
    522      * Need to acquire the namespace writer lock to prevent interference
    523      * with any concurrent namespace walks. The interpreter must be
    524      * released during the deletion since the acquisition of the deletion
    525      * lock may block, and also since the execution of a namespace walk
    526      * must be allowed to use the interpreter.
    527      */
    528     (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
    529     Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
    530 
    531     AcpiNsDeleteNamespaceByOwner (OwnerId);
    532     if (ACPI_FAILURE (Status))
    533     {
    534         return_ACPI_STATUS (Status);
    535     }
    536 
    537     AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
    538 
    539     Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
    540     return_ACPI_STATUS (Status);
    541 }
    542 
    543 
    544 /*******************************************************************************
    545  *
    546  * FUNCTION:    AcpiTbAllocateOwnerId
    547  *
    548  * PARAMETERS:  TableIndex          - Table index
    549  *
    550  * RETURN:      Status
    551  *
    552  * DESCRIPTION: Allocates OwnerId in TableDesc
    553  *
    554  ******************************************************************************/
    555 
    556 ACPI_STATUS
    557 AcpiTbAllocateOwnerId (
    558     UINT32                  TableIndex)
    559 {
    560     ACPI_STATUS             Status = AE_BAD_PARAMETER;
    561 
    562 
    563     ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
    564 
    565 
    566     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    567     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
    568     {
    569         Status = AcpiUtAllocateOwnerId
    570                     (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
    571     }
    572 
    573     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    574     return_ACPI_STATUS (Status);
    575 }
    576 
    577 
    578 /*******************************************************************************
    579  *
    580  * FUNCTION:    AcpiTbReleaseOwnerId
    581  *
    582  * PARAMETERS:  TableIndex          - Table index
    583  *
    584  * RETURN:      Status
    585  *
    586  * DESCRIPTION: Releases OwnerId in TableDesc
    587  *
    588  ******************************************************************************/
    589 
    590 ACPI_STATUS
    591 AcpiTbReleaseOwnerId (
    592     UINT32                  TableIndex)
    593 {
    594     ACPI_STATUS             Status = AE_BAD_PARAMETER;
    595 
    596 
    597     ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
    598 
    599 
    600     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    601     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
    602     {
    603         AcpiUtReleaseOwnerId (
    604             &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
    605         Status = AE_OK;
    606     }
    607 
    608     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    609     return_ACPI_STATUS (Status);
    610 }
    611 
    612 
    613 /*******************************************************************************
    614  *
    615  * FUNCTION:    AcpiTbGetOwnerId
    616  *
    617  * PARAMETERS:  TableIndex          - Table index
    618  *              OwnerId             - Where the table OwnerId is returned
    619  *
    620  * RETURN:      Status
    621  *
    622  * DESCRIPTION: returns OwnerId for the ACPI table
    623  *
    624  ******************************************************************************/
    625 
    626 ACPI_STATUS
    627 AcpiTbGetOwnerId (
    628     UINT32                  TableIndex,
    629     ACPI_OWNER_ID           *OwnerId)
    630 {
    631     ACPI_STATUS             Status = AE_BAD_PARAMETER;
    632 
    633 
    634     ACPI_FUNCTION_TRACE (TbGetOwnerId);
    635 
    636 
    637     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    638     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
    639     {
    640         *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
    641         Status = AE_OK;
    642     }
    643 
    644     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    645     return_ACPI_STATUS (Status);
    646 }
    647 
    648 
    649 /*******************************************************************************
    650  *
    651  * FUNCTION:    AcpiTbIsTableLoaded
    652  *
    653  * PARAMETERS:  TableIndex          - Table index
    654  *
    655  * RETURN:      Table Loaded Flag
    656  *
    657  ******************************************************************************/
    658 
    659 BOOLEAN
    660 AcpiTbIsTableLoaded (
    661     UINT32                  TableIndex)
    662 {
    663     BOOLEAN                 IsLoaded = FALSE;
    664 
    665 
    666     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    667     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
    668     {
    669         IsLoaded = (BOOLEAN)
    670             (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
    671             ACPI_TABLE_IS_LOADED);
    672     }
    673 
    674     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    675     return (IsLoaded);
    676 }
    677 
    678 
    679 /*******************************************************************************
    680  *
    681  * FUNCTION:    AcpiTbSetTableLoadedFlag
    682  *
    683  * PARAMETERS:  TableIndex          - Table index
    684  *              IsLoaded            - TRUE if table is loaded, FALSE otherwise
    685  *
    686  * RETURN:      None
    687  *
    688  * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
    689  *
    690  ******************************************************************************/
    691 
    692 void
    693 AcpiTbSetTableLoadedFlag (
    694     UINT32                  TableIndex,
    695     BOOLEAN                 IsLoaded)
    696 {
    697 
    698     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
    699     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
    700     {
    701         if (IsLoaded)
    702         {
    703             AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
    704                 ACPI_TABLE_IS_LOADED;
    705         }
    706         else
    707         {
    708             AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
    709                 ~ACPI_TABLE_IS_LOADED;
    710         }
    711     }
    712 
    713     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
    714 }
    715 
    716