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