xref: /openbmc/linux/drivers/acpi/acpica/nsdump.c (revision b240b419db5d624ce7a5a397d6f62a1a686009ec)
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: nsdump - table dumping routines for debug
5  *
6  * Copyright (C) 2000 - 2018, Intel Corp.
7  *
8  *****************************************************************************/
9 
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12 #include "acnamesp.h"
13 #include <acpi/acoutput.h>
14 
15 #define _COMPONENT          ACPI_NAMESPACE
16 ACPI_MODULE_NAME("nsdump")
17 
18 /* Local prototypes */
19 #ifdef ACPI_OBSOLETE_FUNCTIONS
20 void acpi_ns_dump_root_devices(void);
21 
22 static acpi_status
23 acpi_ns_dump_one_device(acpi_handle obj_handle,
24 			u32 level, void *context, void **return_value);
25 #endif
26 
27 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
28 
29 static acpi_status
30 acpi_ns_dump_one_object_path(acpi_handle obj_handle,
31 			     u32 level, void *context, void **return_value);
32 
33 static acpi_status
34 acpi_ns_get_max_depth(acpi_handle obj_handle,
35 		      u32 level, void *context, void **return_value);
36 
37 /*******************************************************************************
38  *
39  * FUNCTION:    acpi_ns_print_pathname
40  *
41  * PARAMETERS:  num_segments        - Number of ACPI name segments
42  *              pathname            - The compressed (internal) path
43  *
44  * RETURN:      None
45  *
46  * DESCRIPTION: Print an object's full namespace pathname
47  *
48  ******************************************************************************/
49 
50 void acpi_ns_print_pathname(u32 num_segments, const char *pathname)
51 {
52 	u32 i;
53 
54 	ACPI_FUNCTION_NAME(ns_print_pathname);
55 
56 	/* Check if debug output enabled */
57 
58 	if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_NAMES, ACPI_NAMESPACE)) {
59 		return;
60 	}
61 
62 	/* Print the entire name */
63 
64 	ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "["));
65 
66 	while (num_segments) {
67 		for (i = 0; i < 4; i++) {
68 			isprint((int)pathname[i]) ?
69 			    acpi_os_printf("%c", pathname[i]) :
70 			    acpi_os_printf("?");
71 		}
72 
73 		pathname += ACPI_NAME_SIZE;
74 		num_segments--;
75 		if (num_segments) {
76 			acpi_os_printf(".");
77 		}
78 	}
79 
80 	acpi_os_printf("]\n");
81 }
82 
83 #ifdef ACPI_OBSOLETE_FUNCTIONS
84 /* Not used at this time, perhaps later */
85 
86 /*******************************************************************************
87  *
88  * FUNCTION:    acpi_ns_dump_pathname
89  *
90  * PARAMETERS:  handle              - Object
91  *              msg                 - Prefix message
92  *              level               - Desired debug level
93  *              component           - Caller's component ID
94  *
95  * RETURN:      None
96  *
97  * DESCRIPTION: Print an object's full namespace pathname
98  *              Manages allocation/freeing of a pathname buffer
99  *
100  ******************************************************************************/
101 
102 void
103 acpi_ns_dump_pathname(acpi_handle handle,
104 		      const char *msg, u32 level, u32 component)
105 {
106 
107 	ACPI_FUNCTION_TRACE(ns_dump_pathname);
108 
109 	/* Do this only if the requested debug level and component are enabled */
110 
111 	if (!ACPI_IS_DEBUG_ENABLED(level, component)) {
112 		return_VOID;
113 	}
114 
115 	/* Convert handle to a full pathname and print it (with supplied message) */
116 
117 	acpi_ns_print_node_pathname(handle, msg);
118 	acpi_os_printf("\n");
119 	return_VOID;
120 }
121 #endif
122 
123 /*******************************************************************************
124  *
125  * FUNCTION:    acpi_ns_dump_one_object
126  *
127  * PARAMETERS:  obj_handle          - Node to be dumped
128  *              level               - Nesting level of the handle
129  *              context             - Passed into walk_namespace
130  *              return_value        - Not used
131  *
132  * RETURN:      Status
133  *
134  * DESCRIPTION: Dump a single Node
135  *              This procedure is a user_function called by acpi_ns_walk_namespace.
136  *
137  ******************************************************************************/
138 
139 acpi_status
140 acpi_ns_dump_one_object(acpi_handle obj_handle,
141 			u32 level, void *context, void **return_value)
142 {
143 	struct acpi_walk_info *info = (struct acpi_walk_info *)context;
144 	struct acpi_namespace_node *this_node;
145 	union acpi_operand_object *obj_desc = NULL;
146 	acpi_object_type obj_type;
147 	acpi_object_type type;
148 	u32 bytes_to_dump;
149 	u32 dbg_level;
150 	u32 i;
151 
152 	ACPI_FUNCTION_NAME(ns_dump_one_object);
153 
154 	/* Is output enabled? */
155 
156 	if (!(acpi_dbg_level & info->debug_level)) {
157 		return (AE_OK);
158 	}
159 
160 	if (!obj_handle) {
161 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Null object handle\n"));
162 		return (AE_OK);
163 	}
164 
165 	this_node = acpi_ns_validate_handle(obj_handle);
166 	if (!this_node) {
167 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid object handle %p\n",
168 				  obj_handle));
169 		return (AE_OK);
170 	}
171 
172 	type = this_node->type;
173 
174 	/* Check if the owner matches */
175 
176 	if ((info->owner_id != ACPI_OWNER_ID_MAX) &&
177 	    (info->owner_id != this_node->owner_id)) {
178 		return (AE_OK);
179 	}
180 
181 	if (!(info->display_type & ACPI_DISPLAY_SHORT)) {
182 
183 		/* Indent the object according to the level */
184 
185 		acpi_os_printf("%2d%*s", (u32) level - 1, (int)level * 2, " ");
186 
187 		/* Check the node type and name */
188 
189 		if (type > ACPI_TYPE_LOCAL_MAX) {
190 			ACPI_WARNING((AE_INFO,
191 				      "Invalid ACPI Object Type 0x%08X", type));
192 		}
193 
194 		acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node));
195 	}
196 
197 	/* Now we can print out the pertinent information */
198 
199 	acpi_os_printf(" %-12s %p %2.2X ",
200 		       acpi_ut_get_type_name(type), this_node,
201 		       this_node->owner_id);
202 
203 	dbg_level = acpi_dbg_level;
204 	acpi_dbg_level = 0;
205 	obj_desc = acpi_ns_get_attached_object(this_node);
206 	acpi_dbg_level = dbg_level;
207 
208 	/* Temp nodes are those nodes created by a control method */
209 
210 	if (this_node->flags & ANOBJ_TEMPORARY) {
211 		acpi_os_printf("(T) ");
212 	}
213 
214 	switch (info->display_type & ACPI_DISPLAY_MASK) {
215 	case ACPI_DISPLAY_SUMMARY:
216 
217 		if (!obj_desc) {
218 
219 			/* No attached object. Some types should always have an object */
220 
221 			switch (type) {
222 			case ACPI_TYPE_INTEGER:
223 			case ACPI_TYPE_PACKAGE:
224 			case ACPI_TYPE_BUFFER:
225 			case ACPI_TYPE_STRING:
226 			case ACPI_TYPE_METHOD:
227 
228 				acpi_os_printf("<No attached object>");
229 				break;
230 
231 			default:
232 
233 				break;
234 			}
235 
236 			acpi_os_printf("\n");
237 			return (AE_OK);
238 		}
239 
240 		switch (type) {
241 		case ACPI_TYPE_PROCESSOR:
242 
243 			acpi_os_printf("ID %02X Len %02X Addr %8.8X%8.8X\n",
244 				       obj_desc->processor.proc_id,
245 				       obj_desc->processor.length,
246 				       ACPI_FORMAT_UINT64(obj_desc->processor.
247 							  address));
248 			break;
249 
250 		case ACPI_TYPE_DEVICE:
251 
252 			acpi_os_printf("Notify Object: %p\n", obj_desc);
253 			break;
254 
255 		case ACPI_TYPE_METHOD:
256 
257 			acpi_os_printf("Args %X Len %.4X Aml %p\n",
258 				       (u32) obj_desc->method.param_count,
259 				       obj_desc->method.aml_length,
260 				       obj_desc->method.aml_start);
261 			break;
262 
263 		case ACPI_TYPE_INTEGER:
264 
265 			acpi_os_printf("= %8.8X%8.8X\n",
266 				       ACPI_FORMAT_UINT64(obj_desc->integer.
267 							  value));
268 			break;
269 
270 		case ACPI_TYPE_PACKAGE:
271 
272 			if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
273 				acpi_os_printf("Elements %.2X\n",
274 					       obj_desc->package.count);
275 			} else {
276 				acpi_os_printf("[Length not yet evaluated]\n");
277 			}
278 			break;
279 
280 		case ACPI_TYPE_BUFFER:
281 
282 			if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
283 				acpi_os_printf("Len %.2X",
284 					       obj_desc->buffer.length);
285 
286 				/* Dump some of the buffer */
287 
288 				if (obj_desc->buffer.length > 0) {
289 					acpi_os_printf(" =");
290 					for (i = 0;
291 					     (i < obj_desc->buffer.length
292 					      && i < 12); i++) {
293 						acpi_os_printf(" %.2hX",
294 							       obj_desc->buffer.
295 							       pointer[i]);
296 					}
297 				}
298 				acpi_os_printf("\n");
299 			} else {
300 				acpi_os_printf("[Length not yet evaluated]\n");
301 			}
302 			break;
303 
304 		case ACPI_TYPE_STRING:
305 
306 			acpi_os_printf("Len %.2X ", obj_desc->string.length);
307 			acpi_ut_print_string(obj_desc->string.pointer, 80);
308 			acpi_os_printf("\n");
309 			break;
310 
311 		case ACPI_TYPE_REGION:
312 
313 			acpi_os_printf("[%s]",
314 				       acpi_ut_get_region_name(obj_desc->region.
315 							       space_id));
316 			if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
317 				acpi_os_printf(" Addr %8.8X%8.8X Len %.4X\n",
318 					       ACPI_FORMAT_UINT64(obj_desc->
319 								  region.
320 								  address),
321 					       obj_desc->region.length);
322 			} else {
323 				acpi_os_printf
324 				    (" [Address/Length not yet evaluated]\n");
325 			}
326 			break;
327 
328 		case ACPI_TYPE_LOCAL_REFERENCE:
329 
330 			acpi_os_printf("[%s]\n",
331 				       acpi_ut_get_reference_name(obj_desc));
332 			break;
333 
334 		case ACPI_TYPE_BUFFER_FIELD:
335 
336 			if (obj_desc->buffer_field.buffer_obj &&
337 			    obj_desc->buffer_field.buffer_obj->buffer.node) {
338 				acpi_os_printf("Buf [%4.4s]",
339 					       acpi_ut_get_node_name(obj_desc->
340 								     buffer_field.
341 								     buffer_obj->
342 								     buffer.
343 								     node));
344 			}
345 			break;
346 
347 		case ACPI_TYPE_LOCAL_REGION_FIELD:
348 
349 			acpi_os_printf("Rgn [%4.4s]",
350 				       acpi_ut_get_node_name(obj_desc->
351 							     common_field.
352 							     region_obj->region.
353 							     node));
354 			break;
355 
356 		case ACPI_TYPE_LOCAL_BANK_FIELD:
357 
358 			acpi_os_printf("Rgn [%4.4s] Bnk [%4.4s]",
359 				       acpi_ut_get_node_name(obj_desc->
360 							     common_field.
361 							     region_obj->region.
362 							     node),
363 				       acpi_ut_get_node_name(obj_desc->
364 							     bank_field.
365 							     bank_obj->
366 							     common_field.
367 							     node));
368 			break;
369 
370 		case ACPI_TYPE_LOCAL_INDEX_FIELD:
371 
372 			acpi_os_printf("Idx [%4.4s] Dat [%4.4s]",
373 				       acpi_ut_get_node_name(obj_desc->
374 							     index_field.
375 							     index_obj->
376 							     common_field.node),
377 				       acpi_ut_get_node_name(obj_desc->
378 							     index_field.
379 							     data_obj->
380 							     common_field.
381 							     node));
382 			break;
383 
384 		case ACPI_TYPE_LOCAL_ALIAS:
385 		case ACPI_TYPE_LOCAL_METHOD_ALIAS:
386 
387 			acpi_os_printf("Target %4.4s (%p)\n",
388 				       acpi_ut_get_node_name(obj_desc),
389 				       obj_desc);
390 			break;
391 
392 		default:
393 
394 			acpi_os_printf("Object %p\n", obj_desc);
395 			break;
396 		}
397 
398 		/* Common field handling */
399 
400 		switch (type) {
401 		case ACPI_TYPE_BUFFER_FIELD:
402 		case ACPI_TYPE_LOCAL_REGION_FIELD:
403 		case ACPI_TYPE_LOCAL_BANK_FIELD:
404 		case ACPI_TYPE_LOCAL_INDEX_FIELD:
405 
406 			acpi_os_printf(" Off %.3X Len %.2X Acc %.2hd\n",
407 				       (obj_desc->common_field.
408 					base_byte_offset * 8)
409 				       +
410 				       obj_desc->common_field.
411 				       start_field_bit_offset,
412 				       obj_desc->common_field.bit_length,
413 				       obj_desc->common_field.
414 				       access_byte_width);
415 			break;
416 
417 		default:
418 
419 			break;
420 		}
421 		break;
422 
423 	case ACPI_DISPLAY_OBJECTS:
424 
425 		acpi_os_printf("O:%p", obj_desc);
426 		if (!obj_desc) {
427 
428 			/* No attached object, we are done */
429 
430 			acpi_os_printf("\n");
431 			return (AE_OK);
432 		}
433 
434 		acpi_os_printf("(R%u)", obj_desc->common.reference_count);
435 
436 		switch (type) {
437 		case ACPI_TYPE_METHOD:
438 
439 			/* Name is a Method and its AML offset/length are set */
440 
441 			acpi_os_printf(" M:%p-%X\n", obj_desc->method.aml_start,
442 				       obj_desc->method.aml_length);
443 			break;
444 
445 		case ACPI_TYPE_INTEGER:
446 
447 			acpi_os_printf(" I:%8.8X8.8%X\n",
448 				       ACPI_FORMAT_UINT64(obj_desc->integer.
449 							  value));
450 			break;
451 
452 		case ACPI_TYPE_STRING:
453 
454 			acpi_os_printf(" S:%p-%X\n", obj_desc->string.pointer,
455 				       obj_desc->string.length);
456 			break;
457 
458 		case ACPI_TYPE_BUFFER:
459 
460 			acpi_os_printf(" B:%p-%X\n", obj_desc->buffer.pointer,
461 				       obj_desc->buffer.length);
462 			break;
463 
464 		default:
465 
466 			acpi_os_printf("\n");
467 			break;
468 		}
469 		break;
470 
471 	default:
472 		acpi_os_printf("\n");
473 		break;
474 	}
475 
476 	/* If debug turned off, done */
477 
478 	if (!(acpi_dbg_level & ACPI_LV_VALUES)) {
479 		return (AE_OK);
480 	}
481 
482 	/* If there is an attached object, display it */
483 
484 	dbg_level = acpi_dbg_level;
485 	acpi_dbg_level = 0;
486 	obj_desc = acpi_ns_get_attached_object(this_node);
487 	acpi_dbg_level = dbg_level;
488 
489 	/* Dump attached objects */
490 
491 	while (obj_desc) {
492 		obj_type = ACPI_TYPE_INVALID;
493 		acpi_os_printf("Attached Object %p: ", obj_desc);
494 
495 		/* Decode the type of attached object and dump the contents */
496 
497 		switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
498 		case ACPI_DESC_TYPE_NAMED:
499 
500 			acpi_os_printf("(Ptr to Node)\n");
501 			bytes_to_dump = sizeof(struct acpi_namespace_node);
502 			ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump);
503 			break;
504 
505 		case ACPI_DESC_TYPE_OPERAND:
506 
507 			obj_type = obj_desc->common.type;
508 
509 			if (obj_type > ACPI_TYPE_LOCAL_MAX) {
510 				acpi_os_printf
511 				    ("(Pointer to ACPI Object type %.2X [UNKNOWN])\n",
512 				     obj_type);
513 
514 				bytes_to_dump = 32;
515 			} else {
516 				acpi_os_printf
517 				    ("(Pointer to ACPI Object type %.2X [%s])\n",
518 				     obj_type, acpi_ut_get_type_name(obj_type));
519 
520 				bytes_to_dump =
521 				    sizeof(union acpi_operand_object);
522 			}
523 
524 			ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump);
525 			break;
526 
527 		default:
528 
529 			break;
530 		}
531 
532 		/* If value is NOT an internal object, we are done */
533 
534 		if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) !=
535 		    ACPI_DESC_TYPE_OPERAND) {
536 			goto cleanup;
537 		}
538 
539 		/* Valid object, get the pointer to next level, if any */
540 
541 		switch (obj_type) {
542 		case ACPI_TYPE_BUFFER:
543 		case ACPI_TYPE_STRING:
544 			/*
545 			 * NOTE: takes advantage of common fields between string/buffer
546 			 */
547 			bytes_to_dump = obj_desc->string.length;
548 			obj_desc = (void *)obj_desc->string.pointer;
549 
550 			acpi_os_printf("(Buffer/String pointer %p length %X)\n",
551 				       obj_desc, bytes_to_dump);
552 			ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump);
553 			goto cleanup;
554 
555 		case ACPI_TYPE_BUFFER_FIELD:
556 
557 			obj_desc =
558 			    (union acpi_operand_object *)obj_desc->buffer_field.
559 			    buffer_obj;
560 			break;
561 
562 		case ACPI_TYPE_PACKAGE:
563 
564 			obj_desc = (void *)obj_desc->package.elements;
565 			break;
566 
567 		case ACPI_TYPE_METHOD:
568 
569 			obj_desc = (void *)obj_desc->method.aml_start;
570 			break;
571 
572 		case ACPI_TYPE_LOCAL_REGION_FIELD:
573 
574 			obj_desc = (void *)obj_desc->field.region_obj;
575 			break;
576 
577 		case ACPI_TYPE_LOCAL_BANK_FIELD:
578 
579 			obj_desc = (void *)obj_desc->bank_field.region_obj;
580 			break;
581 
582 		case ACPI_TYPE_LOCAL_INDEX_FIELD:
583 
584 			obj_desc = (void *)obj_desc->index_field.index_obj;
585 			break;
586 
587 		default:
588 
589 			goto cleanup;
590 		}
591 
592 		obj_type = ACPI_TYPE_INVALID;	/* Terminate loop after next pass */
593 	}
594 
595 cleanup:
596 	acpi_os_printf("\n");
597 	return (AE_OK);
598 }
599 
600 /*******************************************************************************
601  *
602  * FUNCTION:    acpi_ns_dump_objects
603  *
604  * PARAMETERS:  type                - Object type to be dumped
605  *              display_type        - 0 or ACPI_DISPLAY_SUMMARY
606  *              max_depth           - Maximum depth of dump. Use ACPI_UINT32_MAX
607  *                                    for an effectively unlimited depth.
608  *              owner_id            - Dump only objects owned by this ID. Use
609  *                                    ACPI_UINT32_MAX to match all owners.
610  *              start_handle        - Where in namespace to start/end search
611  *
612  * RETURN:      None
613  *
614  * DESCRIPTION: Dump typed objects within the loaded namespace. Uses
615  *              acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
616  *
617  ******************************************************************************/
618 
619 void
620 acpi_ns_dump_objects(acpi_object_type type,
621 		     u8 display_type,
622 		     u32 max_depth,
623 		     acpi_owner_id owner_id, acpi_handle start_handle)
624 {
625 	struct acpi_walk_info info;
626 	acpi_status status;
627 
628 	ACPI_FUNCTION_ENTRY();
629 
630 	/*
631 	 * Just lock the entire namespace for the duration of the dump.
632 	 * We don't want any changes to the namespace during this time,
633 	 * especially the temporary nodes since we are going to display
634 	 * them also.
635 	 */
636 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
637 	if (ACPI_FAILURE(status)) {
638 		acpi_os_printf("Could not acquire namespace mutex\n");
639 		return;
640 	}
641 
642 	info.debug_level = ACPI_LV_TABLES;
643 	info.owner_id = owner_id;
644 	info.display_type = display_type;
645 
646 	(void)acpi_ns_walk_namespace(type, start_handle, max_depth,
647 				     ACPI_NS_WALK_NO_UNLOCK |
648 				     ACPI_NS_WALK_TEMP_NODES,
649 				     acpi_ns_dump_one_object, NULL,
650 				     (void *)&info, NULL);
651 
652 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
653 }
654 
655 /*******************************************************************************
656  *
657  * FUNCTION:    acpi_ns_dump_one_object_path, acpi_ns_get_max_depth
658  *
659  * PARAMETERS:  obj_handle          - Node to be dumped
660  *              level               - Nesting level of the handle
661  *              context             - Passed into walk_namespace
662  *              return_value        - Not used
663  *
664  * RETURN:      Status
665  *
666  * DESCRIPTION: Dump the full pathname to a namespace object. acp_ns_get_max_depth
667  *              computes the maximum nesting depth in the namespace tree, in
668  *              order to simplify formatting in acpi_ns_dump_one_object_path.
669  *              These procedures are user_functions called by acpi_ns_walk_namespace.
670  *
671  ******************************************************************************/
672 
673 static acpi_status
674 acpi_ns_dump_one_object_path(acpi_handle obj_handle,
675 			     u32 level, void *context, void **return_value)
676 {
677 	u32 max_level = *((u32 *)context);
678 	char *pathname;
679 	struct acpi_namespace_node *node;
680 	int path_indent;
681 
682 	if (!obj_handle) {
683 		return (AE_OK);
684 	}
685 
686 	node = acpi_ns_validate_handle(obj_handle);
687 	if (!node) {
688 
689 		/* Ignore bad node during namespace walk */
690 
691 		return (AE_OK);
692 	}
693 
694 	pathname = acpi_ns_get_normalized_pathname(node, TRUE);
695 
696 	path_indent = 1;
697 	if (level <= max_level) {
698 		path_indent = max_level - level + 1;
699 	}
700 
701 	acpi_os_printf("%2d%*s%-12s%*s",
702 		       level, level, " ", acpi_ut_get_type_name(node->type),
703 		       path_indent, " ");
704 
705 	acpi_os_printf("%s\n", &pathname[1]);
706 	ACPI_FREE(pathname);
707 	return (AE_OK);
708 }
709 
710 static acpi_status
711 acpi_ns_get_max_depth(acpi_handle obj_handle,
712 		      u32 level, void *context, void **return_value)
713 {
714 	u32 *max_level = (u32 *)context;
715 
716 	if (level > *max_level) {
717 		*max_level = level;
718 	}
719 	return (AE_OK);
720 }
721 
722 /*******************************************************************************
723  *
724  * FUNCTION:    acpi_ns_dump_object_paths
725  *
726  * PARAMETERS:  type                - Object type to be dumped
727  *              display_type        - 0 or ACPI_DISPLAY_SUMMARY
728  *              max_depth           - Maximum depth of dump. Use ACPI_UINT32_MAX
729  *                                    for an effectively unlimited depth.
730  *              owner_id            - Dump only objects owned by this ID. Use
731  *                                    ACPI_UINT32_MAX to match all owners.
732  *              start_handle        - Where in namespace to start/end search
733  *
734  * RETURN:      None
735  *
736  * DESCRIPTION: Dump full object pathnames within the loaded namespace. Uses
737  *              acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object_path.
738  *
739  ******************************************************************************/
740 
741 void
742 acpi_ns_dump_object_paths(acpi_object_type type,
743 			  u8 display_type,
744 			  u32 max_depth,
745 			  acpi_owner_id owner_id, acpi_handle start_handle)
746 {
747 	acpi_status status;
748 	u32 max_level = 0;
749 
750 	ACPI_FUNCTION_ENTRY();
751 
752 	/*
753 	 * Just lock the entire namespace for the duration of the dump.
754 	 * We don't want any changes to the namespace during this time,
755 	 * especially the temporary nodes since we are going to display
756 	 * them also.
757 	 */
758 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
759 	if (ACPI_FAILURE(status)) {
760 		acpi_os_printf("Could not acquire namespace mutex\n");
761 		return;
762 	}
763 
764 	/* Get the max depth of the namespace tree, for formatting later */
765 
766 	(void)acpi_ns_walk_namespace(type, start_handle, max_depth,
767 				     ACPI_NS_WALK_NO_UNLOCK |
768 				     ACPI_NS_WALK_TEMP_NODES,
769 				     acpi_ns_get_max_depth, NULL,
770 				     (void *)&max_level, NULL);
771 
772 	/* Now dump the entire namespace */
773 
774 	(void)acpi_ns_walk_namespace(type, start_handle, max_depth,
775 				     ACPI_NS_WALK_NO_UNLOCK |
776 				     ACPI_NS_WALK_TEMP_NODES,
777 				     acpi_ns_dump_one_object_path, NULL,
778 				     (void *)&max_level, NULL);
779 
780 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
781 }
782 
783 /*******************************************************************************
784  *
785  * FUNCTION:    acpi_ns_dump_entry
786  *
787  * PARAMETERS:  handle              - Node to be dumped
788  *              debug_level         - Output level
789  *
790  * RETURN:      None
791  *
792  * DESCRIPTION: Dump a single Node
793  *
794  ******************************************************************************/
795 
796 void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level)
797 {
798 	struct acpi_walk_info info;
799 
800 	ACPI_FUNCTION_ENTRY();
801 
802 	info.debug_level = debug_level;
803 	info.owner_id = ACPI_OWNER_ID_MAX;
804 	info.display_type = ACPI_DISPLAY_SUMMARY;
805 
806 	(void)acpi_ns_dump_one_object(handle, 1, &info, NULL);
807 }
808 
809 #ifdef ACPI_ASL_COMPILER
810 /*******************************************************************************
811  *
812  * FUNCTION:    acpi_ns_dump_tables
813  *
814  * PARAMETERS:  search_base         - Root of subtree to be dumped, or
815  *                                    NS_ALL to dump the entire namespace
816  *              max_depth           - Maximum depth of dump. Use INT_MAX
817  *                                    for an effectively unlimited depth.
818  *
819  * RETURN:      None
820  *
821  * DESCRIPTION: Dump the name space, or a portion of it.
822  *
823  ******************************************************************************/
824 
825 void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth)
826 {
827 	acpi_handle search_handle = search_base;
828 
829 	ACPI_FUNCTION_TRACE(ns_dump_tables);
830 
831 	if (!acpi_gbl_root_node) {
832 		/*
833 		 * If the name space has not been initialized,
834 		 * there is nothing to dump.
835 		 */
836 		ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
837 				  "namespace not initialized!\n"));
838 		return_VOID;
839 	}
840 
841 	if (ACPI_NS_ALL == search_base) {
842 
843 		/* Entire namespace */
844 
845 		search_handle = acpi_gbl_root_node;
846 		ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "\\\n"));
847 	}
848 
849 	acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth,
850 			     ACPI_OWNER_ID_MAX, search_handle);
851 	return_VOID;
852 }
853 #endif
854 #endif
855