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 <contrib/dev/acpica/include/acpi.h> 45 #include <contrib/dev/acpica/include/accommon.h> 46 #include <contrib/dev/acpica/include/acnamesp.h> 47 #include <contrib/dev/acpica/include/acdispat.h> 48 #include <contrib/dev/acpica/include/actables.h> 49 #include <contrib/dev/acpica/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 AcpiExEnterInterpreter (); 158 Status = AcpiDsInitializeObjects (TableIndex, Node); 159 AcpiExExitInterpreter (); 160 161 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 162 "**** Completed Table Object Initialization\n")); 163 164 /* 165 * Execute any module-level code that was detected during the table load 166 * phase. Although illegal since ACPI 2.0, there are many machines that 167 * contain this type of code. Each block of detected executable AML code 168 * outside of any control method is wrapped with a temporary control 169 * method object and placed on a global list. The methods on this list 170 * are executed below. 171 * 172 * This case executes the module-level code for each table immediately 173 * after the table has been loaded. This provides compatibility with 174 * other ACPI implementations. Optionally, the execution can be deferred 175 * until later, see AcpiInitializeObjects. 176 */ 177 if (!AcpiGbl_ParseTableAsTermList && !AcpiGbl_GroupModuleLevelCode) 178 { 179 AcpiNsExecModuleCodeList (); 180 } 181 182 return_ACPI_STATUS (Status); 183 } 184 185 186 #ifdef ACPI_OBSOLETE_FUNCTIONS 187 /******************************************************************************* 188 * 189 * FUNCTION: AcpiLoadNamespace 190 * 191 * PARAMETERS: None 192 * 193 * RETURN: Status 194 * 195 * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. 196 * (DSDT points to either the BIOS or a buffer.) 197 * 198 ******************************************************************************/ 199 200 ACPI_STATUS 201 AcpiNsLoadNamespace ( 202 void) 203 { 204 ACPI_STATUS Status; 205 206 207 ACPI_FUNCTION_TRACE (AcpiLoadNameSpace); 208 209 210 /* There must be at least a DSDT installed */ 211 212 if (AcpiGbl_DSDT == NULL) 213 { 214 ACPI_ERROR ((AE_INFO, "DSDT is not in memory")); 215 return_ACPI_STATUS (AE_NO_ACPI_TABLES); 216 } 217 218 /* 219 * Load the namespace. The DSDT is required, 220 * but the SSDT and PSDT tables are optional. 221 */ 222 Status = AcpiNsLoadTableByType (ACPI_TABLE_ID_DSDT); 223 if (ACPI_FAILURE (Status)) 224 { 225 return_ACPI_STATUS (Status); 226 } 227 228 /* Ignore exceptions from these */ 229 230 (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_SSDT); 231 (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_PSDT); 232 233 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 234 "ACPI Namespace successfully loaded at root %p\n", 235 AcpiGbl_RootNode)); 236 237 return_ACPI_STATUS (Status); 238 } 239 #endif 240 241 #ifdef ACPI_FUTURE_IMPLEMENTATION 242 /******************************************************************************* 243 * 244 * FUNCTION: AcpiNsDeleteSubtree 245 * 246 * PARAMETERS: StartHandle - Handle in namespace where search begins 247 * 248 * RETURNS Status 249 * 250 * DESCRIPTION: Walks the namespace starting at the given handle and deletes 251 * all objects, entries, and scopes in the entire subtree. 252 * 253 * Namespace/Interpreter should be locked or the subsystem should 254 * be in shutdown before this routine is called. 255 * 256 ******************************************************************************/ 257 258 static ACPI_STATUS 259 AcpiNsDeleteSubtree ( 260 ACPI_HANDLE StartHandle) 261 { 262 ACPI_STATUS Status; 263 ACPI_HANDLE ChildHandle; 264 ACPI_HANDLE ParentHandle; 265 ACPI_HANDLE NextChildHandle; 266 ACPI_HANDLE Dummy; 267 UINT32 Level; 268 269 270 ACPI_FUNCTION_TRACE (NsDeleteSubtree); 271 272 273 ParentHandle = StartHandle; 274 ChildHandle = NULL; 275 Level = 1; 276 277 /* 278 * Traverse the tree of objects until we bubble back up 279 * to where we started. 280 */ 281 while (Level > 0) 282 { 283 /* Attempt to get the next object in this scope */ 284 285 Status = AcpiGetNextObject (ACPI_TYPE_ANY, ParentHandle, 286 ChildHandle, &NextChildHandle); 287 288 ChildHandle = NextChildHandle; 289 290 /* Did we get a new object? */ 291 292 if (ACPI_SUCCESS (Status)) 293 { 294 /* Check if this object has any children */ 295 296 if (ACPI_SUCCESS (AcpiGetNextObject (ACPI_TYPE_ANY, ChildHandle, 297 NULL, &Dummy))) 298 { 299 /* 300 * There is at least one child of this object, 301 * visit the object 302 */ 303 Level++; 304 ParentHandle = ChildHandle; 305 ChildHandle = NULL; 306 } 307 } 308 else 309 { 310 /* 311 * No more children in this object, go back up to 312 * the object's parent 313 */ 314 Level--; 315 316 /* Delete all children now */ 317 318 AcpiNsDeleteChildren (ChildHandle); 319 320 ChildHandle = ParentHandle; 321 Status = AcpiGetParent (ParentHandle, &ParentHandle); 322 if (ACPI_FAILURE (Status)) 323 { 324 return_ACPI_STATUS (Status); 325 } 326 } 327 } 328 329 /* Now delete the starting object, and we are done */ 330 331 AcpiNsRemoveNode (ChildHandle); 332 return_ACPI_STATUS (AE_OK); 333 } 334 335 336 /******************************************************************************* 337 * 338 * FUNCTION: AcpiNsUnloadNameSpace 339 * 340 * PARAMETERS: Handle - Root of namespace subtree to be deleted 341 * 342 * RETURN: Status 343 * 344 * DESCRIPTION: Shrinks the namespace, typically in response to an undocking 345 * event. Deletes an entire subtree starting from (and 346 * including) the given handle. 347 * 348 ******************************************************************************/ 349 350 ACPI_STATUS 351 AcpiNsUnloadNamespace ( 352 ACPI_HANDLE Handle) 353 { 354 ACPI_STATUS Status; 355 356 357 ACPI_FUNCTION_TRACE (NsUnloadNameSpace); 358 359 360 /* Parameter validation */ 361 362 if (!AcpiGbl_RootNode) 363 { 364 return_ACPI_STATUS (AE_NO_NAMESPACE); 365 } 366 367 if (!Handle) 368 { 369 return_ACPI_STATUS (AE_BAD_PARAMETER); 370 } 371 372 /* This function does the real work */ 373 374 Status = AcpiNsDeleteSubtree (Handle); 375 return_ACPI_STATUS (Status); 376 } 377 #endif 378 #endif 379