nsload.c revision 1.1.1.2.4.2 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
357