195b482a8SLen Brown /****************************************************************************** 295b482a8SLen Brown * 395b482a8SLen Brown * Module Name: tbinstal - ACPI table installation and removal 495b482a8SLen Brown * 595b482a8SLen Brown *****************************************************************************/ 695b482a8SLen Brown 795b482a8SLen Brown /* 8fbb7a2dcSBob Moore * Copyright (C) 2000 - 2014, Intel Corp. 995b482a8SLen Brown * All rights reserved. 1095b482a8SLen Brown * 1195b482a8SLen Brown * Redistribution and use in source and binary forms, with or without 1295b482a8SLen Brown * modification, are permitted provided that the following conditions 1395b482a8SLen Brown * are met: 1495b482a8SLen Brown * 1. Redistributions of source code must retain the above copyright 1595b482a8SLen Brown * notice, this list of conditions, and the following disclaimer, 1695b482a8SLen Brown * without modification. 1795b482a8SLen Brown * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1895b482a8SLen Brown * substantially similar to the "NO WARRANTY" disclaimer below 1995b482a8SLen Brown * ("Disclaimer") and any redistribution must be conditioned upon 2095b482a8SLen Brown * including a substantially similar Disclaimer requirement for further 2195b482a8SLen Brown * binary redistribution. 2295b482a8SLen Brown * 3. Neither the names of the above-listed copyright holders nor the names 2395b482a8SLen Brown * of any contributors may be used to endorse or promote products derived 2495b482a8SLen Brown * from this software without specific prior written permission. 2595b482a8SLen Brown * 2695b482a8SLen Brown * Alternatively, this software may be distributed under the terms of the 2795b482a8SLen Brown * GNU General Public License ("GPL") version 2 as published by the Free 2895b482a8SLen Brown * Software Foundation. 2995b482a8SLen Brown * 3095b482a8SLen Brown * NO WARRANTY 3195b482a8SLen Brown * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3295b482a8SLen Brown * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3395b482a8SLen Brown * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3495b482a8SLen Brown * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3595b482a8SLen Brown * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3695b482a8SLen Brown * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3795b482a8SLen Brown * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3895b482a8SLen Brown * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3995b482a8SLen Brown * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4095b482a8SLen Brown * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4195b482a8SLen Brown * POSSIBILITY OF SUCH DAMAGES. 4295b482a8SLen Brown */ 4395b482a8SLen Brown 4495b482a8SLen Brown #include <acpi/acpi.h> 45e2f7a777SLen Brown #include "accommon.h" 46e2f7a777SLen Brown #include "acnamesp.h" 47e2f7a777SLen Brown #include "actables.h" 4895b482a8SLen Brown 4995b482a8SLen Brown #define _COMPONENT ACPI_TABLES 5095b482a8SLen Brown ACPI_MODULE_NAME("tbinstal") 5195b482a8SLen Brown 52*7f9fc99cSLv Zheng /******************************************************************************* 5395b482a8SLen Brown * 54*7f9fc99cSLv Zheng * FUNCTION: acpi_tb_acquire_table 5595b482a8SLen Brown * 56*7f9fc99cSLv Zheng * PARAMETERS: table_desc - Table descriptor 57*7f9fc99cSLv Zheng * table_ptr - Where table is returned 58*7f9fc99cSLv Zheng * table_length - Where table length is returned 59*7f9fc99cSLv Zheng * table_flags - Where table allocation flags are returned 6095b482a8SLen Brown * 6195b482a8SLen Brown * RETURN: Status 6295b482a8SLen Brown * 63*7f9fc99cSLv Zheng * DESCRIPTION: Acquire a table. It can be used for tables not maintained in 64*7f9fc99cSLv Zheng * acpi_gbl_root_table_list. 6595b482a8SLen Brown * 66*7f9fc99cSLv Zheng ******************************************************************************/ 67*7f9fc99cSLv Zheng acpi_status 68*7f9fc99cSLv Zheng acpi_tb_acquire_table(struct acpi_table_desc *table_desc, 69*7f9fc99cSLv Zheng struct acpi_table_header **table_ptr, 70*7f9fc99cSLv Zheng u32 *table_length, u8 *table_flags) 7195b482a8SLen Brown { 72*7f9fc99cSLv Zheng struct acpi_table_header *table = NULL; 7395b482a8SLen Brown 74dc156adfSLv Zheng switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { 75dc156adfSLv Zheng case ACPI_TABLE_ORIGIN_MAPPED: 76dc156adfSLv Zheng 77*7f9fc99cSLv Zheng table = 78*7f9fc99cSLv Zheng acpi_os_map_memory(table_desc->address, table_desc->length); 79dc156adfSLv Zheng break; 80dc156adfSLv Zheng 81dc156adfSLv Zheng case ACPI_TABLE_ORIGIN_ALLOCATED: 82dc156adfSLv Zheng case ACPI_TABLE_ORIGIN_UNKNOWN: 83dc156adfSLv Zheng case ACPI_TABLE_ORIGIN_OVERRIDE: 84dc156adfSLv Zheng 85*7f9fc99cSLv Zheng table = 86dc156adfSLv Zheng ACPI_CAST_PTR(struct acpi_table_header, 87dc156adfSLv Zheng table_desc->address); 88dc156adfSLv Zheng break; 89dc156adfSLv Zheng 90dc156adfSLv Zheng default: 91dc156adfSLv Zheng 92dc156adfSLv Zheng break; 9395b482a8SLen Brown } 945582982dSLv Zheng 95*7f9fc99cSLv Zheng /* Table is not valid yet */ 96*7f9fc99cSLv Zheng 97*7f9fc99cSLv Zheng if (!table) { 98*7f9fc99cSLv Zheng return (AE_NO_MEMORY); 99*7f9fc99cSLv Zheng } 100*7f9fc99cSLv Zheng 101*7f9fc99cSLv Zheng /* Fill the return values */ 102*7f9fc99cSLv Zheng 103*7f9fc99cSLv Zheng *table_ptr = table; 104*7f9fc99cSLv Zheng *table_length = table_desc->length; 105*7f9fc99cSLv Zheng *table_flags = table_desc->flags; 106*7f9fc99cSLv Zheng 107*7f9fc99cSLv Zheng return (AE_OK); 108*7f9fc99cSLv Zheng } 109*7f9fc99cSLv Zheng 110*7f9fc99cSLv Zheng /******************************************************************************* 111*7f9fc99cSLv Zheng * 112*7f9fc99cSLv Zheng * FUNCTION: acpi_tb_release_table 113*7f9fc99cSLv Zheng * 114*7f9fc99cSLv Zheng * PARAMETERS: table - Pointer for the table 115*7f9fc99cSLv Zheng * table_length - Length for the table 116*7f9fc99cSLv Zheng * table_flags - Allocation flags for the table 117*7f9fc99cSLv Zheng * 118*7f9fc99cSLv Zheng * RETURN: None 119*7f9fc99cSLv Zheng * 120*7f9fc99cSLv Zheng * DESCRIPTION: Release a table. The reversal of acpi_tb_acquire_table(). 121*7f9fc99cSLv Zheng * 122*7f9fc99cSLv Zheng ******************************************************************************/ 123*7f9fc99cSLv Zheng 124*7f9fc99cSLv Zheng void 125*7f9fc99cSLv Zheng acpi_tb_release_table(struct acpi_table_header *table, 126*7f9fc99cSLv Zheng u32 table_length, u8 table_flags) 127*7f9fc99cSLv Zheng { 128*7f9fc99cSLv Zheng switch (table_flags & ACPI_TABLE_ORIGIN_MASK) { 129*7f9fc99cSLv Zheng case ACPI_TABLE_ORIGIN_MAPPED: 130*7f9fc99cSLv Zheng 131*7f9fc99cSLv Zheng acpi_os_unmap_memory(table, table_length); 132*7f9fc99cSLv Zheng break; 133*7f9fc99cSLv Zheng 134*7f9fc99cSLv Zheng case ACPI_TABLE_ORIGIN_ALLOCATED: 135*7f9fc99cSLv Zheng case ACPI_TABLE_ORIGIN_UNKNOWN: 136*7f9fc99cSLv Zheng case ACPI_TABLE_ORIGIN_OVERRIDE: 137*7f9fc99cSLv Zheng default: 138*7f9fc99cSLv Zheng 139*7f9fc99cSLv Zheng break; 140*7f9fc99cSLv Zheng } 141*7f9fc99cSLv Zheng } 142*7f9fc99cSLv Zheng 143*7f9fc99cSLv Zheng /****************************************************************************** 144*7f9fc99cSLv Zheng * 145*7f9fc99cSLv Zheng * FUNCTION: acpi_tb_validate_table 146*7f9fc99cSLv Zheng * 147*7f9fc99cSLv Zheng * PARAMETERS: table_desc - Table descriptor 148*7f9fc99cSLv Zheng * 149*7f9fc99cSLv Zheng * RETURN: Status 150*7f9fc99cSLv Zheng * 151*7f9fc99cSLv Zheng * DESCRIPTION: This function is called to validate (ensure Pointer is valid) 152*7f9fc99cSLv Zheng * and verify the table. 153*7f9fc99cSLv Zheng * 154*7f9fc99cSLv Zheng *****************************************************************************/ 155*7f9fc99cSLv Zheng 156*7f9fc99cSLv Zheng acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc) 157*7f9fc99cSLv Zheng { 158*7f9fc99cSLv Zheng acpi_status status = AE_OK; 159*7f9fc99cSLv Zheng 160*7f9fc99cSLv Zheng ACPI_FUNCTION_TRACE(tb_validate_table); 161*7f9fc99cSLv Zheng 162*7f9fc99cSLv Zheng /* Validate the table if necessary */ 163*7f9fc99cSLv Zheng 16495b482a8SLen Brown if (!table_desc->pointer) { 165*7f9fc99cSLv Zheng status = acpi_tb_acquire_table(table_desc, &table_desc->pointer, 166*7f9fc99cSLv Zheng &table_desc->length, 167*7f9fc99cSLv Zheng &table_desc->flags); 168*7f9fc99cSLv Zheng if (ACPI_FAILURE(status) || !table_desc->pointer) { 16995b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY); 17095b482a8SLen Brown } 17195b482a8SLen Brown } 17295b482a8SLen Brown 17395b482a8SLen Brown /* Always calculate checksum, ignore bad checksum if requested */ 17495b482a8SLen Brown 17595b482a8SLen Brown status = 17694d4be67SLv Zheng acpi_tb_verify_checksum(table_desc->pointer, table_desc->length); 17795b482a8SLen Brown 17895b482a8SLen Brown return_ACPI_STATUS(status); 17995b482a8SLen Brown } 18095b482a8SLen Brown 18195b482a8SLen Brown /******************************************************************************* 18295b482a8SLen Brown * 183*7f9fc99cSLv Zheng * FUNCTION: acpi_tb_invalidate_table 184*7f9fc99cSLv Zheng * 185*7f9fc99cSLv Zheng * PARAMETERS: table_desc - Table descriptor 186*7f9fc99cSLv Zheng * 187*7f9fc99cSLv Zheng * RETURN: None 188*7f9fc99cSLv Zheng * 189*7f9fc99cSLv Zheng * DESCRIPTION: Invalidate one internal ACPI table, this is reversal of 190*7f9fc99cSLv Zheng * acpi_tb_validate_table(). 191*7f9fc99cSLv Zheng * 192*7f9fc99cSLv Zheng ******************************************************************************/ 193*7f9fc99cSLv Zheng 194*7f9fc99cSLv Zheng void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc) 195*7f9fc99cSLv Zheng { 196*7f9fc99cSLv Zheng 197*7f9fc99cSLv Zheng ACPI_FUNCTION_TRACE(tb_invalidate_table); 198*7f9fc99cSLv Zheng 199*7f9fc99cSLv Zheng /* Table must be validated */ 200*7f9fc99cSLv Zheng 201*7f9fc99cSLv Zheng if (!table_desc->pointer) { 202*7f9fc99cSLv Zheng return_VOID; 203*7f9fc99cSLv Zheng } 204*7f9fc99cSLv Zheng 205*7f9fc99cSLv Zheng acpi_tb_release_table(table_desc->pointer, table_desc->length, 206*7f9fc99cSLv Zheng table_desc->flags); 207*7f9fc99cSLv Zheng table_desc->pointer = NULL; 208*7f9fc99cSLv Zheng 209*7f9fc99cSLv Zheng return_VOID; 210*7f9fc99cSLv Zheng } 211*7f9fc99cSLv Zheng 212*7f9fc99cSLv Zheng /******************************************************************************* 213*7f9fc99cSLv Zheng * 21495b482a8SLen Brown * FUNCTION: acpi_tb_add_table 21595b482a8SLen Brown * 21695b482a8SLen Brown * PARAMETERS: table_desc - Table descriptor 21795b482a8SLen Brown * table_index - Where the table index is returned 21895b482a8SLen Brown * 21995b482a8SLen Brown * RETURN: Status 22095b482a8SLen Brown * 221d3ccaff8SBob Moore * DESCRIPTION: This function is called to add an ACPI table. It is used to 222d3ccaff8SBob Moore * dynamically load tables via the Load and load_table AML 223d3ccaff8SBob Moore * operators. 22495b482a8SLen Brown * 22595b482a8SLen Brown ******************************************************************************/ 22695b482a8SLen Brown 22795b482a8SLen Brown acpi_status 22895b482a8SLen Brown acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) 22995b482a8SLen Brown { 23095b482a8SLen Brown u32 i; 23195b482a8SLen Brown acpi_status status = AE_OK; 232*7f9fc99cSLv Zheng struct acpi_table_header *final_table; 23395b482a8SLen Brown 23495b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_add_table); 23595b482a8SLen Brown 23695b482a8SLen Brown if (!table_desc->pointer) { 237*7f9fc99cSLv Zheng status = acpi_tb_validate_table(table_desc); 23895b482a8SLen Brown if (ACPI_FAILURE(status) || !table_desc->pointer) { 23995b482a8SLen Brown return_ACPI_STATUS(status); 24095b482a8SLen Brown } 24195b482a8SLen Brown } 24295b482a8SLen Brown 24395b482a8SLen Brown /* 244c8cefe30SBob Moore * Validate the incoming table signature. 245c8cefe30SBob Moore * 246c8cefe30SBob Moore * 1) Originally, we checked the table signature for "SSDT" or "PSDT". 247c8cefe30SBob Moore * 2) We added support for OEMx tables, signature "OEM". 248c8cefe30SBob Moore * 3) Valid tables were encountered with a null signature, so we just 249c8cefe30SBob Moore * gave up on validating the signature, (05/2008). 250c8cefe30SBob Moore * 4) We encountered non-AML tables such as the MADT, which caused 251c8cefe30SBob Moore * interpreter errors and kernel faults. So now, we once again allow 252c8cefe30SBob Moore * only "SSDT", "OEMx", and now, also a null signature. (05/2011). 25395b482a8SLen Brown */ 254c8cefe30SBob Moore if ((table_desc->pointer->signature[0] != 0x00) && 255c8cefe30SBob Moore (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)) 256c8cefe30SBob Moore && (ACPI_STRNCMP(table_desc->pointer->signature, "OEM", 3))) { 2573b3ea775SBob Moore ACPI_BIOS_ERROR((AE_INFO, 2583b3ea775SBob Moore "Table has invalid signature [%4.4s] (0x%8.8X), " 2593b3ea775SBob Moore "must be SSDT or OEMx", 260de8e7db7SBob Moore acpi_ut_valid_acpi_name(table_desc->pointer-> 2613b3ea775SBob Moore signature) ? 2623b3ea775SBob Moore table_desc->pointer->signature : "????", 263c8cefe30SBob Moore *(u32 *)table_desc->pointer->signature)); 264c8cefe30SBob Moore 265c8cefe30SBob Moore return_ACPI_STATUS(AE_BAD_SIGNATURE); 266c8cefe30SBob Moore } 26795b482a8SLen Brown 26895b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 26995b482a8SLen Brown 27095b482a8SLen Brown /* Check if table is already registered */ 27195b482a8SLen Brown 272b9ee2043SBob Moore for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { 27395b482a8SLen Brown if (!acpi_gbl_root_table_list.tables[i].pointer) { 27495b482a8SLen Brown status = 275*7f9fc99cSLv Zheng acpi_tb_validate_table(&acpi_gbl_root_table_list. 27695b482a8SLen Brown tables[i]); 27795b482a8SLen Brown if (ACPI_FAILURE(status) 27895b482a8SLen Brown || !acpi_gbl_root_table_list.tables[i].pointer) { 27995b482a8SLen Brown continue; 28095b482a8SLen Brown } 28195b482a8SLen Brown } 28295b482a8SLen Brown 28395b482a8SLen Brown /* 28495b482a8SLen Brown * Check for a table match on the entire table length, 28595b482a8SLen Brown * not just the header. 28695b482a8SLen Brown */ 28795b482a8SLen Brown if (table_desc->length != 28895b482a8SLen Brown acpi_gbl_root_table_list.tables[i].length) { 28995b482a8SLen Brown continue; 29095b482a8SLen Brown } 29195b482a8SLen Brown 29295b482a8SLen Brown if (ACPI_MEMCMP(table_desc->pointer, 29395b482a8SLen Brown acpi_gbl_root_table_list.tables[i].pointer, 29495b482a8SLen Brown acpi_gbl_root_table_list.tables[i].length)) { 29595b482a8SLen Brown continue; 29695b482a8SLen Brown } 29795b482a8SLen Brown 29895b482a8SLen Brown /* 29995b482a8SLen Brown * Note: the current mechanism does not unregister a table if it is 30095b482a8SLen Brown * dynamically unloaded. The related namespace entries are deleted, 30195b482a8SLen Brown * but the table remains in the root table list. 30295b482a8SLen Brown * 30395b482a8SLen Brown * The assumption here is that the number of different tables that 30495b482a8SLen Brown * will be loaded is actually small, and there is minimal overhead 30595b482a8SLen Brown * in just keeping the table in case it is needed again. 30695b482a8SLen Brown * 30795b482a8SLen Brown * If this assumption changes in the future (perhaps on large 30895b482a8SLen Brown * machines with many table load/unload operations), tables will 30995b482a8SLen Brown * need to be unregistered when they are unloaded, and slots in the 31095b482a8SLen Brown * root table list should be reused when empty. 31195b482a8SLen Brown */ 31295b482a8SLen Brown *table_index = i; 31395b482a8SLen Brown 31495b482a8SLen Brown if (acpi_gbl_root_table_list.tables[i]. 31595b482a8SLen Brown flags & ACPI_TABLE_IS_LOADED) { 31695b482a8SLen Brown 31795b482a8SLen Brown /* Table is still loaded, this is an error */ 31895b482a8SLen Brown 31995b482a8SLen Brown status = AE_ALREADY_EXISTS; 32095b482a8SLen Brown goto release; 32195b482a8SLen Brown } else { 32295b482a8SLen Brown /* Table was unloaded, allow it to be reloaded */ 32395b482a8SLen Brown 324*7f9fc99cSLv Zheng acpi_tb_uninstall_table(table_desc); 32595b482a8SLen Brown table_desc->pointer = 32695b482a8SLen Brown acpi_gbl_root_table_list.tables[i].pointer; 32795b482a8SLen Brown table_desc->address = 32895b482a8SLen Brown acpi_gbl_root_table_list.tables[i].address; 32995b482a8SLen Brown status = AE_OK; 33095b482a8SLen Brown goto print_header; 33195b482a8SLen Brown } 33295b482a8SLen Brown } 33395b482a8SLen Brown 334d3ccaff8SBob Moore /* 335d3ccaff8SBob Moore * ACPI Table Override: 336d3ccaff8SBob Moore * Allow the host to override dynamically loaded tables. 337f7b004a1SBob Moore * NOTE: the table is fully mapped at this point, and the mapping will 338*7f9fc99cSLv Zheng * be deleted by acpi_tb_override_table if the table is actually overridden. 339d3ccaff8SBob Moore */ 340*7f9fc99cSLv Zheng final_table = acpi_tb_override_table(table_desc->pointer, table_desc); 341*7f9fc99cSLv Zheng if (final_table) { 342*7f9fc99cSLv Zheng 343*7f9fc99cSLv Zheng /* Ensure table descriptor is in "VALIDATED" state */ 344*7f9fc99cSLv Zheng 345*7f9fc99cSLv Zheng table_desc->pointer = final_table; 346*7f9fc99cSLv Zheng } 347d3ccaff8SBob Moore 34895b482a8SLen Brown /* Add the table to the global root table list */ 34995b482a8SLen Brown 35095b482a8SLen Brown status = acpi_tb_store_table(table_desc->address, table_desc->pointer, 35195b482a8SLen Brown table_desc->length, table_desc->flags, 35295b482a8SLen Brown table_index); 35395b482a8SLen Brown if (ACPI_FAILURE(status)) { 35495b482a8SLen Brown goto release; 35595b482a8SLen Brown } 35695b482a8SLen Brown 35795b482a8SLen Brown print_header: 35895b482a8SLen Brown acpi_tb_print_table_header(table_desc->address, table_desc->pointer); 35995b482a8SLen Brown 36095b482a8SLen Brown release: 36195b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 36295b482a8SLen Brown return_ACPI_STATUS(status); 36395b482a8SLen Brown } 36495b482a8SLen Brown 36595b482a8SLen Brown /******************************************************************************* 36695b482a8SLen Brown * 367*7f9fc99cSLv Zheng * FUNCTION: acpi_tb_override_table 368f7b004a1SBob Moore * 369f7b004a1SBob Moore * PARAMETERS: table_header - Header for the original table 370f7b004a1SBob Moore * table_desc - Table descriptor initialized for the 371f7b004a1SBob Moore * original table. May or may not be mapped. 372f7b004a1SBob Moore * 373f7b004a1SBob Moore * RETURN: Pointer to the entire new table. NULL if table not overridden. 374f7b004a1SBob Moore * If overridden, installs the new table within the input table 375f7b004a1SBob Moore * descriptor. 376f7b004a1SBob Moore * 377f7b004a1SBob Moore * DESCRIPTION: Attempt table override by calling the OSL override functions. 378f7b004a1SBob Moore * Note: If the table is overridden, then the entire new table 379*7f9fc99cSLv Zheng * is acquired and returned by this function. 380*7f9fc99cSLv Zheng * After invocation, the table descriptor is in a state that is 381*7f9fc99cSLv Zheng * "INSTALLED" but not "VALIDATED", thus the "Pointer" member is 382*7f9fc99cSLv Zheng * kept NULL. 383f7b004a1SBob Moore * 384f7b004a1SBob Moore ******************************************************************************/ 385f7b004a1SBob Moore 386*7f9fc99cSLv Zheng struct acpi_table_header *acpi_tb_override_table(struct acpi_table_header 387f7b004a1SBob Moore *table_header, 388f7b004a1SBob Moore struct acpi_table_desc 389f7b004a1SBob Moore *table_desc) 390f7b004a1SBob Moore { 391f7b004a1SBob Moore acpi_status status; 392*7f9fc99cSLv Zheng struct acpi_table_header *new_table; 393*7f9fc99cSLv Zheng u32 new_table_length; 394f7b004a1SBob Moore u8 new_flags; 395f7b004a1SBob Moore char *override_type; 396*7f9fc99cSLv Zheng struct acpi_table_desc new_table_desc; 397*7f9fc99cSLv Zheng 398*7f9fc99cSLv Zheng ACPI_MEMSET(&new_table_desc, 0, sizeof(struct acpi_table_desc)); 399f7b004a1SBob Moore 400f7b004a1SBob Moore /* (1) Attempt logical override (returns a logical address) */ 401f7b004a1SBob Moore 402*7f9fc99cSLv Zheng status = acpi_os_table_override(table_header, &new_table_desc.pointer); 403*7f9fc99cSLv Zheng if (ACPI_SUCCESS(status) && new_table_desc.pointer) { 404*7f9fc99cSLv Zheng new_table_desc.address = 405*7f9fc99cSLv Zheng ACPI_PTR_TO_PHYSADDR(new_table_desc.pointer); 406*7f9fc99cSLv Zheng new_table_desc.length = new_table_desc.pointer->length; 407*7f9fc99cSLv Zheng new_table_desc.flags = ACPI_TABLE_ORIGIN_OVERRIDE; 408f7b004a1SBob Moore override_type = "Logical"; 409f7b004a1SBob Moore goto finish_override; 410f7b004a1SBob Moore } 411f7b004a1SBob Moore 412f7b004a1SBob Moore /* (2) Attempt physical override (returns a physical address) */ 413f7b004a1SBob Moore 414f7b004a1SBob Moore status = acpi_os_physical_table_override(table_header, 415*7f9fc99cSLv Zheng &new_table_desc.address, 416*7f9fc99cSLv Zheng &new_table_desc.length); 417*7f9fc99cSLv Zheng if (ACPI_SUCCESS(status) && new_table_desc.address 418*7f9fc99cSLv Zheng && new_table_desc.length) { 419f7b004a1SBob Moore override_type = "Physical"; 420*7f9fc99cSLv Zheng new_table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED; 421f7b004a1SBob Moore goto finish_override; 422f7b004a1SBob Moore } 423f7b004a1SBob Moore 424f7b004a1SBob Moore return (NULL); /* There was no override */ 425f7b004a1SBob Moore 426f7b004a1SBob Moore finish_override: 427f7b004a1SBob Moore 428*7f9fc99cSLv Zheng /* 429*7f9fc99cSLv Zheng * Acquire the entire new table to indicate overridden. 430*7f9fc99cSLv Zheng * Note that this is required by the callers of this function. 431*7f9fc99cSLv Zheng */ 432*7f9fc99cSLv Zheng status = acpi_tb_acquire_table(&new_table_desc, &new_table, 433*7f9fc99cSLv Zheng &new_table_length, &new_flags); 434*7f9fc99cSLv Zheng if (ACPI_FAILURE(status)) { 435*7f9fc99cSLv Zheng ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, 436*7f9fc99cSLv Zheng "%4.4s " ACPI_PRINTF_UINT 437*7f9fc99cSLv Zheng " Attempted table override failed", 438*7f9fc99cSLv Zheng table_header->signature, 439*7f9fc99cSLv Zheng ACPI_FORMAT_TO_UINT(table_desc->address))); 440*7f9fc99cSLv Zheng return (NULL); 441*7f9fc99cSLv Zheng } 442*7f9fc99cSLv Zheng 4432e19f8d0SBob Moore ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT 4442e19f8d0SBob Moore " %s table override, new table: " ACPI_PRINTF_UINT, 445f7b004a1SBob Moore table_header->signature, 4462e19f8d0SBob Moore ACPI_FORMAT_TO_UINT(table_desc->address), 447*7f9fc99cSLv Zheng override_type, ACPI_FORMAT_TO_UINT(new_table_desc.address))); 448f7b004a1SBob Moore 449*7f9fc99cSLv Zheng /* We can now uninstall the original table (if fully mapped) */ 450f7b004a1SBob Moore 451*7f9fc99cSLv Zheng acpi_tb_uninstall_table(table_desc); 452f7b004a1SBob Moore 453*7f9fc99cSLv Zheng /* Install the new table */ 454f7b004a1SBob Moore 455*7f9fc99cSLv Zheng table_desc->address = new_table_desc.address; 456*7f9fc99cSLv Zheng table_desc->length = new_table_desc.length; 457*7f9fc99cSLv Zheng table_desc->flags = new_table_desc.flags; 458f7b004a1SBob Moore 459f7b004a1SBob Moore return (new_table); 460f7b004a1SBob Moore } 461f7b004a1SBob Moore 462f7b004a1SBob Moore /******************************************************************************* 463f7b004a1SBob Moore * 46495b482a8SLen Brown * FUNCTION: acpi_tb_resize_root_table_list 46595b482a8SLen Brown * 46695b482a8SLen Brown * PARAMETERS: None 46795b482a8SLen Brown * 46895b482a8SLen Brown * RETURN: Status 46995b482a8SLen Brown * 47095b482a8SLen Brown * DESCRIPTION: Expand the size of global table array 47195b482a8SLen Brown * 47295b482a8SLen Brown ******************************************************************************/ 47395b482a8SLen Brown 47495b482a8SLen Brown acpi_status acpi_tb_resize_root_table_list(void) 47595b482a8SLen Brown { 47695b482a8SLen Brown struct acpi_table_desc *tables; 4772bc198c1SLv Zheng u32 table_count; 47895b482a8SLen Brown 47995b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_resize_root_table_list); 48095b482a8SLen Brown 48195b482a8SLen Brown /* allow_resize flag is a parameter to acpi_initialize_tables */ 48295b482a8SLen Brown 48395b482a8SLen Brown if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { 48495b482a8SLen Brown ACPI_ERROR((AE_INFO, 48595b482a8SLen Brown "Resize of Root Table Array is not allowed")); 48695b482a8SLen Brown return_ACPI_STATUS(AE_SUPPORT); 48795b482a8SLen Brown } 48895b482a8SLen Brown 48995b482a8SLen Brown /* Increase the Table Array size */ 49095b482a8SLen Brown 4912bc198c1SLv Zheng if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 4922bc198c1SLv Zheng table_count = acpi_gbl_root_table_list.max_table_count; 4932bc198c1SLv Zheng } else { 4942bc198c1SLv Zheng table_count = acpi_gbl_root_table_list.current_table_count; 4952bc198c1SLv Zheng } 4962bc198c1SLv Zheng 4972bc198c1SLv Zheng tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count + 498ec41f193SBob Moore ACPI_ROOT_TABLE_SIZE_INCREMENT) * 499ec41f193SBob Moore sizeof(struct acpi_table_desc)); 50095b482a8SLen Brown if (!tables) { 50195b482a8SLen Brown ACPI_ERROR((AE_INFO, 50295b482a8SLen Brown "Could not allocate new root table array")); 50395b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY); 50495b482a8SLen Brown } 50595b482a8SLen Brown 50695b482a8SLen Brown /* Copy and free the previous table array */ 50795b482a8SLen Brown 50895b482a8SLen Brown if (acpi_gbl_root_table_list.tables) { 50995b482a8SLen Brown ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, 5102bc198c1SLv Zheng (acpi_size) table_count * 5112bc198c1SLv Zheng sizeof(struct acpi_table_desc)); 51295b482a8SLen Brown 51395b482a8SLen Brown if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 51495b482a8SLen Brown ACPI_FREE(acpi_gbl_root_table_list.tables); 51595b482a8SLen Brown } 51695b482a8SLen Brown } 51795b482a8SLen Brown 51895b482a8SLen Brown acpi_gbl_root_table_list.tables = tables; 5192bc198c1SLv Zheng acpi_gbl_root_table_list.max_table_count = 5202bc198c1SLv Zheng table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT; 5212bc198c1SLv Zheng acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED; 52295b482a8SLen Brown 52395b482a8SLen Brown return_ACPI_STATUS(AE_OK); 52495b482a8SLen Brown } 52595b482a8SLen Brown 52695b482a8SLen Brown /******************************************************************************* 52795b482a8SLen Brown * 52895b482a8SLen Brown * FUNCTION: acpi_tb_store_table 52995b482a8SLen Brown * 530ba494beeSBob Moore * PARAMETERS: address - Table address 531ba494beeSBob Moore * table - Table header 532ba494beeSBob Moore * length - Table length 533ba494beeSBob Moore * flags - flags 53495b482a8SLen Brown * 53595b482a8SLen Brown * RETURN: Status and table index. 53695b482a8SLen Brown * 53795b482a8SLen Brown * DESCRIPTION: Add an ACPI table to the global table list 53895b482a8SLen Brown * 53995b482a8SLen Brown ******************************************************************************/ 54095b482a8SLen Brown 54195b482a8SLen Brown acpi_status 54295b482a8SLen Brown acpi_tb_store_table(acpi_physical_address address, 54395b482a8SLen Brown struct acpi_table_header *table, 54495b482a8SLen Brown u32 length, u8 flags, u32 *table_index) 54595b482a8SLen Brown { 546b9ee2043SBob Moore acpi_status status; 547b9ee2043SBob Moore struct acpi_table_desc *new_table; 54895b482a8SLen Brown 54995b482a8SLen Brown /* Ensure that there is room for the table in the Root Table List */ 55095b482a8SLen Brown 551b9ee2043SBob Moore if (acpi_gbl_root_table_list.current_table_count >= 552b9ee2043SBob Moore acpi_gbl_root_table_list.max_table_count) { 55395b482a8SLen Brown status = acpi_tb_resize_root_table_list(); 55495b482a8SLen Brown if (ACPI_FAILURE(status)) { 55595b482a8SLen Brown return (status); 55695b482a8SLen Brown } 55795b482a8SLen Brown } 55895b482a8SLen Brown 559b9ee2043SBob Moore new_table = 560b9ee2043SBob Moore &acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list. 561b9ee2043SBob Moore current_table_count]; 562b9ee2043SBob Moore 56395b482a8SLen Brown /* Initialize added table */ 56495b482a8SLen Brown 565b9ee2043SBob Moore new_table->address = address; 566b9ee2043SBob Moore new_table->pointer = table; 567b9ee2043SBob Moore new_table->length = length; 568b9ee2043SBob Moore new_table->owner_id = 0; 569b9ee2043SBob Moore new_table->flags = flags; 57095b482a8SLen Brown 571b9ee2043SBob Moore ACPI_MOVE_32_TO_32(&new_table->signature, table->signature); 57295b482a8SLen Brown 573b9ee2043SBob Moore *table_index = acpi_gbl_root_table_list.current_table_count; 574b9ee2043SBob Moore acpi_gbl_root_table_list.current_table_count++; 575b9ee2043SBob Moore return (AE_OK); 57695b482a8SLen Brown } 57795b482a8SLen Brown 57895b482a8SLen Brown /******************************************************************************* 57995b482a8SLen Brown * 580*7f9fc99cSLv Zheng * FUNCTION: acpi_tb_uninstall_table 58195b482a8SLen Brown * 582*7f9fc99cSLv Zheng * PARAMETERS: table_desc - Table descriptor 58395b482a8SLen Brown * 58495b482a8SLen Brown * RETURN: None 58595b482a8SLen Brown * 58695b482a8SLen Brown * DESCRIPTION: Delete one internal ACPI table 58795b482a8SLen Brown * 58895b482a8SLen Brown ******************************************************************************/ 58995b482a8SLen Brown 590*7f9fc99cSLv Zheng void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc) 59195b482a8SLen Brown { 5925582982dSLv Zheng 593*7f9fc99cSLv Zheng ACPI_FUNCTION_TRACE(tb_uninstall_table); 5945582982dSLv Zheng 595*7f9fc99cSLv Zheng /* Table must be installed */ 596*7f9fc99cSLv Zheng 597*7f9fc99cSLv Zheng if (!table_desc->address) { 598*7f9fc99cSLv Zheng return_VOID; 59995b482a8SLen Brown } 6005582982dSLv Zheng 601*7f9fc99cSLv Zheng acpi_tb_invalidate_table(table_desc); 6021d1ea1b7SChao Guan 603*7f9fc99cSLv Zheng if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == 604*7f9fc99cSLv Zheng ACPI_TABLE_ORIGIN_ALLOCATED) { 605*7f9fc99cSLv Zheng ACPI_FREE(ACPI_CAST_PTR(void, table_desc->address)); 606*7f9fc99cSLv Zheng } 6071d1ea1b7SChao Guan 608dc156adfSLv Zheng table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL); 609f7b004a1SBob Moore 610*7f9fc99cSLv Zheng return_VOID; 61195b482a8SLen Brown } 61295b482a8SLen Brown 61395b482a8SLen Brown /******************************************************************************* 61495b482a8SLen Brown * 61595b482a8SLen Brown * FUNCTION: acpi_tb_terminate 61695b482a8SLen Brown * 61795b482a8SLen Brown * PARAMETERS: None 61895b482a8SLen Brown * 61995b482a8SLen Brown * RETURN: None 62095b482a8SLen Brown * 62195b482a8SLen Brown * DESCRIPTION: Delete all internal ACPI tables 62295b482a8SLen Brown * 62395b482a8SLen Brown ******************************************************************************/ 62495b482a8SLen Brown 62595b482a8SLen Brown void acpi_tb_terminate(void) 62695b482a8SLen Brown { 62795b482a8SLen Brown u32 i; 62895b482a8SLen Brown 62995b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_terminate); 63095b482a8SLen Brown 63195b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 63295b482a8SLen Brown 63395b482a8SLen Brown /* Delete the individual tables */ 63495b482a8SLen Brown 635b9ee2043SBob Moore for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { 636*7f9fc99cSLv Zheng acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]); 63795b482a8SLen Brown } 63895b482a8SLen Brown 63995b482a8SLen Brown /* 64095b482a8SLen Brown * Delete the root table array if allocated locally. Array cannot be 64195b482a8SLen Brown * mapped, so we don't need to check for that flag. 64295b482a8SLen Brown */ 64395b482a8SLen Brown if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 64495b482a8SLen Brown ACPI_FREE(acpi_gbl_root_table_list.tables); 64595b482a8SLen Brown } 64695b482a8SLen Brown 64795b482a8SLen Brown acpi_gbl_root_table_list.tables = NULL; 64895b482a8SLen Brown acpi_gbl_root_table_list.flags = 0; 649b9ee2043SBob Moore acpi_gbl_root_table_list.current_table_count = 0; 65095b482a8SLen Brown 65195b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); 65295b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 65368aafc35SBob Moore 65468aafc35SBob Moore return_VOID; 65595b482a8SLen Brown } 65695b482a8SLen Brown 65795b482a8SLen Brown /******************************************************************************* 65895b482a8SLen Brown * 65995b482a8SLen Brown * FUNCTION: acpi_tb_delete_namespace_by_owner 66095b482a8SLen Brown * 66195b482a8SLen Brown * PARAMETERS: table_index - Table index 66295b482a8SLen Brown * 6638a335a23SBob Moore * RETURN: Status 66495b482a8SLen Brown * 66595b482a8SLen Brown * DESCRIPTION: Delete all namespace objects created when this table was loaded. 66695b482a8SLen Brown * 66795b482a8SLen Brown ******************************************************************************/ 66895b482a8SLen Brown 6698a335a23SBob Moore acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) 67095b482a8SLen Brown { 67195b482a8SLen Brown acpi_owner_id owner_id; 6728a335a23SBob Moore acpi_status status; 67395b482a8SLen Brown 6748a335a23SBob Moore ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner); 6758a335a23SBob Moore 6768a335a23SBob Moore status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 6778a335a23SBob Moore if (ACPI_FAILURE(status)) { 6788a335a23SBob Moore return_ACPI_STATUS(status); 67995b482a8SLen Brown } 68095b482a8SLen Brown 681b9ee2043SBob Moore if (table_index >= acpi_gbl_root_table_list.current_table_count) { 6828a335a23SBob Moore 6838a335a23SBob Moore /* The table index does not exist */ 6848a335a23SBob Moore 68595b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 6868a335a23SBob Moore return_ACPI_STATUS(AE_NOT_EXIST); 6878a335a23SBob Moore } 6888a335a23SBob Moore 6898a335a23SBob Moore /* Get the owner ID for this table, used to delete namespace nodes */ 6908a335a23SBob Moore 6918a335a23SBob Moore owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id; 6928a335a23SBob Moore (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 6938a335a23SBob Moore 6948a335a23SBob Moore /* 6958a335a23SBob Moore * Need to acquire the namespace writer lock to prevent interference 6968a335a23SBob Moore * with any concurrent namespace walks. The interpreter must be 6978a335a23SBob Moore * released during the deletion since the acquisition of the deletion 6988a335a23SBob Moore * lock may block, and also since the execution of a namespace walk 6998a335a23SBob Moore * must be allowed to use the interpreter. 7008a335a23SBob Moore */ 701e4c1ebfcSBob Moore (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); 7028a335a23SBob Moore status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); 7038a335a23SBob Moore 70495b482a8SLen Brown acpi_ns_delete_namespace_by_owner(owner_id); 7058a335a23SBob Moore if (ACPI_FAILURE(status)) { 7068a335a23SBob Moore return_ACPI_STATUS(status); 7078a335a23SBob Moore } 7088a335a23SBob Moore 7098a335a23SBob Moore acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); 7108a335a23SBob Moore 7118a335a23SBob Moore status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); 7128a335a23SBob Moore return_ACPI_STATUS(status); 71395b482a8SLen Brown } 71495b482a8SLen Brown 71595b482a8SLen Brown /******************************************************************************* 71695b482a8SLen Brown * 71795b482a8SLen Brown * FUNCTION: acpi_tb_allocate_owner_id 71895b482a8SLen Brown * 71995b482a8SLen Brown * PARAMETERS: table_index - Table index 72095b482a8SLen Brown * 72195b482a8SLen Brown * RETURN: Status 72295b482a8SLen Brown * 72395b482a8SLen Brown * DESCRIPTION: Allocates owner_id in table_desc 72495b482a8SLen Brown * 72595b482a8SLen Brown ******************************************************************************/ 72695b482a8SLen Brown 72795b482a8SLen Brown acpi_status acpi_tb_allocate_owner_id(u32 table_index) 72895b482a8SLen Brown { 72995b482a8SLen Brown acpi_status status = AE_BAD_PARAMETER; 73095b482a8SLen Brown 73195b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_allocate_owner_id); 73295b482a8SLen Brown 73395b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 734b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 73595b482a8SLen Brown status = acpi_ut_allocate_owner_id 73695b482a8SLen Brown (&(acpi_gbl_root_table_list.tables[table_index].owner_id)); 73795b482a8SLen Brown } 73895b482a8SLen Brown 73995b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 74095b482a8SLen Brown return_ACPI_STATUS(status); 74195b482a8SLen Brown } 74295b482a8SLen Brown 74395b482a8SLen Brown /******************************************************************************* 74495b482a8SLen Brown * 74595b482a8SLen Brown * FUNCTION: acpi_tb_release_owner_id 74695b482a8SLen Brown * 74795b482a8SLen Brown * PARAMETERS: table_index - Table index 74895b482a8SLen Brown * 74995b482a8SLen Brown * RETURN: Status 75095b482a8SLen Brown * 75195b482a8SLen Brown * DESCRIPTION: Releases owner_id in table_desc 75295b482a8SLen Brown * 75395b482a8SLen Brown ******************************************************************************/ 75495b482a8SLen Brown 75595b482a8SLen Brown acpi_status acpi_tb_release_owner_id(u32 table_index) 75695b482a8SLen Brown { 75795b482a8SLen Brown acpi_status status = AE_BAD_PARAMETER; 75895b482a8SLen Brown 75995b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_release_owner_id); 76095b482a8SLen Brown 76195b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 762b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 76395b482a8SLen Brown acpi_ut_release_owner_id(& 76495b482a8SLen Brown (acpi_gbl_root_table_list. 76595b482a8SLen Brown tables[table_index].owner_id)); 76695b482a8SLen Brown status = AE_OK; 76795b482a8SLen Brown } 76895b482a8SLen Brown 76995b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 77095b482a8SLen Brown return_ACPI_STATUS(status); 77195b482a8SLen Brown } 77295b482a8SLen Brown 77395b482a8SLen Brown /******************************************************************************* 77495b482a8SLen Brown * 77595b482a8SLen Brown * FUNCTION: acpi_tb_get_owner_id 77695b482a8SLen Brown * 77795b482a8SLen Brown * PARAMETERS: table_index - Table index 77895b482a8SLen Brown * owner_id - Where the table owner_id is returned 77995b482a8SLen Brown * 78095b482a8SLen Brown * RETURN: Status 78195b482a8SLen Brown * 78295b482a8SLen Brown * DESCRIPTION: returns owner_id for the ACPI table 78395b482a8SLen Brown * 78495b482a8SLen Brown ******************************************************************************/ 78595b482a8SLen Brown 78695b482a8SLen Brown acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id * owner_id) 78795b482a8SLen Brown { 78895b482a8SLen Brown acpi_status status = AE_BAD_PARAMETER; 78995b482a8SLen Brown 79095b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_get_owner_id); 79195b482a8SLen Brown 79295b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 793b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 79495b482a8SLen Brown *owner_id = 79595b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].owner_id; 79695b482a8SLen Brown status = AE_OK; 79795b482a8SLen Brown } 79895b482a8SLen Brown 79995b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 80095b482a8SLen Brown return_ACPI_STATUS(status); 80195b482a8SLen Brown } 80295b482a8SLen Brown 80395b482a8SLen Brown /******************************************************************************* 80495b482a8SLen Brown * 80595b482a8SLen Brown * FUNCTION: acpi_tb_is_table_loaded 80695b482a8SLen Brown * 80795b482a8SLen Brown * PARAMETERS: table_index - Table index 80895b482a8SLen Brown * 80995b482a8SLen Brown * RETURN: Table Loaded Flag 81095b482a8SLen Brown * 81195b482a8SLen Brown ******************************************************************************/ 81295b482a8SLen Brown 81395b482a8SLen Brown u8 acpi_tb_is_table_loaded(u32 table_index) 81495b482a8SLen Brown { 81595b482a8SLen Brown u8 is_loaded = FALSE; 81695b482a8SLen Brown 81795b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 818b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 81995b482a8SLen Brown is_loaded = (u8) 820ec41f193SBob Moore (acpi_gbl_root_table_list.tables[table_index].flags & 821ec41f193SBob Moore ACPI_TABLE_IS_LOADED); 82295b482a8SLen Brown } 82395b482a8SLen Brown 82495b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 82595b482a8SLen Brown return (is_loaded); 82695b482a8SLen Brown } 82795b482a8SLen Brown 82895b482a8SLen Brown /******************************************************************************* 82995b482a8SLen Brown * 83095b482a8SLen Brown * FUNCTION: acpi_tb_set_table_loaded_flag 83195b482a8SLen Brown * 83295b482a8SLen Brown * PARAMETERS: table_index - Table index 83395b482a8SLen Brown * is_loaded - TRUE if table is loaded, FALSE otherwise 83495b482a8SLen Brown * 83595b482a8SLen Brown * RETURN: None 83695b482a8SLen Brown * 83795b482a8SLen Brown * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 83895b482a8SLen Brown * 83995b482a8SLen Brown ******************************************************************************/ 84095b482a8SLen Brown 84195b482a8SLen Brown void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) 84295b482a8SLen Brown { 84395b482a8SLen Brown 84495b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 845b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 84695b482a8SLen Brown if (is_loaded) { 84795b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].flags |= 84895b482a8SLen Brown ACPI_TABLE_IS_LOADED; 84995b482a8SLen Brown } else { 85095b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].flags &= 85195b482a8SLen Brown ~ACPI_TABLE_IS_LOADED; 85295b482a8SLen Brown } 85395b482a8SLen Brown } 85495b482a8SLen Brown 85595b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 85695b482a8SLen Brown } 857