This source file includes following definitions.
- ACPI_MODULE_NAME
- acpi_ns_delete_node
- acpi_ns_remove_node
- acpi_ns_install_node
- acpi_ns_delete_children
- acpi_ns_delete_namespace_subtree
- acpi_ns_delete_namespace_by_owner
1
2
3
4
5
6
7
8 #include <acpi/acpi.h>
9 #include "accommon.h"
10 #include "acnamesp.h"
11
12 #define _COMPONENT ACPI_NAMESPACE
13 ACPI_MODULE_NAME("nsalloc")
14
15
16
17
18
19
20
21
22
23
24
25
26 struct acpi_namespace_node *acpi_ns_create_node(u32 name)
27 {
28 struct acpi_namespace_node *node;
29 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
30 u32 temp;
31 #endif
32
33 ACPI_FUNCTION_TRACE(ns_create_node);
34
35 node = acpi_os_acquire_object(acpi_gbl_namespace_cache);
36 if (!node) {
37 return_PTR(NULL);
38 }
39
40 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++);
41
42 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
43 temp = acpi_gbl_ns_node_list->total_allocated -
44 acpi_gbl_ns_node_list->total_freed;
45 if (temp > acpi_gbl_ns_node_list->max_occupied) {
46 acpi_gbl_ns_node_list->max_occupied = temp;
47 }
48 #endif
49
50 node->name.integer = name;
51 ACPI_SET_DESCRIPTOR_TYPE(node, ACPI_DESC_TYPE_NAMED);
52 return_PTR(node);
53 }
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 void acpi_ns_delete_node(struct acpi_namespace_node *node)
71 {
72 union acpi_operand_object *obj_desc;
73 union acpi_operand_object *next_desc;
74
75 ACPI_FUNCTION_NAME(ns_delete_node);
76
77 if (!node) {
78 return_VOID;
79 }
80
81
82
83 acpi_ns_detach_object(node);
84
85
86
87
88
89
90
91 obj_desc = node->object;
92 while (obj_desc && (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
93
94
95
96 if (obj_desc->data.handler) {
97 obj_desc->data.handler(node, obj_desc->data.pointer);
98 }
99
100 next_desc = obj_desc->common.next_object;
101 acpi_ut_remove_reference(obj_desc);
102 obj_desc = next_desc;
103 }
104
105
106
107 if (node == acpi_gbl_root_node) {
108 return;
109 }
110
111
112
113 (void)acpi_os_release_object(acpi_gbl_namespace_cache, node);
114
115 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
116 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Node %p, Remaining %X\n",
117 node, acpi_gbl_current_node_count));
118 }
119
120
121
122
123
124
125
126
127
128
129
130
131
132 void acpi_ns_remove_node(struct acpi_namespace_node *node)
133 {
134 struct acpi_namespace_node *parent_node;
135 struct acpi_namespace_node *prev_node;
136 struct acpi_namespace_node *next_node;
137
138 ACPI_FUNCTION_TRACE_PTR(ns_remove_node, node);
139
140 parent_node = node->parent;
141
142 prev_node = NULL;
143 next_node = parent_node->child;
144
145
146
147 while (next_node != node) {
148 prev_node = next_node;
149 next_node = next_node->peer;
150 }
151
152 if (prev_node) {
153
154
155
156 prev_node->peer = node->peer;
157 } else {
158
159
160
161
162 parent_node->child = node->peer;
163 }
164
165
166
167 acpi_ns_delete_node(node);
168 return_VOID;
169 }
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191 void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namespace_node *parent_node,
192 struct acpi_namespace_node *node,
193 acpi_object_type type)
194 {
195 acpi_owner_id owner_id = 0;
196 struct acpi_namespace_node *child_node;
197
198 ACPI_FUNCTION_TRACE(ns_install_node);
199
200 if (walk_state) {
201
202
203
204
205 owner_id = walk_state->owner_id;
206
207 if ((walk_state->method_desc) &&
208 (parent_node != walk_state->method_node)) {
209
210
211
212
213
214
215 walk_state->method_desc->method.info_flags |=
216 ACPI_METHOD_MODIFIED_NAMESPACE;
217 }
218 }
219
220
221
222 node->peer = NULL;
223 node->parent = parent_node;
224 child_node = parent_node->child;
225
226 if (!child_node) {
227 parent_node->child = node;
228 } else {
229
230
231 while (child_node->peer) {
232 child_node = child_node->peer;
233 }
234
235 child_node->peer = node;
236 }
237
238
239
240 node->owner_id = owner_id;
241 node->type = (u8) type;
242
243 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
244 "%4.4s (%s) [Node %p Owner %3.3X] added to %4.4s (%s) [Node %p]\n",
245 acpi_ut_get_node_name(node),
246 acpi_ut_get_type_name(node->type), node, owner_id,
247 acpi_ut_get_node_name(parent_node),
248 acpi_ut_get_type_name(parent_node->type),
249 parent_node));
250
251 return_VOID;
252 }
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267 void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
268 {
269 struct acpi_namespace_node *next_node;
270 struct acpi_namespace_node *node_to_delete;
271
272 ACPI_FUNCTION_TRACE_PTR(ns_delete_children, parent_node);
273
274 if (!parent_node) {
275 return_VOID;
276 }
277
278
279
280 next_node = parent_node->child;
281 while (next_node) {
282
283
284
285 if (next_node->child) {
286 ACPI_ERROR((AE_INFO, "Found a grandchild! P=%p C=%p",
287 parent_node, next_node));
288 }
289
290
291
292
293
294 node_to_delete = next_node;
295 next_node = next_node->peer;
296 acpi_ns_delete_node(node_to_delete);
297 };
298
299
300
301 parent_node->child = NULL;
302 return_VOID;
303 }
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318 void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
319 {
320 struct acpi_namespace_node *child_node = NULL;
321 u32 level = 1;
322 acpi_status status;
323
324 ACPI_FUNCTION_TRACE(ns_delete_namespace_subtree);
325
326 if (!parent_node) {
327 return_VOID;
328 }
329
330
331
332 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
333 if (ACPI_FAILURE(status)) {
334 return_VOID;
335 }
336
337
338
339
340
341 while (level > 0) {
342
343
344
345 child_node = acpi_ns_get_next_node(parent_node, child_node);
346 if (child_node) {
347
348
349
350 acpi_ns_detach_object(child_node);
351
352
353
354 if (child_node->child) {
355
356
357
358
359 level++;
360 parent_node = child_node;
361 child_node = NULL;
362 }
363 } else {
364
365
366
367
368 level--;
369
370
371
372
373
374 acpi_ns_delete_children(parent_node);
375
376
377
378 child_node = parent_node;
379
380
381
382 parent_node = parent_node->parent;
383 }
384 }
385
386 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
387 return_VOID;
388 }
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406 void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
407 {
408 struct acpi_namespace_node *child_node;
409 struct acpi_namespace_node *deletion_node;
410 struct acpi_namespace_node *parent_node;
411 u32 level;
412 acpi_status status;
413
414 ACPI_FUNCTION_TRACE_U32(ns_delete_namespace_by_owner, owner_id);
415
416 if (owner_id == 0) {
417 return_VOID;
418 }
419
420
421
422 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
423 if (ACPI_FAILURE(status)) {
424 return_VOID;
425 }
426
427 deletion_node = NULL;
428 parent_node = acpi_gbl_root_node;
429 child_node = NULL;
430 level = 1;
431
432
433
434
435
436 while (level > 0) {
437
438
439
440
441 child_node = acpi_ns_get_next_node(parent_node, child_node);
442
443 if (deletion_node) {
444 acpi_ns_delete_children(deletion_node);
445 acpi_ns_remove_node(deletion_node);
446 deletion_node = NULL;
447 }
448
449 if (child_node) {
450 if (child_node->owner_id == owner_id) {
451
452
453
454 acpi_ns_detach_object(child_node);
455 }
456
457
458
459 if (child_node->child) {
460
461
462
463
464 level++;
465 parent_node = child_node;
466 child_node = NULL;
467 } else if (child_node->owner_id == owner_id) {
468 deletion_node = child_node;
469 }
470 } else {
471
472
473
474
475 level--;
476 if (level != 0) {
477 if (parent_node->owner_id == owner_id) {
478 deletion_node = parent_node;
479 }
480 }
481
482
483
484 child_node = parent_node;
485
486
487
488 parent_node = parent_node->parent;
489 }
490 }
491
492 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
493 return_VOID;
494 }