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