195b482a8SLen Brown /****************************************************************************** 295b482a8SLen Brown * 395b482a8SLen Brown * Module Name: tbinstal - ACPI table installation and removal 495b482a8SLen Brown * 595b482a8SLen Brown *****************************************************************************/ 695b482a8SLen Brown 795b482a8SLen Brown /* 895b482a8SLen Brown * Copyright (C) 2000 - 2008, 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 5295b482a8SLen Brown /****************************************************************************** 5395b482a8SLen Brown * 5495b482a8SLen Brown * FUNCTION: acpi_tb_verify_table 5595b482a8SLen Brown * 5695b482a8SLen Brown * PARAMETERS: table_desc - table 5795b482a8SLen Brown * 5895b482a8SLen Brown * RETURN: Status 5995b482a8SLen Brown * 6095b482a8SLen Brown * DESCRIPTION: this function is called to verify and map table 6195b482a8SLen Brown * 6295b482a8SLen Brown *****************************************************************************/ 6395b482a8SLen Brown acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) 6495b482a8SLen Brown { 6595b482a8SLen Brown acpi_status status = AE_OK; 6695b482a8SLen Brown 6795b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_verify_table); 6895b482a8SLen Brown 6995b482a8SLen Brown /* Map the table if necessary */ 7095b482a8SLen Brown 7195b482a8SLen Brown if (!table_desc->pointer) { 7295b482a8SLen Brown if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == 7395b482a8SLen Brown ACPI_TABLE_ORIGIN_MAPPED) { 7495b482a8SLen Brown table_desc->pointer = 7595b482a8SLen Brown acpi_os_map_memory(table_desc->address, 7695b482a8SLen Brown table_desc->length); 7795b482a8SLen Brown } 7895b482a8SLen Brown if (!table_desc->pointer) { 7995b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY); 8095b482a8SLen Brown } 8195b482a8SLen Brown } 8295b482a8SLen Brown 8395b482a8SLen Brown /* FACS is the odd table, has no standard ACPI header and no checksum */ 8495b482a8SLen Brown 8595b482a8SLen Brown if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) { 8695b482a8SLen Brown 8795b482a8SLen Brown /* Always calculate checksum, ignore bad checksum if requested */ 8895b482a8SLen Brown 8995b482a8SLen Brown status = 9095b482a8SLen Brown acpi_tb_verify_checksum(table_desc->pointer, 9195b482a8SLen Brown table_desc->length); 9295b482a8SLen Brown } 9395b482a8SLen Brown 9495b482a8SLen Brown return_ACPI_STATUS(status); 9595b482a8SLen Brown } 9695b482a8SLen Brown 9795b482a8SLen Brown /******************************************************************************* 9895b482a8SLen Brown * 9995b482a8SLen Brown * FUNCTION: acpi_tb_add_table 10095b482a8SLen Brown * 10195b482a8SLen Brown * PARAMETERS: table_desc - Table descriptor 10295b482a8SLen Brown * table_index - Where the table index is returned 10395b482a8SLen Brown * 10495b482a8SLen Brown * RETURN: Status 10595b482a8SLen Brown * 106*d3ccaff8SBob Moore * DESCRIPTION: This function is called to add an ACPI table. It is used to 107*d3ccaff8SBob Moore * dynamically load tables via the Load and load_table AML 108*d3ccaff8SBob Moore * operators. 10995b482a8SLen Brown * 11095b482a8SLen Brown ******************************************************************************/ 11195b482a8SLen Brown 11295b482a8SLen Brown acpi_status 11395b482a8SLen Brown acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) 11495b482a8SLen Brown { 11595b482a8SLen Brown u32 i; 11695b482a8SLen Brown acpi_status status = AE_OK; 117*d3ccaff8SBob Moore struct acpi_table_header *override_table = NULL; 11895b482a8SLen Brown 11995b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_add_table); 12095b482a8SLen Brown 12195b482a8SLen Brown if (!table_desc->pointer) { 12295b482a8SLen Brown status = acpi_tb_verify_table(table_desc); 12395b482a8SLen Brown if (ACPI_FAILURE(status) || !table_desc->pointer) { 12495b482a8SLen Brown return_ACPI_STATUS(status); 12595b482a8SLen Brown } 12695b482a8SLen Brown } 12795b482a8SLen Brown 12895b482a8SLen Brown /* 12995b482a8SLen Brown * Originally, we checked the table signature for "SSDT" or "PSDT" here. 13095b482a8SLen Brown * Next, we added support for OEMx tables, signature "OEM". 13195b482a8SLen Brown * Valid tables were encountered with a null signature, so we've just 13295b482a8SLen Brown * given up on validating the signature, since it seems to be a waste 13395b482a8SLen Brown * of code. The original code was removed (05/2008). 13495b482a8SLen Brown */ 13595b482a8SLen Brown 13695b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 13795b482a8SLen Brown 13895b482a8SLen Brown /* Check if table is already registered */ 13995b482a8SLen Brown 14095b482a8SLen Brown for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { 14195b482a8SLen Brown if (!acpi_gbl_root_table_list.tables[i].pointer) { 14295b482a8SLen Brown status = 14395b482a8SLen Brown acpi_tb_verify_table(&acpi_gbl_root_table_list. 14495b482a8SLen Brown tables[i]); 14595b482a8SLen Brown if (ACPI_FAILURE(status) 14695b482a8SLen Brown || !acpi_gbl_root_table_list.tables[i].pointer) { 14795b482a8SLen Brown continue; 14895b482a8SLen Brown } 14995b482a8SLen Brown } 15095b482a8SLen Brown 15195b482a8SLen Brown /* 15295b482a8SLen Brown * Check for a table match on the entire table length, 15395b482a8SLen Brown * not just the header. 15495b482a8SLen Brown */ 15595b482a8SLen Brown if (table_desc->length != 15695b482a8SLen Brown acpi_gbl_root_table_list.tables[i].length) { 15795b482a8SLen Brown continue; 15895b482a8SLen Brown } 15995b482a8SLen Brown 16095b482a8SLen Brown if (ACPI_MEMCMP(table_desc->pointer, 16195b482a8SLen Brown acpi_gbl_root_table_list.tables[i].pointer, 16295b482a8SLen Brown acpi_gbl_root_table_list.tables[i].length)) { 16395b482a8SLen Brown continue; 16495b482a8SLen Brown } 16595b482a8SLen Brown 16695b482a8SLen Brown /* 16795b482a8SLen Brown * Note: the current mechanism does not unregister a table if it is 16895b482a8SLen Brown * dynamically unloaded. The related namespace entries are deleted, 16995b482a8SLen Brown * but the table remains in the root table list. 17095b482a8SLen Brown * 17195b482a8SLen Brown * The assumption here is that the number of different tables that 17295b482a8SLen Brown * will be loaded is actually small, and there is minimal overhead 17395b482a8SLen Brown * in just keeping the table in case it is needed again. 17495b482a8SLen Brown * 17595b482a8SLen Brown * If this assumption changes in the future (perhaps on large 17695b482a8SLen Brown * machines with many table load/unload operations), tables will 17795b482a8SLen Brown * need to be unregistered when they are unloaded, and slots in the 17895b482a8SLen Brown * root table list should be reused when empty. 17995b482a8SLen Brown */ 18095b482a8SLen Brown 18195b482a8SLen Brown /* 18295b482a8SLen Brown * Table is already registered. 18395b482a8SLen Brown * We can delete the table that was passed as a parameter. 18495b482a8SLen Brown */ 18595b482a8SLen Brown acpi_tb_delete_table(table_desc); 18695b482a8SLen Brown *table_index = i; 18795b482a8SLen Brown 18895b482a8SLen Brown if (acpi_gbl_root_table_list.tables[i]. 18995b482a8SLen Brown flags & ACPI_TABLE_IS_LOADED) { 19095b482a8SLen Brown 19195b482a8SLen Brown /* Table is still loaded, this is an error */ 19295b482a8SLen Brown 19395b482a8SLen Brown status = AE_ALREADY_EXISTS; 19495b482a8SLen Brown goto release; 19595b482a8SLen Brown } else { 19695b482a8SLen Brown /* Table was unloaded, allow it to be reloaded */ 19795b482a8SLen Brown 19895b482a8SLen Brown table_desc->pointer = 19995b482a8SLen Brown acpi_gbl_root_table_list.tables[i].pointer; 20095b482a8SLen Brown table_desc->address = 20195b482a8SLen Brown acpi_gbl_root_table_list.tables[i].address; 20295b482a8SLen Brown status = AE_OK; 20395b482a8SLen Brown goto print_header; 20495b482a8SLen Brown } 20595b482a8SLen Brown } 20695b482a8SLen Brown 207*d3ccaff8SBob Moore /* 208*d3ccaff8SBob Moore * ACPI Table Override: 209*d3ccaff8SBob Moore * Allow the host to override dynamically loaded tables. 210*d3ccaff8SBob Moore */ 211*d3ccaff8SBob Moore status = acpi_os_table_override(table_desc->pointer, &override_table); 212*d3ccaff8SBob Moore if (ACPI_SUCCESS(status) && override_table) { 213*d3ccaff8SBob Moore ACPI_INFO((AE_INFO, 214*d3ccaff8SBob Moore "%4.4s @ 0x%p Table override, replaced with:", 215*d3ccaff8SBob Moore table_desc->pointer->signature, 216*d3ccaff8SBob Moore ACPI_CAST_PTR(void, table_desc->address))); 217*d3ccaff8SBob Moore 218*d3ccaff8SBob Moore /* We can delete the table that was passed as a parameter */ 219*d3ccaff8SBob Moore 220*d3ccaff8SBob Moore acpi_tb_delete_table(table_desc); 221*d3ccaff8SBob Moore 222*d3ccaff8SBob Moore /* Setup descriptor for the new table */ 223*d3ccaff8SBob Moore 224*d3ccaff8SBob Moore table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table); 225*d3ccaff8SBob Moore table_desc->pointer = override_table; 226*d3ccaff8SBob Moore table_desc->length = override_table->length; 227*d3ccaff8SBob Moore table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE; 228*d3ccaff8SBob Moore } 229*d3ccaff8SBob Moore 23095b482a8SLen Brown /* Add the table to the global root table list */ 23195b482a8SLen Brown 23295b482a8SLen Brown status = acpi_tb_store_table(table_desc->address, table_desc->pointer, 23395b482a8SLen Brown table_desc->length, table_desc->flags, 23495b482a8SLen Brown table_index); 23595b482a8SLen Brown if (ACPI_FAILURE(status)) { 23695b482a8SLen Brown goto release; 23795b482a8SLen Brown } 23895b482a8SLen Brown 23995b482a8SLen Brown print_header: 24095b482a8SLen Brown acpi_tb_print_table_header(table_desc->address, table_desc->pointer); 24195b482a8SLen Brown 24295b482a8SLen Brown release: 24395b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 24495b482a8SLen Brown return_ACPI_STATUS(status); 24595b482a8SLen Brown } 24695b482a8SLen Brown 24795b482a8SLen Brown /******************************************************************************* 24895b482a8SLen Brown * 24995b482a8SLen Brown * FUNCTION: acpi_tb_resize_root_table_list 25095b482a8SLen Brown * 25195b482a8SLen Brown * PARAMETERS: None 25295b482a8SLen Brown * 25395b482a8SLen Brown * RETURN: Status 25495b482a8SLen Brown * 25595b482a8SLen Brown * DESCRIPTION: Expand the size of global table array 25695b482a8SLen Brown * 25795b482a8SLen Brown ******************************************************************************/ 25895b482a8SLen Brown 25995b482a8SLen Brown acpi_status acpi_tb_resize_root_table_list(void) 26095b482a8SLen Brown { 26195b482a8SLen Brown struct acpi_table_desc *tables; 26295b482a8SLen Brown 26395b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_resize_root_table_list); 26495b482a8SLen Brown 26595b482a8SLen Brown /* allow_resize flag is a parameter to acpi_initialize_tables */ 26695b482a8SLen Brown 26795b482a8SLen Brown if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { 26895b482a8SLen Brown ACPI_ERROR((AE_INFO, 26995b482a8SLen Brown "Resize of Root Table Array is not allowed")); 27095b482a8SLen Brown return_ACPI_STATUS(AE_SUPPORT); 27195b482a8SLen Brown } 27295b482a8SLen Brown 27395b482a8SLen Brown /* Increase the Table Array size */ 27495b482a8SLen Brown 27595b482a8SLen Brown tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list. 27695b482a8SLen Brown size + ACPI_ROOT_TABLE_SIZE_INCREMENT) 27795b482a8SLen Brown * sizeof(struct acpi_table_desc)); 27895b482a8SLen Brown if (!tables) { 27995b482a8SLen Brown ACPI_ERROR((AE_INFO, 28095b482a8SLen Brown "Could not allocate new root table array")); 28195b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY); 28295b482a8SLen Brown } 28395b482a8SLen Brown 28495b482a8SLen Brown /* Copy and free the previous table array */ 28595b482a8SLen Brown 28695b482a8SLen Brown if (acpi_gbl_root_table_list.tables) { 28795b482a8SLen Brown ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, 28895b482a8SLen Brown (acpi_size) acpi_gbl_root_table_list.size * 28995b482a8SLen Brown sizeof(struct acpi_table_desc)); 29095b482a8SLen Brown 29195b482a8SLen Brown if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 29295b482a8SLen Brown ACPI_FREE(acpi_gbl_root_table_list.tables); 29395b482a8SLen Brown } 29495b482a8SLen Brown } 29595b482a8SLen Brown 29695b482a8SLen Brown acpi_gbl_root_table_list.tables = tables; 29795b482a8SLen Brown acpi_gbl_root_table_list.size += ACPI_ROOT_TABLE_SIZE_INCREMENT; 29895b482a8SLen Brown acpi_gbl_root_table_list.flags |= (u8) ACPI_ROOT_ORIGIN_ALLOCATED; 29995b482a8SLen Brown 30095b482a8SLen Brown return_ACPI_STATUS(AE_OK); 30195b482a8SLen Brown } 30295b482a8SLen Brown 30395b482a8SLen Brown /******************************************************************************* 30495b482a8SLen Brown * 30595b482a8SLen Brown * FUNCTION: acpi_tb_store_table 30695b482a8SLen Brown * 30795b482a8SLen Brown * PARAMETERS: Address - Table address 30895b482a8SLen Brown * Table - Table header 30995b482a8SLen Brown * Length - Table length 31095b482a8SLen Brown * Flags - flags 31195b482a8SLen Brown * 31295b482a8SLen Brown * RETURN: Status and table index. 31395b482a8SLen Brown * 31495b482a8SLen Brown * DESCRIPTION: Add an ACPI table to the global table list 31595b482a8SLen Brown * 31695b482a8SLen Brown ******************************************************************************/ 31795b482a8SLen Brown 31895b482a8SLen Brown acpi_status 31995b482a8SLen Brown acpi_tb_store_table(acpi_physical_address address, 32095b482a8SLen Brown struct acpi_table_header *table, 32195b482a8SLen Brown u32 length, u8 flags, u32 *table_index) 32295b482a8SLen Brown { 32395b482a8SLen Brown acpi_status status = AE_OK; 32495b482a8SLen Brown 32595b482a8SLen Brown /* Ensure that there is room for the table in the Root Table List */ 32695b482a8SLen Brown 32795b482a8SLen Brown if (acpi_gbl_root_table_list.count >= acpi_gbl_root_table_list.size) { 32895b482a8SLen Brown status = acpi_tb_resize_root_table_list(); 32995b482a8SLen Brown if (ACPI_FAILURE(status)) { 33095b482a8SLen Brown return (status); 33195b482a8SLen Brown } 33295b482a8SLen Brown } 33395b482a8SLen Brown 33495b482a8SLen Brown /* Initialize added table */ 33595b482a8SLen Brown 33695b482a8SLen Brown acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. 33795b482a8SLen Brown address = address; 33895b482a8SLen Brown acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. 33995b482a8SLen Brown pointer = table; 34095b482a8SLen Brown acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].length = 34195b482a8SLen Brown length; 34295b482a8SLen Brown acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. 34395b482a8SLen Brown owner_id = 0; 34495b482a8SLen Brown acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].flags = 34595b482a8SLen Brown flags; 34695b482a8SLen Brown 34795b482a8SLen Brown ACPI_MOVE_32_TO_32(& 34895b482a8SLen Brown (acpi_gbl_root_table_list. 34995b482a8SLen Brown tables[acpi_gbl_root_table_list.count].signature), 35095b482a8SLen Brown table->signature); 35195b482a8SLen Brown 35295b482a8SLen Brown *table_index = acpi_gbl_root_table_list.count; 35395b482a8SLen Brown acpi_gbl_root_table_list.count++; 35495b482a8SLen Brown return (status); 35595b482a8SLen Brown } 35695b482a8SLen Brown 35795b482a8SLen Brown /******************************************************************************* 35895b482a8SLen Brown * 35995b482a8SLen Brown * FUNCTION: acpi_tb_delete_table 36095b482a8SLen Brown * 36195b482a8SLen Brown * PARAMETERS: table_index - Table index 36295b482a8SLen Brown * 36395b482a8SLen Brown * RETURN: None 36495b482a8SLen Brown * 36595b482a8SLen Brown * DESCRIPTION: Delete one internal ACPI table 36695b482a8SLen Brown * 36795b482a8SLen Brown ******************************************************************************/ 36895b482a8SLen Brown 36995b482a8SLen Brown void acpi_tb_delete_table(struct acpi_table_desc *table_desc) 37095b482a8SLen Brown { 37195b482a8SLen Brown /* Table must be mapped or allocated */ 37295b482a8SLen Brown if (!table_desc->pointer) { 37395b482a8SLen Brown return; 37495b482a8SLen Brown } 37595b482a8SLen Brown switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { 37695b482a8SLen Brown case ACPI_TABLE_ORIGIN_MAPPED: 37795b482a8SLen Brown acpi_os_unmap_memory(table_desc->pointer, table_desc->length); 37895b482a8SLen Brown break; 37995b482a8SLen Brown case ACPI_TABLE_ORIGIN_ALLOCATED: 38095b482a8SLen Brown ACPI_FREE(table_desc->pointer); 38195b482a8SLen Brown break; 38295b482a8SLen Brown default:; 38395b482a8SLen Brown } 38495b482a8SLen Brown 38595b482a8SLen Brown table_desc->pointer = NULL; 38695b482a8SLen Brown } 38795b482a8SLen Brown 38895b482a8SLen Brown /******************************************************************************* 38995b482a8SLen Brown * 39095b482a8SLen Brown * FUNCTION: acpi_tb_terminate 39195b482a8SLen Brown * 39295b482a8SLen Brown * PARAMETERS: None 39395b482a8SLen Brown * 39495b482a8SLen Brown * RETURN: None 39595b482a8SLen Brown * 39695b482a8SLen Brown * DESCRIPTION: Delete all internal ACPI tables 39795b482a8SLen Brown * 39895b482a8SLen Brown ******************************************************************************/ 39995b482a8SLen Brown 40095b482a8SLen Brown void acpi_tb_terminate(void) 40195b482a8SLen Brown { 40295b482a8SLen Brown u32 i; 40395b482a8SLen Brown 40495b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_terminate); 40595b482a8SLen Brown 40695b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 40795b482a8SLen Brown 40895b482a8SLen Brown /* Delete the individual tables */ 40995b482a8SLen Brown 41095b482a8SLen Brown for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { 41195b482a8SLen Brown acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]); 41295b482a8SLen Brown } 41395b482a8SLen Brown 41495b482a8SLen Brown /* 41595b482a8SLen Brown * Delete the root table array if allocated locally. Array cannot be 41695b482a8SLen Brown * mapped, so we don't need to check for that flag. 41795b482a8SLen Brown */ 41895b482a8SLen Brown if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 41995b482a8SLen Brown ACPI_FREE(acpi_gbl_root_table_list.tables); 42095b482a8SLen Brown } 42195b482a8SLen Brown 42295b482a8SLen Brown acpi_gbl_root_table_list.tables = NULL; 42395b482a8SLen Brown acpi_gbl_root_table_list.flags = 0; 42495b482a8SLen Brown acpi_gbl_root_table_list.count = 0; 42595b482a8SLen Brown 42695b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); 42795b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 42895b482a8SLen Brown } 42995b482a8SLen Brown 43095b482a8SLen Brown /******************************************************************************* 43195b482a8SLen Brown * 43295b482a8SLen Brown * FUNCTION: acpi_tb_delete_namespace_by_owner 43395b482a8SLen Brown * 43495b482a8SLen Brown * PARAMETERS: table_index - Table index 43595b482a8SLen Brown * 43695b482a8SLen Brown * RETURN: None 43795b482a8SLen Brown * 43895b482a8SLen Brown * DESCRIPTION: Delete all namespace objects created when this table was loaded. 43995b482a8SLen Brown * 44095b482a8SLen Brown ******************************************************************************/ 44195b482a8SLen Brown 44295b482a8SLen Brown void acpi_tb_delete_namespace_by_owner(u32 table_index) 44395b482a8SLen Brown { 44495b482a8SLen Brown acpi_owner_id owner_id; 44595b482a8SLen Brown 44695b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 44795b482a8SLen Brown if (table_index < acpi_gbl_root_table_list.count) { 44895b482a8SLen Brown owner_id = 44995b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].owner_id; 45095b482a8SLen Brown } else { 45195b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 45295b482a8SLen Brown return; 45395b482a8SLen Brown } 45495b482a8SLen Brown 45595b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 45695b482a8SLen Brown acpi_ns_delete_namespace_by_owner(owner_id); 45795b482a8SLen Brown } 45895b482a8SLen Brown 45995b482a8SLen Brown /******************************************************************************* 46095b482a8SLen Brown * 46195b482a8SLen Brown * FUNCTION: acpi_tb_allocate_owner_id 46295b482a8SLen Brown * 46395b482a8SLen Brown * PARAMETERS: table_index - Table index 46495b482a8SLen Brown * 46595b482a8SLen Brown * RETURN: Status 46695b482a8SLen Brown * 46795b482a8SLen Brown * DESCRIPTION: Allocates owner_id in table_desc 46895b482a8SLen Brown * 46995b482a8SLen Brown ******************************************************************************/ 47095b482a8SLen Brown 47195b482a8SLen Brown acpi_status acpi_tb_allocate_owner_id(u32 table_index) 47295b482a8SLen Brown { 47395b482a8SLen Brown acpi_status status = AE_BAD_PARAMETER; 47495b482a8SLen Brown 47595b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_allocate_owner_id); 47695b482a8SLen Brown 47795b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 47895b482a8SLen Brown if (table_index < acpi_gbl_root_table_list.count) { 47995b482a8SLen Brown status = acpi_ut_allocate_owner_id 48095b482a8SLen Brown (&(acpi_gbl_root_table_list.tables[table_index].owner_id)); 48195b482a8SLen Brown } 48295b482a8SLen Brown 48395b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 48495b482a8SLen Brown return_ACPI_STATUS(status); 48595b482a8SLen Brown } 48695b482a8SLen Brown 48795b482a8SLen Brown /******************************************************************************* 48895b482a8SLen Brown * 48995b482a8SLen Brown * FUNCTION: acpi_tb_release_owner_id 49095b482a8SLen Brown * 49195b482a8SLen Brown * PARAMETERS: table_index - Table index 49295b482a8SLen Brown * 49395b482a8SLen Brown * RETURN: Status 49495b482a8SLen Brown * 49595b482a8SLen Brown * DESCRIPTION: Releases owner_id in table_desc 49695b482a8SLen Brown * 49795b482a8SLen Brown ******************************************************************************/ 49895b482a8SLen Brown 49995b482a8SLen Brown acpi_status acpi_tb_release_owner_id(u32 table_index) 50095b482a8SLen Brown { 50195b482a8SLen Brown acpi_status status = AE_BAD_PARAMETER; 50295b482a8SLen Brown 50395b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_release_owner_id); 50495b482a8SLen Brown 50595b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 50695b482a8SLen Brown if (table_index < acpi_gbl_root_table_list.count) { 50795b482a8SLen Brown acpi_ut_release_owner_id(& 50895b482a8SLen Brown (acpi_gbl_root_table_list. 50995b482a8SLen Brown tables[table_index].owner_id)); 51095b482a8SLen Brown status = AE_OK; 51195b482a8SLen Brown } 51295b482a8SLen Brown 51395b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 51495b482a8SLen Brown return_ACPI_STATUS(status); 51595b482a8SLen Brown } 51695b482a8SLen Brown 51795b482a8SLen Brown /******************************************************************************* 51895b482a8SLen Brown * 51995b482a8SLen Brown * FUNCTION: acpi_tb_get_owner_id 52095b482a8SLen Brown * 52195b482a8SLen Brown * PARAMETERS: table_index - Table index 52295b482a8SLen Brown * owner_id - Where the table owner_id is returned 52395b482a8SLen Brown * 52495b482a8SLen Brown * RETURN: Status 52595b482a8SLen Brown * 52695b482a8SLen Brown * DESCRIPTION: returns owner_id for the ACPI table 52795b482a8SLen Brown * 52895b482a8SLen Brown ******************************************************************************/ 52995b482a8SLen Brown 53095b482a8SLen Brown acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id) 53195b482a8SLen Brown { 53295b482a8SLen Brown acpi_status status = AE_BAD_PARAMETER; 53395b482a8SLen Brown 53495b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_get_owner_id); 53595b482a8SLen Brown 53695b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 53795b482a8SLen Brown if (table_index < acpi_gbl_root_table_list.count) { 53895b482a8SLen Brown *owner_id = 53995b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].owner_id; 54095b482a8SLen Brown status = AE_OK; 54195b482a8SLen Brown } 54295b482a8SLen Brown 54395b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 54495b482a8SLen Brown return_ACPI_STATUS(status); 54595b482a8SLen Brown } 54695b482a8SLen Brown 54795b482a8SLen Brown /******************************************************************************* 54895b482a8SLen Brown * 54995b482a8SLen Brown * FUNCTION: acpi_tb_is_table_loaded 55095b482a8SLen Brown * 55195b482a8SLen Brown * PARAMETERS: table_index - Table index 55295b482a8SLen Brown * 55395b482a8SLen Brown * RETURN: Table Loaded Flag 55495b482a8SLen Brown * 55595b482a8SLen Brown ******************************************************************************/ 55695b482a8SLen Brown 55795b482a8SLen Brown u8 acpi_tb_is_table_loaded(u32 table_index) 55895b482a8SLen Brown { 55995b482a8SLen Brown u8 is_loaded = FALSE; 56095b482a8SLen Brown 56195b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 56295b482a8SLen Brown if (table_index < acpi_gbl_root_table_list.count) { 56395b482a8SLen Brown is_loaded = (u8) 56495b482a8SLen Brown (acpi_gbl_root_table_list.tables[table_index]. 56595b482a8SLen Brown flags & ACPI_TABLE_IS_LOADED); 56695b482a8SLen Brown } 56795b482a8SLen Brown 56895b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 56995b482a8SLen Brown return (is_loaded); 57095b482a8SLen Brown } 57195b482a8SLen Brown 57295b482a8SLen Brown /******************************************************************************* 57395b482a8SLen Brown * 57495b482a8SLen Brown * FUNCTION: acpi_tb_set_table_loaded_flag 57595b482a8SLen Brown * 57695b482a8SLen Brown * PARAMETERS: table_index - Table index 57795b482a8SLen Brown * is_loaded - TRUE if table is loaded, FALSE otherwise 57895b482a8SLen Brown * 57995b482a8SLen Brown * RETURN: None 58095b482a8SLen Brown * 58195b482a8SLen Brown * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 58295b482a8SLen Brown * 58395b482a8SLen Brown ******************************************************************************/ 58495b482a8SLen Brown 58595b482a8SLen Brown void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) 58695b482a8SLen Brown { 58795b482a8SLen Brown 58895b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 58995b482a8SLen Brown if (table_index < acpi_gbl_root_table_list.count) { 59095b482a8SLen Brown if (is_loaded) { 59195b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].flags |= 59295b482a8SLen Brown ACPI_TABLE_IS_LOADED; 59395b482a8SLen Brown } else { 59495b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].flags &= 59595b482a8SLen Brown ~ACPI_TABLE_IS_LOADED; 59695b482a8SLen Brown } 59795b482a8SLen Brown } 59895b482a8SLen Brown 59995b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 60095b482a8SLen Brown } 601