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