1 /****************************************************************************** 2 * 3 * Module Name: nsload - namespace loading/expanding/contracting procedures 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, 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 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 /* 132 * On error, delete any namespace objects created by this table. 133 * We cannot initialize these objects, so delete them. There are 134 * a couple of expecially bad cases: 135 * AE_ALREADY_EXISTS - namespace collision. 136 * AE_NOT_FOUND - the target of a Scope operator does not 137 * exist. This target of Scope must already exist in the 138 * namespace, as per the ACPI specification. 139 */ 140 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 141 AcpiNsDeleteNamespaceByOwner ( 142 AcpiGbl_RootTableList.Tables[TableIndex].OwnerId); 143 AcpiTbReleaseOwnerId (TableIndex); 144 145 return_ACPI_STATUS (Status); 146 } 147 148 Unlock: 149 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 150 151 if (ACPI_FAILURE (Status)) 152 { 153 return_ACPI_STATUS (Status); 154 } 155 156 /* 157 * Now we can parse the control methods. We always parse 158 * them here for a sanity check, and if configured for 159 * just-in-time parsing, we delete the control method 160 * parse trees. 161 */ 162 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 163 "**** Begin Table Object Initialization\n")); 164 165 Status = AcpiDsInitializeObjects (TableIndex, Node); 166 167 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 168 "**** Completed Table Object Initialization\n")); 169 170 return_ACPI_STATUS (Status); 171 } 172 173 174 #ifdef ACPI_OBSOLETE_FUNCTIONS 175 /******************************************************************************* 176 * 177 * FUNCTION: AcpiLoadNamespace 178 * 179 * PARAMETERS: None 180 * 181 * RETURN: Status 182 * 183 * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. 184 * (DSDT points to either the BIOS or a buffer.) 185 * 186 ******************************************************************************/ 187 188 ACPI_STATUS 189 AcpiNsLoadNamespace ( 190 void) 191 { 192 ACPI_STATUS Status; 193 194 195 ACPI_FUNCTION_TRACE (AcpiLoadNameSpace); 196 197 198 /* There must be at least a DSDT installed */ 199 200 if (AcpiGbl_DSDT == NULL) 201 { 202 ACPI_ERROR ((AE_INFO, "DSDT is not in memory")); 203 return_ACPI_STATUS (AE_NO_ACPI_TABLES); 204 } 205 206 /* 207 * Load the namespace. The DSDT is required, 208 * but the SSDT and PSDT tables are optional. 209 */ 210 Status = AcpiNsLoadTableByType (ACPI_TABLE_ID_DSDT); 211 if (ACPI_FAILURE (Status)) 212 { 213 return_ACPI_STATUS (Status); 214 } 215 216 /* Ignore exceptions from these */ 217 218 (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_SSDT); 219 (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_PSDT); 220 221 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 222 "ACPI Namespace successfully loaded at root %p\n", 223 AcpiGbl_RootNode)); 224 225 return_ACPI_STATUS (Status); 226 } 227 #endif 228 229 #ifdef ACPI_FUTURE_IMPLEMENTATION 230 /******************************************************************************* 231 * 232 * FUNCTION: AcpiNsDeleteSubtree 233 * 234 * PARAMETERS: StartHandle - Handle in namespace where search begins 235 * 236 * RETURNS Status 237 * 238 * DESCRIPTION: Walks the namespace starting at the given handle and deletes 239 * all objects, entries, and scopes in the entire subtree. 240 * 241 * Namespace/Interpreter should be locked or the subsystem should 242 * be in shutdown before this routine is called. 243 * 244 ******************************************************************************/ 245 246 static ACPI_STATUS 247 AcpiNsDeleteSubtree ( 248 ACPI_HANDLE StartHandle) 249 { 250 ACPI_STATUS Status; 251 ACPI_HANDLE ChildHandle; 252 ACPI_HANDLE ParentHandle; 253 ACPI_HANDLE NextChildHandle; 254 ACPI_HANDLE Dummy; 255 UINT32 Level; 256 257 258 ACPI_FUNCTION_TRACE (NsDeleteSubtree); 259 260 261 ParentHandle = StartHandle; 262 ChildHandle = NULL; 263 Level = 1; 264 265 /* 266 * Traverse the tree of objects until we bubble back up 267 * to where we started. 268 */ 269 while (Level > 0) 270 { 271 /* Attempt to get the next object in this scope */ 272 273 Status = AcpiGetNextObject (ACPI_TYPE_ANY, ParentHandle, 274 ChildHandle, &NextChildHandle); 275 276 ChildHandle = NextChildHandle; 277 278 /* Did we get a new object? */ 279 280 if (ACPI_SUCCESS (Status)) 281 { 282 /* Check if this object has any children */ 283 284 if (ACPI_SUCCESS (AcpiGetNextObject (ACPI_TYPE_ANY, ChildHandle, 285 NULL, &Dummy))) 286 { 287 /* 288 * There is at least one child of this object, 289 * visit the object 290 */ 291 Level++; 292 ParentHandle = ChildHandle; 293 ChildHandle = NULL; 294 } 295 } 296 else 297 { 298 /* 299 * No more children in this object, go back up to 300 * the object's parent 301 */ 302 Level--; 303 304 /* Delete all children now */ 305 306 AcpiNsDeleteChildren (ChildHandle); 307 308 ChildHandle = ParentHandle; 309 Status = AcpiGetParent (ParentHandle, &ParentHandle); 310 if (ACPI_FAILURE (Status)) 311 { 312 return_ACPI_STATUS (Status); 313 } 314 } 315 } 316 317 /* Now delete the starting object, and we are done */ 318 319 AcpiNsRemoveNode (ChildHandle); 320 return_ACPI_STATUS (AE_OK); 321 } 322 323 324 /******************************************************************************* 325 * 326 * FUNCTION: AcpiNsUnloadNameSpace 327 * 328 * PARAMETERS: Handle - Root of namespace subtree to be deleted 329 * 330 * RETURN: Status 331 * 332 * DESCRIPTION: Shrinks the namespace, typically in response to an undocking 333 * event. Deletes an entire subtree starting from (and 334 * including) the given handle. 335 * 336 ******************************************************************************/ 337 338 ACPI_STATUS 339 AcpiNsUnloadNamespace ( 340 ACPI_HANDLE Handle) 341 { 342 ACPI_STATUS Status; 343 344 345 ACPI_FUNCTION_TRACE (NsUnloadNameSpace); 346 347 348 /* Parameter validation */ 349 350 if (!AcpiGbl_RootNode) 351 { 352 return_ACPI_STATUS (AE_NO_NAMESPACE); 353 } 354 355 if (!Handle) 356 { 357 return_ACPI_STATUS (AE_BAD_PARAMETER); 358 } 359 360 /* This function does the real work */ 361 362 Status = AcpiNsDeleteSubtree (Handle); 363 364 return_ACPI_STATUS (Status); 365 } 366 #endif 367 #endif 368