1 /****************************************************************************** 2 * 3 * Module Name: nsload - namespace loading/expanding/contracting procedures 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, 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 50 51 #define _COMPONENT ACPI_NAMESPACE 52 ACPI_MODULE_NAME ("nsload") 53 54 /* Local prototypes */ 55 56 #ifdef ACPI_FUTURE_IMPLEMENTATION 57 ACPI_STATUS 58 AcpiNsUnloadNamespace ( 59 ACPI_HANDLE Handle); 60 61 static ACPI_STATUS 62 AcpiNsDeleteSubtree ( 63 ACPI_HANDLE StartHandle); 64 #endif 65 66 67 #ifndef ACPI_NO_METHOD_EXECUTION 68 /******************************************************************************* 69 * 70 * FUNCTION: AcpiNsLoadTable 71 * 72 * PARAMETERS: TableIndex - Index for table to be loaded 73 * Node - Owning NS node 74 * 75 * RETURN: Status 76 * 77 * DESCRIPTION: Load one ACPI table into the namespace 78 * 79 ******************************************************************************/ 80 81 ACPI_STATUS 82 AcpiNsLoadTable ( 83 UINT32 TableIndex, 84 ACPI_NAMESPACE_NODE *Node) 85 { 86 ACPI_STATUS Status; 87 88 89 ACPI_FUNCTION_TRACE (NsLoadTable); 90 91 92 /* 93 * Parse the table and load the namespace with all named 94 * objects found within. Control methods are NOT parsed 95 * at this time. In fact, the control methods cannot be 96 * parsed until the entire namespace is loaded, because 97 * if a control method makes a forward reference (call) 98 * to another control method, we can't continue parsing 99 * because we don't know how many arguments to parse next! 100 */ 101 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 102 if (ACPI_FAILURE (Status)) 103 { 104 return_ACPI_STATUS (Status); 105 } 106 107 /* If table already loaded into namespace, just return */ 108 109 if (AcpiTbIsTableLoaded (TableIndex)) 110 { 111 Status = AE_ALREADY_EXISTS; 112 goto Unlock; 113 } 114 115 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 116 "**** Loading table into namespace ****\n")); 117 118 Status = AcpiTbAllocateOwnerId (TableIndex); 119 if (ACPI_FAILURE (Status)) 120 { 121 goto Unlock; 122 } 123 124 Status = AcpiNsParseTable (TableIndex, Node); 125 if (ACPI_SUCCESS (Status)) 126 { 127 AcpiTbSetTableLoadedFlag (TableIndex, TRUE); 128 } 129 else 130 { 131 (void) AcpiTbReleaseOwnerId (TableIndex); 132 } 133 134 Unlock: 135 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 136 137 if (ACPI_FAILURE (Status)) 138 { 139 return_ACPI_STATUS (Status); 140 } 141 142 /* 143 * Now we can parse the control methods. We always parse 144 * them here for a sanity check, and if configured for 145 * just-in-time parsing, we delete the control method 146 * parse trees. 147 */ 148 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 149 "**** Begin Table Object Initialization\n")); 150 151 Status = AcpiDsInitializeObjects (TableIndex, Node); 152 153 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 154 "**** Completed Table Object Initialization\n")); 155 156 return_ACPI_STATUS (Status); 157 } 158 159 160 #ifdef ACPI_OBSOLETE_FUNCTIONS 161 /******************************************************************************* 162 * 163 * FUNCTION: AcpiLoadNamespace 164 * 165 * PARAMETERS: None 166 * 167 * RETURN: Status 168 * 169 * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. 170 * (DSDT points to either the BIOS or a buffer.) 171 * 172 ******************************************************************************/ 173 174 ACPI_STATUS 175 AcpiNsLoadNamespace ( 176 void) 177 { 178 ACPI_STATUS Status; 179 180 181 ACPI_FUNCTION_TRACE (AcpiLoadNameSpace); 182 183 184 /* There must be at least a DSDT installed */ 185 186 if (AcpiGbl_DSDT == NULL) 187 { 188 ACPI_ERROR ((AE_INFO, "DSDT is not in memory")); 189 return_ACPI_STATUS (AE_NO_ACPI_TABLES); 190 } 191 192 /* 193 * Load the namespace. The DSDT is required, 194 * but the SSDT and PSDT tables are optional. 195 */ 196 Status = AcpiNsLoadTableByType (ACPI_TABLE_ID_DSDT); 197 if (ACPI_FAILURE (Status)) 198 { 199 return_ACPI_STATUS (Status); 200 } 201 202 /* Ignore exceptions from these */ 203 204 (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_SSDT); 205 (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_PSDT); 206 207 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 208 "ACPI Namespace successfully loaded at root %p\n", 209 AcpiGbl_RootNode)); 210 211 return_ACPI_STATUS (Status); 212 } 213 #endif 214 215 #ifdef ACPI_FUTURE_IMPLEMENTATION 216 /******************************************************************************* 217 * 218 * FUNCTION: AcpiNsDeleteSubtree 219 * 220 * PARAMETERS: StartHandle - 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 233 AcpiNsDeleteSubtree ( 234 ACPI_HANDLE StartHandle) 235 { 236 ACPI_STATUS Status; 237 ACPI_HANDLE ChildHandle; 238 ACPI_HANDLE ParentHandle; 239 ACPI_HANDLE NextChildHandle; 240 ACPI_HANDLE Dummy; 241 UINT32 Level; 242 243 244 ACPI_FUNCTION_TRACE (NsDeleteSubtree); 245 246 247 ParentHandle = StartHandle; 248 ChildHandle = NULL; 249 Level = 1; 250 251 /* 252 * Traverse the tree of objects until we bubble back up 253 * to where we started. 254 */ 255 while (Level > 0) 256 { 257 /* Attempt to get the next object in this scope */ 258 259 Status = AcpiGetNextObject (ACPI_TYPE_ANY, ParentHandle, 260 ChildHandle, &NextChildHandle); 261 262 ChildHandle = NextChildHandle; 263 264 /* Did we get a new object? */ 265 266 if (ACPI_SUCCESS (Status)) 267 { 268 /* Check if this object has any children */ 269 270 if (ACPI_SUCCESS (AcpiGetNextObject (ACPI_TYPE_ANY, ChildHandle, 271 NULL, &Dummy))) 272 { 273 /* 274 * There is at least one child of this object, 275 * visit the object 276 */ 277 Level++; 278 ParentHandle = ChildHandle; 279 ChildHandle = NULL; 280 } 281 } 282 else 283 { 284 /* 285 * No more children in this object, go back up to 286 * the object's parent 287 */ 288 Level--; 289 290 /* Delete all children now */ 291 292 AcpiNsDeleteChildren (ChildHandle); 293 294 ChildHandle = ParentHandle; 295 Status = AcpiGetParent (ParentHandle, &ParentHandle); 296 if (ACPI_FAILURE (Status)) 297 { 298 return_ACPI_STATUS (Status); 299 } 300 } 301 } 302 303 /* Now delete the starting object, and we are done */ 304 305 AcpiNsRemoveNode (ChildHandle); 306 return_ACPI_STATUS (AE_OK); 307 } 308 309 310 /******************************************************************************* 311 * 312 * FUNCTION: AcpiNsUnloadNameSpace 313 * 314 * PARAMETERS: Handle - Root of namespace subtree to be deleted 315 * 316 * RETURN: Status 317 * 318 * DESCRIPTION: Shrinks the namespace, typically in response to an undocking 319 * event. Deletes an entire subtree starting from (and 320 * including) the given handle. 321 * 322 ******************************************************************************/ 323 324 ACPI_STATUS 325 AcpiNsUnloadNamespace ( 326 ACPI_HANDLE Handle) 327 { 328 ACPI_STATUS Status; 329 330 331 ACPI_FUNCTION_TRACE (NsUnloadNameSpace); 332 333 334 /* Parameter validation */ 335 336 if (!AcpiGbl_RootNode) 337 { 338 return_ACPI_STATUS (AE_NO_NAMESPACE); 339 } 340 341 if (!Handle) 342 { 343 return_ACPI_STATUS (AE_BAD_PARAMETER); 344 } 345 346 /* This function does the real work */ 347 348 Status = AcpiNsDeleteSubtree (Handle); 349 350 return_ACPI_STATUS (Status); 351 } 352 #endif 353 #endif 354