aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/namespace/nsalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/namespace/nsalloc.c')
-rw-r--r--drivers/acpi/namespace/nsalloc.c232
1 files changed, 94 insertions, 138 deletions
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
index 21d560decbf9..cc7a85f8cfe6 100644
--- a/drivers/acpi/namespace/nsalloc.c
+++ b/drivers/acpi/namespace/nsalloc.c
@@ -41,20 +41,14 @@
41 * POSSIBILITY OF SUCH DAMAGES. 41 * POSSIBILITY OF SUCH DAMAGES.
42 */ 42 */
43 43
44
45#include <acpi/acpi.h> 44#include <acpi/acpi.h>
46#include <acpi/acnamesp.h> 45#include <acpi/acnamesp.h>
47 46
48
49#define _COMPONENT ACPI_NAMESPACE 47#define _COMPONENT ACPI_NAMESPACE
50 ACPI_MODULE_NAME ("nsalloc") 48ACPI_MODULE_NAME("nsalloc")
51 49
52/* Local prototypes */ 50/* Local prototypes */
53 51static void acpi_ns_remove_reference(struct acpi_namespace_node *node);
54static void
55acpi_ns_remove_reference (
56 struct acpi_namespace_node *node);
57
58 52
59/******************************************************************************* 53/*******************************************************************************
60 * 54 *
@@ -68,31 +62,26 @@ acpi_ns_remove_reference (
68 * 62 *
69 ******************************************************************************/ 63 ******************************************************************************/
70 64
71struct acpi_namespace_node * 65struct acpi_namespace_node *acpi_ns_create_node(u32 name)
72acpi_ns_create_node (
73 u32 name)
74{ 66{
75 struct acpi_namespace_node *node; 67 struct acpi_namespace_node *node;
76
77 68
78 ACPI_FUNCTION_TRACE ("ns_create_node"); 69 ACPI_FUNCTION_TRACE("ns_create_node");
79 70
80 71 node = ACPI_MEM_CALLOCATE(sizeof(struct acpi_namespace_node));
81 node = ACPI_MEM_CALLOCATE (sizeof (struct acpi_namespace_node));
82 if (!node) { 72 if (!node) {
83 return_PTR (NULL); 73 return_PTR(NULL);
84 } 74 }
85 75
86 ACPI_MEM_TRACKING (acpi_gbl_ns_node_list->total_allocated++); 76 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++);
87 77
88 node->name.integer = name; 78 node->name.integer = name;
89 node->reference_count = 1; 79 node->reference_count = 1;
90 ACPI_SET_DESCRIPTOR_TYPE (node, ACPI_DESC_TYPE_NAMED); 80 ACPI_SET_DESCRIPTOR_TYPE(node, ACPI_DESC_TYPE_NAMED);
91 81
92 return_PTR (node); 82 return_PTR(node);
93} 83}
94 84
95
96/******************************************************************************* 85/*******************************************************************************
97 * 86 *
98 * FUNCTION: acpi_ns_delete_node 87 * FUNCTION: acpi_ns_delete_node
@@ -105,19 +94,15 @@ acpi_ns_create_node (
105 * 94 *
106 ******************************************************************************/ 95 ******************************************************************************/
107 96
108void 97void acpi_ns_delete_node(struct acpi_namespace_node *node)
109acpi_ns_delete_node (
110 struct acpi_namespace_node *node)
111{ 98{
112 struct acpi_namespace_node *parent_node; 99 struct acpi_namespace_node *parent_node;
113 struct acpi_namespace_node *prev_node; 100 struct acpi_namespace_node *prev_node;
114 struct acpi_namespace_node *next_node; 101 struct acpi_namespace_node *next_node;
115
116
117 ACPI_FUNCTION_TRACE_PTR ("ns_delete_node", node);
118 102
103 ACPI_FUNCTION_TRACE_PTR("ns_delete_node", node);
119 104
120 parent_node = acpi_ns_get_parent_node (node); 105 parent_node = acpi_ns_get_parent_node(node);
121 106
122 prev_node = NULL; 107 prev_node = NULL;
123 next_node = parent_node->child; 108 next_node = parent_node->child;
@@ -136,32 +121,29 @@ acpi_ns_delete_node (
136 if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { 121 if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
137 prev_node->flags |= ANOBJ_END_OF_PEER_LIST; 122 prev_node->flags |= ANOBJ_END_OF_PEER_LIST;
138 } 123 }
139 } 124 } else {
140 else {
141 /* Node is first child (has no previous peer) */ 125 /* Node is first child (has no previous peer) */
142 126
143 if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { 127 if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
144 /* No peers at all */ 128 /* No peers at all */
145 129
146 parent_node->child = NULL; 130 parent_node->child = NULL;
147 } 131 } else { /* Link peer list to parent */
148 else { /* Link peer list to parent */
149 132
150 parent_node->child = next_node->peer; 133 parent_node->child = next_node->peer;
151 } 134 }
152 } 135 }
153 136
154 ACPI_MEM_TRACKING (acpi_gbl_ns_node_list->total_freed++); 137 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
155 138
156 /* 139 /*
157 * Detach an object if there is one then delete the node 140 * Detach an object if there is one then delete the node
158 */ 141 */
159 acpi_ns_detach_object (node); 142 acpi_ns_detach_object(node);
160 ACPI_MEM_FREE (node); 143 ACPI_MEM_FREE(node);
161 return_VOID; 144 return_VOID;
162} 145}
163 146
164
165/******************************************************************************* 147/*******************************************************************************
166 * 148 *
167 * FUNCTION: acpi_ns_install_node 149 * FUNCTION: acpi_ns_install_node
@@ -182,19 +164,14 @@ acpi_ns_delete_node (
182 * 164 *
183 ******************************************************************************/ 165 ******************************************************************************/
184 166
185void 167void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namespace_node *parent_node, /* Parent */
186acpi_ns_install_node ( 168 struct acpi_namespace_node *node, /* New Child */
187 struct acpi_walk_state *walk_state, 169 acpi_object_type type)
188 struct acpi_namespace_node *parent_node, /* Parent */
189 struct acpi_namespace_node *node, /* New Child*/
190 acpi_object_type type)
191{ 170{
192 acpi_owner_id owner_id = 0; 171 acpi_owner_id owner_id = 0;
193 struct acpi_namespace_node *child_node; 172 struct acpi_namespace_node *child_node;
194
195
196 ACPI_FUNCTION_TRACE ("ns_install_node");
197 173
174 ACPI_FUNCTION_TRACE("ns_install_node");
198 175
199 /* 176 /*
200 * Get the owner ID from the Walk state 177 * Get the owner ID from the Walk state
@@ -212,8 +189,7 @@ acpi_ns_install_node (
212 parent_node->child = node; 189 parent_node->child = node;
213 node->flags |= ANOBJ_END_OF_PEER_LIST; 190 node->flags |= ANOBJ_END_OF_PEER_LIST;
214 node->peer = parent_node; 191 node->peer = parent_node;
215 } 192 } else {
216 else {
217 while (!(child_node->flags & ANOBJ_END_OF_PEER_LIST)) { 193 while (!(child_node->flags & ANOBJ_END_OF_PEER_LIST)) {
218 child_node = child_node->peer; 194 child_node = child_node->peer;
219 } 195 }
@@ -232,24 +208,25 @@ acpi_ns_install_node (
232 node->owner_id = owner_id; 208 node->owner_id = owner_id;
233 node->type = (u8) type; 209 node->type = (u8) type;
234 210
235 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 211 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
236 "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n", 212 "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n",
237 acpi_ut_get_node_name (node), acpi_ut_get_type_name (node->type), node, owner_id, 213 acpi_ut_get_node_name(node),
238 acpi_ut_get_node_name (parent_node), acpi_ut_get_type_name (parent_node->type), 214 acpi_ut_get_type_name(node->type), node, owner_id,
239 parent_node)); 215 acpi_ut_get_node_name(parent_node),
216 acpi_ut_get_type_name(parent_node->type),
217 parent_node));
240 218
241 /* 219 /*
242 * Increment the reference count(s) of all parents up to 220 * Increment the reference count(s) of all parents up to
243 * the root! 221 * the root!
244 */ 222 */
245 while ((node = acpi_ns_get_parent_node (node)) != NULL) { 223 while ((node = acpi_ns_get_parent_node(node)) != NULL) {
246 node->reference_count++; 224 node->reference_count++;
247 } 225 }
248 226
249 return_VOID; 227 return_VOID;
250} 228}
251 229
252
253/******************************************************************************* 230/*******************************************************************************
254 * 231 *
255 * FUNCTION: acpi_ns_delete_children 232 * FUNCTION: acpi_ns_delete_children
@@ -263,18 +240,14 @@ acpi_ns_install_node (
263 * 240 *
264 ******************************************************************************/ 241 ******************************************************************************/
265 242
266void 243void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
267acpi_ns_delete_children (
268 struct acpi_namespace_node *parent_node)
269{ 244{
270 struct acpi_namespace_node *child_node; 245 struct acpi_namespace_node *child_node;
271 struct acpi_namespace_node *next_node; 246 struct acpi_namespace_node *next_node;
272 struct acpi_namespace_node *node; 247 struct acpi_namespace_node *node;
273 u8 flags; 248 u8 flags;
274
275
276 ACPI_FUNCTION_TRACE_PTR ("ns_delete_children", parent_node);
277 249
250 ACPI_FUNCTION_TRACE_PTR("ns_delete_children", parent_node);
278 251
279 if (!parent_node) { 252 if (!parent_node) {
280 return_VOID; 253 return_VOID;
@@ -293,48 +266,48 @@ acpi_ns_delete_children (
293 do { 266 do {
294 /* Get the things we need */ 267 /* Get the things we need */
295 268
296 next_node = child_node->peer; 269 next_node = child_node->peer;
297 flags = child_node->flags; 270 flags = child_node->flags;
298 271
299 /* Grandchildren should have all been deleted already */ 272 /* Grandchildren should have all been deleted already */
300 273
301 if (child_node->child) { 274 if (child_node->child) {
302 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found a grandchild! P=%p C=%p\n", 275 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
303 parent_node, child_node)); 276 "Found a grandchild! P=%p C=%p\n",
277 parent_node, child_node));
304 } 278 }
305 279
306 /* Now we can free this child object */ 280 /* Now we can free this child object */
307 281
308 ACPI_MEM_TRACKING (acpi_gbl_ns_node_list->total_freed++); 282 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
309 283
310 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n", 284 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
311 child_node, acpi_gbl_current_node_count)); 285 "Object %p, Remaining %X\n", child_node,
286 acpi_gbl_current_node_count));
312 287
313 /* 288 /*
314 * Detach an object if there is one, then free the child node 289 * Detach an object if there is one, then free the child node
315 */ 290 */
316 acpi_ns_detach_object (child_node); 291 acpi_ns_detach_object(child_node);
317 292
318 /* 293 /*
319 * Decrement the reference count(s) of all parents up to 294 * Decrement the reference count(s) of all parents up to
320 * the root! (counts were incremented when the node was created) 295 * the root! (counts were incremented when the node was created)
321 */ 296 */
322 node = child_node; 297 node = child_node;
323 while ((node = acpi_ns_get_parent_node (node)) != NULL) { 298 while ((node = acpi_ns_get_parent_node(node)) != NULL) {
324 node->reference_count--; 299 node->reference_count--;
325 } 300 }
326 301
327 /* There should be only one reference remaining on this node */ 302 /* There should be only one reference remaining on this node */
328 303
329 if (child_node->reference_count != 1) { 304 if (child_node->reference_count != 1) {
330 ACPI_REPORT_WARNING (( 305 ACPI_REPORT_WARNING(("Existing references (%d) on node being deleted (%p)\n", child_node->reference_count, child_node));
331 "Existing references (%d) on node being deleted (%p)\n",
332 child_node->reference_count, child_node));
333 } 306 }
334 307
335 /* Now we can delete the node */ 308 /* Now we can delete the node */
336 309
337 ACPI_MEM_FREE (child_node); 310 ACPI_MEM_FREE(child_node);
338 311
339 /* And move on to the next child in the list */ 312 /* And move on to the next child in the list */
340 313
@@ -342,7 +315,6 @@ acpi_ns_delete_children (
342 315
343 } while (!(flags & ANOBJ_END_OF_PEER_LIST)); 316 } while (!(flags & ANOBJ_END_OF_PEER_LIST));
344 317
345
346 /* Clear the parent's child pointer */ 318 /* Clear the parent's child pointer */
347 319
348 parent_node->child = NULL; 320 parent_node->child = NULL;
@@ -350,7 +322,6 @@ acpi_ns_delete_children (
350 return_VOID; 322 return_VOID;
351} 323}
352 324
353
354/******************************************************************************* 325/*******************************************************************************
355 * 326 *
356 * FUNCTION: acpi_ns_delete_namespace_subtree 327 * FUNCTION: acpi_ns_delete_namespace_subtree
@@ -364,16 +335,12 @@ acpi_ns_delete_children (
364 * 335 *
365 ******************************************************************************/ 336 ******************************************************************************/
366 337
367void 338void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
368acpi_ns_delete_namespace_subtree (
369 struct acpi_namespace_node *parent_node)
370{ 339{
371 struct acpi_namespace_node *child_node = NULL; 340 struct acpi_namespace_node *child_node = NULL;
372 u32 level = 1; 341 u32 level = 1;
373
374
375 ACPI_FUNCTION_TRACE ("ns_delete_namespace_subtree");
376 342
343 ACPI_FUNCTION_TRACE("ns_delete_namespace_subtree");
377 344
378 if (!parent_node) { 345 if (!parent_node) {
379 return_VOID; 346 return_VOID;
@@ -386,16 +353,17 @@ acpi_ns_delete_namespace_subtree (
386 while (level > 0) { 353 while (level > 0) {
387 /* Get the next node in this scope (NULL if none) */ 354 /* Get the next node in this scope (NULL if none) */
388 355
389 child_node = acpi_ns_get_next_node (ACPI_TYPE_ANY, parent_node, 356 child_node = acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
390 child_node); 357 child_node);
391 if (child_node) { 358 if (child_node) {
392 /* Found a child node - detach any attached object */ 359 /* Found a child node - detach any attached object */
393 360
394 acpi_ns_detach_object (child_node); 361 acpi_ns_detach_object(child_node);
395 362
396 /* Check if this node has any children */ 363 /* Check if this node has any children */
397 364
398 if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, NULL)) { 365 if (acpi_ns_get_next_node
366 (ACPI_TYPE_ANY, child_node, NULL)) {
399 /* 367 /*
400 * There is at least one child of this node, 368 * There is at least one child of this node,
401 * visit the node 369 * visit the node
@@ -404,8 +372,7 @@ acpi_ns_delete_namespace_subtree (
404 parent_node = child_node; 372 parent_node = child_node;
405 child_node = NULL; 373 child_node = NULL;
406 } 374 }
407 } 375 } else {
408 else {
409 /* 376 /*
410 * No more children of this parent node. 377 * No more children of this parent node.
411 * Move up to the grandparent. 378 * Move up to the grandparent.
@@ -416,7 +383,7 @@ acpi_ns_delete_namespace_subtree (
416 * Now delete all of the children of this parent 383 * Now delete all of the children of this parent
417 * all at the same time. 384 * all at the same time.
418 */ 385 */
419 acpi_ns_delete_children (parent_node); 386 acpi_ns_delete_children(parent_node);
420 387
421 /* New "last child" is this parent node */ 388 /* New "last child" is this parent node */
422 389
@@ -424,14 +391,13 @@ acpi_ns_delete_namespace_subtree (
424 391
425 /* Move up the tree to the grandparent */ 392 /* Move up the tree to the grandparent */
426 393
427 parent_node = acpi_ns_get_parent_node (parent_node); 394 parent_node = acpi_ns_get_parent_node(parent_node);
428 } 395 }
429 } 396 }
430 397
431 return_VOID; 398 return_VOID;
432} 399}
433 400
434
435/******************************************************************************* 401/*******************************************************************************
436 * 402 *
437 * FUNCTION: acpi_ns_remove_reference 403 * FUNCTION: acpi_ns_remove_reference
@@ -447,16 +413,12 @@ acpi_ns_delete_namespace_subtree (
447 * 413 *
448 ******************************************************************************/ 414 ******************************************************************************/
449 415
450static void 416static void acpi_ns_remove_reference(struct acpi_namespace_node *node)
451acpi_ns_remove_reference (
452 struct acpi_namespace_node *node)
453{ 417{
454 struct acpi_namespace_node *parent_node; 418 struct acpi_namespace_node *parent_node;
455 struct acpi_namespace_node *this_node; 419 struct acpi_namespace_node *this_node;
456
457
458 ACPI_FUNCTION_ENTRY ();
459 420
421 ACPI_FUNCTION_ENTRY();
460 422
461 /* 423 /*
462 * Decrement the reference count(s) of this node and all 424 * Decrement the reference count(s) of this node and all
@@ -466,7 +428,7 @@ acpi_ns_remove_reference (
466 while (this_node) { 428 while (this_node) {
467 /* Prepare to move up to parent */ 429 /* Prepare to move up to parent */
468 430
469 parent_node = acpi_ns_get_parent_node (this_node); 431 parent_node = acpi_ns_get_parent_node(this_node);
470 432
471 /* Decrement the reference count on this node */ 433 /* Decrement the reference count on this node */
472 434
@@ -477,15 +439,14 @@ acpi_ns_remove_reference (
477 if (!this_node->reference_count) { 439 if (!this_node->reference_count) {
478 /* Delete all children and delete the node */ 440 /* Delete all children and delete the node */
479 441
480 acpi_ns_delete_children (this_node); 442 acpi_ns_delete_children(this_node);
481 acpi_ns_delete_node (this_node); 443 acpi_ns_delete_node(this_node);
482 } 444 }
483 445
484 this_node = parent_node; 446 this_node = parent_node;
485 } 447 }
486} 448}
487 449
488
489/******************************************************************************* 450/*******************************************************************************
490 * 451 *
491 * FUNCTION: acpi_ns_delete_namespace_by_owner 452 * FUNCTION: acpi_ns_delete_namespace_by_owner
@@ -500,27 +461,23 @@ acpi_ns_remove_reference (
500 * 461 *
501 ******************************************************************************/ 462 ******************************************************************************/
502 463
503void 464void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
504acpi_ns_delete_namespace_by_owner (
505 acpi_owner_id owner_id)
506{ 465{
507 struct acpi_namespace_node *child_node; 466 struct acpi_namespace_node *child_node;
508 struct acpi_namespace_node *deletion_node; 467 struct acpi_namespace_node *deletion_node;
509 u32 level; 468 u32 level;
510 struct acpi_namespace_node *parent_node; 469 struct acpi_namespace_node *parent_node;
511
512
513 ACPI_FUNCTION_TRACE_U32 ("ns_delete_namespace_by_owner", owner_id);
514 470
471 ACPI_FUNCTION_TRACE_U32("ns_delete_namespace_by_owner", owner_id);
515 472
516 if (owner_id == 0) { 473 if (owner_id == 0) {
517 return_VOID; 474 return_VOID;
518 } 475 }
519 476
520 parent_node = acpi_gbl_root_node; 477 parent_node = acpi_gbl_root_node;
521 child_node = NULL; 478 child_node = NULL;
522 deletion_node = NULL; 479 deletion_node = NULL;
523 level = 1; 480 level = 1;
524 481
525 /* 482 /*
526 * Traverse the tree of nodes until we bubble back up 483 * Traverse the tree of nodes until we bubble back up
@@ -531,10 +488,12 @@ acpi_ns_delete_namespace_by_owner (
531 * Get the next child of this parent node. When child_node is NULL, 488 * Get the next child of this parent node. When child_node is NULL,
532 * the first child of the parent is returned 489 * the first child of the parent is returned
533 */ 490 */
534 child_node = acpi_ns_get_next_node (ACPI_TYPE_ANY, parent_node, child_node); 491 child_node =
492 acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
493 child_node);
535 494
536 if (deletion_node) { 495 if (deletion_node) {
537 acpi_ns_remove_reference (deletion_node); 496 acpi_ns_remove_reference(deletion_node);
538 deletion_node = NULL; 497 deletion_node = NULL;
539 } 498 }
540 499
@@ -542,12 +501,13 @@ acpi_ns_delete_namespace_by_owner (
542 if (child_node->owner_id == owner_id) { 501 if (child_node->owner_id == owner_id) {
543 /* Found a matching child node - detach any attached object */ 502 /* Found a matching child node - detach any attached object */
544 503
545 acpi_ns_detach_object (child_node); 504 acpi_ns_detach_object(child_node);
546 } 505 }
547 506
548 /* Check if this node has any children */ 507 /* Check if this node has any children */
549 508
550 if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, NULL)) { 509 if (acpi_ns_get_next_node
510 (ACPI_TYPE_ANY, child_node, NULL)) {
551 /* 511 /*
552 * There is at least one child of this node, 512 * There is at least one child of this node,
553 * visit the node 513 * visit the node
@@ -555,12 +515,10 @@ acpi_ns_delete_namespace_by_owner (
555 level++; 515 level++;
556 parent_node = child_node; 516 parent_node = child_node;
557 child_node = NULL; 517 child_node = NULL;
558 } 518 } else if (child_node->owner_id == owner_id) {
559 else if (child_node->owner_id == owner_id) {
560 deletion_node = child_node; 519 deletion_node = child_node;
561 } 520 }
562 } 521 } else {
563 else {
564 /* 522 /*
565 * No more children of this parent node. 523 * No more children of this parent node.
566 * Move up to the grandparent. 524 * Move up to the grandparent.
@@ -578,11 +536,9 @@ acpi_ns_delete_namespace_by_owner (
578 536
579 /* Move up the tree to the grandparent */ 537 /* Move up the tree to the grandparent */
580 538
581 parent_node = acpi_ns_get_parent_node (parent_node); 539 parent_node = acpi_ns_get_parent_node(parent_node);
582 } 540 }
583 } 541 }
584 542
585 return_VOID; 543 return_VOID;
586} 544}
587
588