1 /****************************************************************************** 2 * 3 * Module Name: nsload - namespace loading/expanding/contracting procedures 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 #include <acpi/acpi.h> 45 #include "accommon.h" 46 #include "acnamesp.h" 47 #include "acdispat.h" 48 #include "actables.h" 49 #include "acinterp.h" 50 51 #define _COMPONENT ACPI_NAMESPACE 52 ACPI_MODULE_NAME("nsload") 53 54 /* Local prototypes */ 55 #ifdef ACPI_FUTURE_IMPLEMENTATION 56 acpi_status acpi_ns_unload_namespace(acpi_handle handle); 57 58 static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); 59 #endif 60 61 #ifndef ACPI_NO_METHOD_EXECUTION 62 /******************************************************************************* 63 * 64 * FUNCTION: acpi_ns_load_table 65 * 66 * PARAMETERS: table_index - Index for table to be loaded 67 * node - Owning NS node 68 * 69 * RETURN: Status 70 * 71 * DESCRIPTION: Load one ACPI table into the namespace 72 * 73 ******************************************************************************/ 74 75 acpi_status 76 acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) 77 { 78 acpi_status status; 79 80 ACPI_FUNCTION_TRACE(ns_load_table); 81 82 /* If table already loaded into namespace, just return */ 83 84 if (acpi_tb_is_table_loaded(table_index)) { 85 status = AE_ALREADY_EXISTS; 86 goto unlock; 87 } 88 89 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 90 "**** Loading table into namespace ****\n")); 91 92 status = acpi_tb_allocate_owner_id(table_index); 93 if (ACPI_FAILURE(status)) { 94 goto unlock; 95 } 96 97 /* 98 * Parse the table and load the namespace with all named 99 * objects found within. Control methods are NOT parsed 100 * at this time. In fact, the control methods cannot be 101 * parsed until the entire namespace is loaded, because 102 * if a control method makes a forward reference (call) 103 * to another control method, we can't continue parsing 104 * because we don't know how many arguments to parse next! 105 */ 106 status = acpi_ns_parse_table(table_index, node); 107 if (ACPI_SUCCESS(status)) { 108 acpi_tb_set_table_loaded_flag(table_index, TRUE); 109 } else { 110 /* 111 * On error, delete any namespace objects created by this table. 112 * We cannot initialize these objects, so delete them. There are 113 * a couple of expecially bad cases: 114 * AE_ALREADY_EXISTS - namespace collision. 115 * AE_NOT_FOUND - the target of a Scope operator does not 116 * exist. This target of Scope must already exist in the 117 * namespace, as per the ACPI specification. 118 */ 119 acpi_ns_delete_namespace_by_owner(acpi_gbl_root_table_list. 120 tables[table_index].owner_id); 121 122 acpi_tb_release_owner_id(table_index); 123 return_ACPI_STATUS(status); 124 } 125 126 unlock: 127 if (ACPI_FAILURE(status)) { 128 return_ACPI_STATUS(status); 129 } 130 131 /* 132 * Now we can parse the control methods. We always parse 133 * them here for a sanity check, and if configured for 134 * just-in-time parsing, we delete the control method 135 * parse trees. 136 */ 137 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 138 "**** Begin Table Object Initialization\n")); 139 140 status = acpi_ds_initialize_objects(table_index, node); 141 142 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 143 "**** Completed Table Object Initialization\n")); 144 145 /* 146 * Execute any module-level code that was detected during the table load 147 * phase. Although illegal since ACPI 2.0, there are many machines that 148 * contain this type of code. Each block of detected executable AML code 149 * outside of any control method is wrapped with a temporary control 150 * method object and placed on a global list. The methods on this list 151 * are executed below. 152 * 153 * This case executes the module-level code for each table immediately 154 * after the table has been loaded. This provides compatibility with 155 * other ACPI implementations. Optionally, the execution can be deferred 156 * until later, see acpi_initialize_objects. 157 */ 158 if (!acpi_gbl_parse_table_as_term_list 159 && !acpi_gbl_group_module_level_code) { 160 acpi_ns_exec_module_code_list(); 161 } 162 163 return_ACPI_STATUS(status); 164 } 165 166 #ifdef ACPI_OBSOLETE_FUNCTIONS 167 /******************************************************************************* 168 * 169 * FUNCTION: acpi_load_namespace 170 * 171 * PARAMETERS: None 172 * 173 * RETURN: Status 174 * 175 * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. 176 * (DSDT points to either the BIOS or a buffer.) 177 * 178 ******************************************************************************/ 179 180 acpi_status acpi_ns_load_namespace(void) 181 { 182 acpi_status status; 183 184 ACPI_FUNCTION_TRACE(acpi_load_name_space); 185 186 /* There must be at least a DSDT installed */ 187 188 if (acpi_gbl_DSDT == NULL) { 189 ACPI_ERROR((AE_INFO, "DSDT is not in memory")); 190 return_ACPI_STATUS(AE_NO_ACPI_TABLES); 191 } 192 193 /* 194 * Load the namespace. The DSDT is required, 195 * but the SSDT and PSDT tables are optional. 196 */ 197 status = acpi_ns_load_table_by_type(ACPI_TABLE_ID_DSDT); 198 if (ACPI_FAILURE(status)) { 199 return_ACPI_STATUS(status); 200 } 201 202 /* Ignore exceptions from these */ 203 204 (void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_SSDT); 205 (void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_PSDT); 206 207 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, 208 "ACPI Namespace successfully loaded at root %p\n", 209 acpi_gbl_root_node)); 210 211 return_ACPI_STATUS(status); 212 } 213 #endif 214 215 #ifdef ACPI_FUTURE_IMPLEMENTATION 216 /******************************************************************************* 217 * 218 * FUNCTION: acpi_ns_delete_subtree 219 * 220 * PARAMETERS: start_handle - Handle in namespace where search begins 221 * 222 * RETURNS Status 223 * 224 * DESCRIPTION: Walks the namespace starting at the given handle and deletes 225 * all objects, entries, and scopes in the entire subtree. 226 * 227 * Namespace/Interpreter should be locked or the subsystem should 228 * be in shutdown before this routine is called. 229 * 230 ******************************************************************************/ 231 232 static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle) 233 { 234 acpi_status status; 235 acpi_handle child_handle; 236 acpi_handle parent_handle; 237 acpi_handle next_child_handle; 238 acpi_handle dummy; 239 u32 level; 240 241 ACPI_FUNCTION_TRACE(ns_delete_subtree); 242 243 parent_handle = start_handle; 244 child_handle = NULL; 245 level = 1; 246 247 /* 248 * Traverse the tree of objects until we bubble back up 249 * to where we started. 250 */ 251 while (level > 0) { 252 253 /* Attempt to get the next object in this scope */ 254 255 status = acpi_get_next_object(ACPI_TYPE_ANY, parent_handle, 256 child_handle, &next_child_handle); 257 258 child_handle = next_child_handle; 259 260 /* Did we get a new object? */ 261 262 if (ACPI_SUCCESS(status)) { 263 264 /* Check if this object has any children */ 265 266 if (ACPI_SUCCESS 267 (acpi_get_next_object 268 (ACPI_TYPE_ANY, child_handle, NULL, &dummy))) { 269 /* 270 * There is at least one child of this object, 271 * visit the object 272 */ 273 level++; 274 parent_handle = child_handle; 275 child_handle = NULL; 276 } 277 } else { 278 /* 279 * No more children in this object, go back up to 280 * the object's parent 281 */ 282 level--; 283 284 /* Delete all children now */ 285 286 acpi_ns_delete_children(child_handle); 287 288 child_handle = parent_handle; 289 status = acpi_get_parent(parent_handle, &parent_handle); 290 if (ACPI_FAILURE(status)) { 291 return_ACPI_STATUS(status); 292 } 293 } 294 } 295 296 /* Now delete the starting object, and we are done */ 297 298 acpi_ns_remove_node(child_handle); 299 return_ACPI_STATUS(AE_OK); 300 } 301 302 /******************************************************************************* 303 * 304 * FUNCTION: acpi_ns_unload_name_space 305 * 306 * PARAMETERS: handle - Root of namespace subtree to be deleted 307 * 308 * RETURN: Status 309 * 310 * DESCRIPTION: Shrinks the namespace, typically in response to an undocking 311 * event. Deletes an entire subtree starting from (and 312 * including) the given handle. 313 * 314 ******************************************************************************/ 315 316 acpi_status acpi_ns_unload_namespace(acpi_handle handle) 317 { 318 acpi_status status; 319 320 ACPI_FUNCTION_TRACE(ns_unload_name_space); 321 322 /* Parameter validation */ 323 324 if (!acpi_gbl_root_node) { 325 return_ACPI_STATUS(AE_NO_NAMESPACE); 326 } 327 328 if (!handle) { 329 return_ACPI_STATUS(AE_BAD_PARAMETER); 330 } 331 332 /* This function does the real work */ 333 334 status = acpi_ns_delete_subtree(handle); 335 return_ACPI_STATUS(status); 336 } 337 #endif 338 #endif 339