Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /****************************************************************************** |
2 | * | |
3 | * Module Name: nsload - namespace loading/expanding/contracting procedures | |
4 | * | |
5 | *****************************************************************************/ | |
6 | ||
7 | /* | |
75a44ce0 | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
1da177e4 LT |
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 | ||
1da177e4 LT |
44 | #include <acpi/acpi.h> |
45 | #include <acpi/acnamesp.h> | |
46 | #include <acpi/acdispat.h> | |
f3d2e786 | 47 | #include <acpi/actables.h> |
1da177e4 | 48 | |
1da177e4 | 49 | #define _COMPONENT ACPI_NAMESPACE |
4be44fcd | 50 | ACPI_MODULE_NAME("nsload") |
1da177e4 | 51 | |
44f6c012 | 52 | /* Local prototypes */ |
44f6c012 | 53 | #ifdef ACPI_FUTURE_IMPLEMENTATION |
4be44fcd | 54 | acpi_status acpi_ns_unload_namespace(acpi_handle handle); |
44f6c012 | 55 | |
4be44fcd | 56 | static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); |
44f6c012 | 57 | #endif |
1da177e4 | 58 | |
44f6c012 | 59 | #ifndef ACPI_NO_METHOD_EXECUTION |
1da177e4 LT |
60 | /******************************************************************************* |
61 | * | |
62 | * FUNCTION: acpi_ns_load_table | |
63 | * | |
f3d2e786 | 64 | * PARAMETERS: table_index - Index for table to be loaded |
1da177e4 LT |
65 | * Node - Owning NS node |
66 | * | |
67 | * RETURN: Status | |
68 | * | |
69 | * DESCRIPTION: Load one ACPI table into the namespace | |
70 | * | |
71 | ******************************************************************************/ | |
72 | ||
73 | acpi_status | |
67a119f9 | 74 | acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) |
1da177e4 | 75 | { |
4be44fcd | 76 | acpi_status status; |
1da177e4 | 77 | |
b229cf92 | 78 | ACPI_FUNCTION_TRACE(ns_load_table); |
1da177e4 | 79 | |
1da177e4 LT |
80 | /* |
81 | * Parse the table and load the namespace with all named | |
82 | * objects found within. Control methods are NOT parsed | |
83 | * at this time. In fact, the control methods cannot be | |
84 | * parsed until the entire namespace is loaded, because | |
85 | * if a control method makes a forward reference (call) | |
86 | * to another control method, we can't continue parsing | |
87 | * because we don't know how many arguments to parse next! | |
88 | */ | |
f3d2e786 BM |
89 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
90 | if (ACPI_FAILURE(status)) { | |
91 | return_ACPI_STATUS(status); | |
92 | } | |
93 | ||
94 | /* If table already loaded into namespace, just return */ | |
95 | ||
96 | if (acpi_tb_is_table_loaded(table_index)) { | |
97 | status = AE_ALREADY_EXISTS; | |
98 | goto unlock; | |
99 | } | |
100 | ||
4be44fcd LB |
101 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
102 | "**** Loading table into namespace ****\n")); | |
1da177e4 | 103 | |
f3d2e786 | 104 | status = acpi_tb_allocate_owner_id(table_index); |
4be44fcd | 105 | if (ACPI_FAILURE(status)) { |
f3d2e786 | 106 | goto unlock; |
1da177e4 LT |
107 | } |
108 | ||
7f4ac9f9 | 109 | status = acpi_ns_parse_table(table_index, node); |
f3d2e786 BM |
110 | if (ACPI_SUCCESS(status)) { |
111 | acpi_tb_set_table_loaded_flag(table_index, TRUE); | |
112 | } else { | |
1d18c058 | 113 | (void)acpi_tb_release_owner_id(table_index); |
f3d2e786 BM |
114 | } |
115 | ||
116 | unlock: | |
4be44fcd | 117 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
1da177e4 | 118 | |
4be44fcd LB |
119 | if (ACPI_FAILURE(status)) { |
120 | return_ACPI_STATUS(status); | |
1da177e4 LT |
121 | } |
122 | ||
123 | /* | |
124 | * Now we can parse the control methods. We always parse | |
125 | * them here for a sanity check, and if configured for | |
126 | * just-in-time parsing, we delete the control method | |
127 | * parse trees. | |
128 | */ | |
4be44fcd LB |
129 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
130 | "**** Begin Table Method Parsing and Object Initialization ****\n")); | |
1da177e4 | 131 | |
f3d2e786 | 132 | status = acpi_ds_initialize_objects(table_index, node); |
1da177e4 | 133 | |
4be44fcd LB |
134 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
135 | "**** Completed Table Method Parsing and Object Initialization ****\n")); | |
1da177e4 | 136 | |
4be44fcd | 137 | return_ACPI_STATUS(status); |
1da177e4 LT |
138 | } |
139 | ||
f3d2e786 | 140 | #ifdef ACPI_OBSOLETE_FUNCTIONS |
1da177e4 LT |
141 | /******************************************************************************* |
142 | * | |
143 | * FUNCTION: acpi_load_namespace | |
144 | * | |
145 | * PARAMETERS: None | |
146 | * | |
147 | * RETURN: Status | |
148 | * | |
149 | * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. | |
150 | * (DSDT points to either the BIOS or a buffer.) | |
151 | * | |
152 | ******************************************************************************/ | |
153 | ||
4be44fcd | 154 | acpi_status acpi_ns_load_namespace(void) |
1da177e4 | 155 | { |
4be44fcd | 156 | acpi_status status; |
1da177e4 | 157 | |
b229cf92 | 158 | ACPI_FUNCTION_TRACE(acpi_load_name_space); |
1da177e4 LT |
159 | |
160 | /* There must be at least a DSDT installed */ | |
161 | ||
162 | if (acpi_gbl_DSDT == NULL) { | |
b8e4d893 | 163 | ACPI_ERROR((AE_INFO, "DSDT is not in memory")); |
4be44fcd | 164 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); |
1da177e4 LT |
165 | } |
166 | ||
167 | /* | |
168 | * Load the namespace. The DSDT is required, | |
169 | * but the SSDT and PSDT tables are optional. | |
170 | */ | |
b229cf92 | 171 | status = acpi_ns_load_table_by_type(ACPI_TABLE_ID_DSDT); |
4be44fcd LB |
172 | if (ACPI_FAILURE(status)) { |
173 | return_ACPI_STATUS(status); | |
1da177e4 LT |
174 | } |
175 | ||
176 | /* Ignore exceptions from these */ | |
177 | ||
b229cf92 BM |
178 | (void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_SSDT); |
179 | (void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_PSDT); | |
1da177e4 | 180 | |
4be44fcd LB |
181 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
182 | "ACPI Namespace successfully loaded at root %p\n", | |
183 | acpi_gbl_root_node)); | |
1da177e4 | 184 | |
4be44fcd | 185 | return_ACPI_STATUS(status); |
1da177e4 | 186 | } |
f3d2e786 | 187 | #endif |
1da177e4 | 188 | |
44f6c012 | 189 | #ifdef ACPI_FUTURE_IMPLEMENTATION |
1da177e4 LT |
190 | /******************************************************************************* |
191 | * | |
192 | * FUNCTION: acpi_ns_delete_subtree | |
193 | * | |
194 | * PARAMETERS: start_handle - Handle in namespace where search begins | |
195 | * | |
196 | * RETURNS Status | |
197 | * | |
198 | * DESCRIPTION: Walks the namespace starting at the given handle and deletes | |
199 | * all objects, entries, and scopes in the entire subtree. | |
200 | * | |
201 | * Namespace/Interpreter should be locked or the subsystem should | |
202 | * be in shutdown before this routine is called. | |
203 | * | |
204 | ******************************************************************************/ | |
205 | ||
4be44fcd | 206 | static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle) |
1da177e4 | 207 | { |
4be44fcd LB |
208 | acpi_status status; |
209 | acpi_handle child_handle; | |
210 | acpi_handle parent_handle; | |
211 | acpi_handle next_child_handle; | |
212 | acpi_handle dummy; | |
213 | u32 level; | |
1da177e4 | 214 | |
b229cf92 | 215 | ACPI_FUNCTION_TRACE(ns_delete_subtree); |
1da177e4 LT |
216 | |
217 | parent_handle = start_handle; | |
218 | child_handle = NULL; | |
4be44fcd | 219 | level = 1; |
1da177e4 LT |
220 | |
221 | /* | |
222 | * Traverse the tree of objects until we bubble back up | |
223 | * to where we started. | |
224 | */ | |
225 | while (level > 0) { | |
52fc0b02 | 226 | |
1da177e4 LT |
227 | /* Attempt to get the next object in this scope */ |
228 | ||
4be44fcd LB |
229 | status = acpi_get_next_object(ACPI_TYPE_ANY, parent_handle, |
230 | child_handle, &next_child_handle); | |
1da177e4 LT |
231 | |
232 | child_handle = next_child_handle; | |
233 | ||
234 | /* Did we get a new object? */ | |
235 | ||
4be44fcd | 236 | if (ACPI_SUCCESS(status)) { |
52fc0b02 | 237 | |
1da177e4 LT |
238 | /* Check if this object has any children */ |
239 | ||
4be44fcd LB |
240 | if (ACPI_SUCCESS |
241 | (acpi_get_next_object | |
242 | (ACPI_TYPE_ANY, child_handle, NULL, &dummy))) { | |
1da177e4 LT |
243 | /* |
244 | * There is at least one child of this object, | |
245 | * visit the object | |
246 | */ | |
247 | level++; | |
248 | parent_handle = child_handle; | |
249 | child_handle = NULL; | |
250 | } | |
4be44fcd | 251 | } else { |
1da177e4 LT |
252 | /* |
253 | * No more children in this object, go back up to | |
254 | * the object's parent | |
255 | */ | |
256 | level--; | |
257 | ||
258 | /* Delete all children now */ | |
259 | ||
4be44fcd | 260 | acpi_ns_delete_children(child_handle); |
1da177e4 LT |
261 | |
262 | child_handle = parent_handle; | |
4be44fcd LB |
263 | status = acpi_get_parent(parent_handle, &parent_handle); |
264 | if (ACPI_FAILURE(status)) { | |
265 | return_ACPI_STATUS(status); | |
1da177e4 LT |
266 | } |
267 | } | |
268 | } | |
269 | ||
270 | /* Now delete the starting object, and we are done */ | |
271 | ||
4be44fcd | 272 | acpi_ns_delete_node(child_handle); |
1da177e4 | 273 | |
4be44fcd | 274 | return_ACPI_STATUS(AE_OK); |
1da177e4 LT |
275 | } |
276 | ||
1da177e4 LT |
277 | /******************************************************************************* |
278 | * | |
279 | * FUNCTION: acpi_ns_unload_name_space | |
280 | * | |
281 | * PARAMETERS: Handle - Root of namespace subtree to be deleted | |
282 | * | |
283 | * RETURN: Status | |
284 | * | |
285 | * DESCRIPTION: Shrinks the namespace, typically in response to an undocking | |
286 | * event. Deletes an entire subtree starting from (and | |
287 | * including) the given handle. | |
288 | * | |
289 | ******************************************************************************/ | |
290 | ||
4be44fcd | 291 | acpi_status acpi_ns_unload_namespace(acpi_handle handle) |
1da177e4 | 292 | { |
4be44fcd | 293 | acpi_status status; |
1da177e4 | 294 | |
b229cf92 | 295 | ACPI_FUNCTION_TRACE(ns_unload_name_space); |
1da177e4 LT |
296 | |
297 | /* Parameter validation */ | |
298 | ||
299 | if (!acpi_gbl_root_node) { | |
4be44fcd | 300 | return_ACPI_STATUS(AE_NO_NAMESPACE); |
1da177e4 LT |
301 | } |
302 | ||
303 | if (!handle) { | |
4be44fcd | 304 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
1da177e4 LT |
305 | } |
306 | ||
307 | /* This function does the real work */ | |
308 | ||
4be44fcd | 309 | status = acpi_ns_delete_subtree(handle); |
1da177e4 | 310 | |
4be44fcd | 311 | return_ACPI_STATUS(status); |
1da177e4 | 312 | } |
44f6c012 | 313 | #endif |
1da177e4 | 314 | #endif |