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 - 2023, 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  
acpi_ns_print_pathname(u32 num_segments,const char * pathname)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_NAMESEG_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
acpi_ns_dump_pathname(acpi_handle handle,const char * msg,u32 level,u32 component)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
acpi_ns_dump_one_object(acpi_handle obj_handle,u32 level,void * context,void ** return_value)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  	info->count++;
174  
175  	/* Check if the owner matches */
176  
177  	if ((info->owner_id != ACPI_OWNER_ID_MAX) &&
178  	    (info->owner_id != this_node->owner_id)) {
179  		return (AE_OK);
180  	}
181  
182  	if (!(info->display_type & ACPI_DISPLAY_SHORT)) {
183  
184  		/* Indent the object according to the level */
185  
186  		acpi_os_printf("%2d%*s", (u32) level - 1, (int)level * 2, " ");
187  
188  		/* Check the node type and name */
189  
190  		if (type > ACPI_TYPE_LOCAL_MAX) {
191  			ACPI_WARNING((AE_INFO,
192  				      "Invalid ACPI Object Type 0x%08X", type));
193  		}
194  
195  		acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node));
196  	}
197  
198  	/* Now we can print out the pertinent information */
199  
200  	acpi_os_printf(" %-12s %p %3.3X ",
201  		       acpi_ut_get_type_name(type), this_node,
202  		       this_node->owner_id);
203  
204  	dbg_level = acpi_dbg_level;
205  	acpi_dbg_level = 0;
206  	obj_desc = acpi_ns_get_attached_object(this_node);
207  	acpi_dbg_level = dbg_level;
208  
209  	/* Temp nodes are those nodes created by a control method */
210  
211  	if (this_node->flags & ANOBJ_TEMPORARY) {
212  		acpi_os_printf("(T) ");
213  	}
214  
215  	switch (info->display_type & ACPI_DISPLAY_MASK) {
216  	case ACPI_DISPLAY_SUMMARY:
217  
218  		if (!obj_desc) {
219  
220  			/* No attached object. Some types should always have an object */
221  
222  			switch (type) {
223  			case ACPI_TYPE_INTEGER:
224  			case ACPI_TYPE_PACKAGE:
225  			case ACPI_TYPE_BUFFER:
226  			case ACPI_TYPE_STRING:
227  			case ACPI_TYPE_METHOD:
228  
229  				acpi_os_printf("<No attached object>");
230  				break;
231  
232  			default:
233  
234  				break;
235  			}
236  
237  			acpi_os_printf("\n");
238  			return (AE_OK);
239  		}
240  
241  		switch (type) {
242  		case ACPI_TYPE_PROCESSOR:
243  
244  			acpi_os_printf("ID %02X Len %02X Addr %8.8X%8.8X\n",
245  				       obj_desc->processor.proc_id,
246  				       obj_desc->processor.length,
247  				       ACPI_FORMAT_UINT64(obj_desc->processor.
248  							  address));
249  			break;
250  
251  		case ACPI_TYPE_DEVICE:
252  
253  			acpi_os_printf("Notify Object: %p\n", obj_desc);
254  			break;
255  
256  		case ACPI_TYPE_METHOD:
257  
258  			acpi_os_printf("Args %X Len %.4X Aml %p\n",
259  				       (u32) obj_desc->method.param_count,
260  				       obj_desc->method.aml_length,
261  				       obj_desc->method.aml_start);
262  			break;
263  
264  		case ACPI_TYPE_INTEGER:
265  
266  			acpi_os_printf("= %8.8X%8.8X\n",
267  				       ACPI_FORMAT_UINT64(obj_desc->integer.
268  							  value));
269  			break;
270  
271  		case ACPI_TYPE_PACKAGE:
272  
273  			if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
274  				acpi_os_printf("Elements %.2X\n",
275  					       obj_desc->package.count);
276  			} else {
277  				acpi_os_printf("[Length not yet evaluated]\n");
278  			}
279  			break;
280  
281  		case ACPI_TYPE_BUFFER:
282  
283  			if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
284  				acpi_os_printf("Len %.2X",
285  					       obj_desc->buffer.length);
286  
287  				/* Dump some of the buffer */
288  
289  				if (obj_desc->buffer.length > 0) {
290  					acpi_os_printf(" =");
291  					for (i = 0;
292  					     (i < obj_desc->buffer.length
293  					      && i < 12); i++) {
294  						acpi_os_printf(" %2.2X",
295  							       obj_desc->buffer.
296  							       pointer[i]);
297  					}
298  				}
299  				acpi_os_printf("\n");
300  			} else {
301  				acpi_os_printf("[Length not yet evaluated]\n");
302  			}
303  			break;
304  
305  		case ACPI_TYPE_STRING:
306  
307  			acpi_os_printf("Len %.2X ", obj_desc->string.length);
308  			acpi_ut_print_string(obj_desc->string.pointer, 80);
309  			acpi_os_printf("\n");
310  			break;
311  
312  		case ACPI_TYPE_REGION:
313  
314  			acpi_os_printf("[%s]",
315  				       acpi_ut_get_region_name(obj_desc->region.
316  							       space_id));
317  			if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
318  				acpi_os_printf(" Addr %8.8X%8.8X Len %.4X\n",
319  					       ACPI_FORMAT_UINT64(obj_desc->
320  								  region.
321  								  address),
322  					       obj_desc->region.length);
323  			} else {
324  				acpi_os_printf
325  				    (" [Address/Length not yet evaluated]\n");
326  			}
327  			break;
328  
329  		case ACPI_TYPE_LOCAL_REFERENCE:
330  
331  			acpi_os_printf("[%s]\n",
332  				       acpi_ut_get_reference_name(obj_desc));
333  			break;
334  
335  		case ACPI_TYPE_BUFFER_FIELD:
336  
337  			if (obj_desc->buffer_field.buffer_obj &&
338  			    obj_desc->buffer_field.buffer_obj->buffer.node) {
339  				acpi_os_printf("Buf [%4.4s]",
340  					       acpi_ut_get_node_name(obj_desc->
341  								     buffer_field.
342  								     buffer_obj->
343  								     buffer.
344  								     node));
345  			}
346  			break;
347  
348  		case ACPI_TYPE_LOCAL_REGION_FIELD:
349  
350  			acpi_os_printf("Rgn [%4.4s]",
351  				       acpi_ut_get_node_name(obj_desc->
352  							     common_field.
353  							     region_obj->region.
354  							     node));
355  			break;
356  
357  		case ACPI_TYPE_LOCAL_BANK_FIELD:
358  
359  			acpi_os_printf("Rgn [%4.4s] Bnk [%4.4s]",
360  				       acpi_ut_get_node_name(obj_desc->
361  							     common_field.
362  							     region_obj->region.
363  							     node),
364  				       acpi_ut_get_node_name(obj_desc->
365  							     bank_field.
366  							     bank_obj->
367  							     common_field.
368  							     node));
369  			break;
370  
371  		case ACPI_TYPE_LOCAL_INDEX_FIELD:
372  
373  			acpi_os_printf("Idx [%4.4s] Dat [%4.4s]",
374  				       acpi_ut_get_node_name(obj_desc->
375  							     index_field.
376  							     index_obj->
377  							     common_field.node),
378  				       acpi_ut_get_node_name(obj_desc->
379  							     index_field.
380  							     data_obj->
381  							     common_field.
382  							     node));
383  			break;
384  
385  		case ACPI_TYPE_LOCAL_ALIAS:
386  		case ACPI_TYPE_LOCAL_METHOD_ALIAS:
387  
388  			acpi_os_printf("Target %4.4s (%p)\n",
389  				       acpi_ut_get_node_name(obj_desc),
390  				       obj_desc);
391  			break;
392  
393  		default:
394  
395  			acpi_os_printf("Object %p\n", obj_desc);
396  			break;
397  		}
398  
399  		/* Common field handling */
400  
401  		switch (type) {
402  		case ACPI_TYPE_BUFFER_FIELD:
403  		case ACPI_TYPE_LOCAL_REGION_FIELD:
404  		case ACPI_TYPE_LOCAL_BANK_FIELD:
405  		case ACPI_TYPE_LOCAL_INDEX_FIELD:
406  
407  			acpi_os_printf(" Off %.3X Len %.2X Acc %.2X\n",
408  				       (obj_desc->common_field.
409  					base_byte_offset * 8)
410  				       +
411  				       obj_desc->common_field.
412  				       start_field_bit_offset,
413  				       obj_desc->common_field.bit_length,
414  				       obj_desc->common_field.
415  				       access_byte_width);
416  			break;
417  
418  		default:
419  
420  			break;
421  		}
422  		break;
423  
424  	case ACPI_DISPLAY_OBJECTS:
425  
426  		acpi_os_printf("O:%p", obj_desc);
427  		if (!obj_desc) {
428  
429  			/* No attached object, we are done */
430  
431  			acpi_os_printf("\n");
432  			return (AE_OK);
433  		}
434  
435  		acpi_os_printf("(R%u)", obj_desc->common.reference_count);
436  
437  		switch (type) {
438  		case ACPI_TYPE_METHOD:
439  
440  			/* Name is a Method and its AML offset/length are set */
441  
442  			acpi_os_printf(" M:%p-%X\n", obj_desc->method.aml_start,
443  				       obj_desc->method.aml_length);
444  			break;
445  
446  		case ACPI_TYPE_INTEGER:
447  
448  			acpi_os_printf(" I:%8.8X8.8%X\n",
449  				       ACPI_FORMAT_UINT64(obj_desc->integer.
450  							  value));
451  			break;
452  
453  		case ACPI_TYPE_STRING:
454  
455  			acpi_os_printf(" S:%p-%X\n", obj_desc->string.pointer,
456  				       obj_desc->string.length);
457  			break;
458  
459  		case ACPI_TYPE_BUFFER:
460  
461  			acpi_os_printf(" B:%p-%X\n", obj_desc->buffer.pointer,
462  				       obj_desc->buffer.length);
463  			break;
464  
465  		default:
466  
467  			acpi_os_printf("\n");
468  			break;
469  		}
470  		break;
471  
472  	default:
473  		acpi_os_printf("\n");
474  		break;
475  	}
476  
477  	/* If debug turned off, done */
478  
479  	if (!(acpi_dbg_level & ACPI_LV_VALUES)) {
480  		return (AE_OK);
481  	}
482  
483  	/* If there is an attached object, display it */
484  
485  	dbg_level = acpi_dbg_level;
486  	acpi_dbg_level = 0;
487  	obj_desc = acpi_ns_get_attached_object(this_node);
488  	acpi_dbg_level = dbg_level;
489  
490  	/* Dump attached objects */
491  
492  	while (obj_desc) {
493  		obj_type = ACPI_TYPE_INVALID;
494  		acpi_os_printf("Attached Object %p: ", obj_desc);
495  
496  		/* Decode the type of attached object and dump the contents */
497  
498  		switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
499  		case ACPI_DESC_TYPE_NAMED:
500  
501  			acpi_os_printf("(Ptr to Node)\n");
502  			bytes_to_dump = sizeof(struct acpi_namespace_node);
503  			ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump);
504  			break;
505  
506  		case ACPI_DESC_TYPE_OPERAND:
507  
508  			obj_type = obj_desc->common.type;
509  
510  			if (obj_type > ACPI_TYPE_LOCAL_MAX) {
511  				acpi_os_printf
512  				    ("(Pointer to ACPI Object type %.2X [UNKNOWN])\n",
513  				     obj_type);
514  
515  				bytes_to_dump = 32;
516  			} else {
517  				acpi_os_printf
518  				    ("(Pointer to ACPI Object type %.2X [%s])\n",
519  				     obj_type, acpi_ut_get_type_name(obj_type));
520  
521  				bytes_to_dump =
522  				    sizeof(union acpi_operand_object);
523  			}
524  
525  			ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump);
526  			break;
527  
528  		default:
529  
530  			break;
531  		}
532  
533  		/* If value is NOT an internal object, we are done */
534  
535  		if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) !=
536  		    ACPI_DESC_TYPE_OPERAND) {
537  			goto cleanup;
538  		}
539  
540  		/* Valid object, get the pointer to next level, if any */
541  
542  		switch (obj_type) {
543  		case ACPI_TYPE_BUFFER:
544  		case ACPI_TYPE_STRING:
545  			/*
546  			 * NOTE: takes advantage of common fields between string/buffer
547  			 */
548  			bytes_to_dump = obj_desc->string.length;
549  			obj_desc = (void *)obj_desc->string.pointer;
550  
551  			acpi_os_printf("(Buffer/String pointer %p length %X)\n",
552  				       obj_desc, bytes_to_dump);
553  			ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump);
554  			goto cleanup;
555  
556  		case ACPI_TYPE_BUFFER_FIELD:
557  
558  			obj_desc =
559  			    (union acpi_operand_object *)obj_desc->buffer_field.
560  			    buffer_obj;
561  			break;
562  
563  		case ACPI_TYPE_PACKAGE:
564  
565  			obj_desc = (void *)obj_desc->package.elements;
566  			break;
567  
568  		case ACPI_TYPE_METHOD:
569  
570  			obj_desc = (void *)obj_desc->method.aml_start;
571  			break;
572  
573  		case ACPI_TYPE_LOCAL_REGION_FIELD:
574  
575  			obj_desc = (void *)obj_desc->field.region_obj;
576  			break;
577  
578  		case ACPI_TYPE_LOCAL_BANK_FIELD:
579  
580  			obj_desc = (void *)obj_desc->bank_field.region_obj;
581  			break;
582  
583  		case ACPI_TYPE_LOCAL_INDEX_FIELD:
584  
585  			obj_desc = (void *)obj_desc->index_field.index_obj;
586  			break;
587  
588  		default:
589  
590  			goto cleanup;
591  		}
592  	}
593  
594  cleanup:
595  	acpi_os_printf("\n");
596  	return (AE_OK);
597  }
598  
599  /*******************************************************************************
600   *
601   * FUNCTION:    acpi_ns_dump_objects
602   *
603   * PARAMETERS:  type                - Object type to be dumped
604   *              display_type        - 0 or ACPI_DISPLAY_SUMMARY
605   *              max_depth           - Maximum depth of dump. Use ACPI_UINT32_MAX
606   *                                    for an effectively unlimited depth.
607   *              owner_id            - Dump only objects owned by this ID. Use
608   *                                    ACPI_UINT32_MAX to match all owners.
609   *              start_handle        - Where in namespace to start/end search
610   *
611   * RETURN:      None
612   *
613   * DESCRIPTION: Dump typed objects within the loaded namespace. Uses
614   *              acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
615   *
616   ******************************************************************************/
617  
618  void
acpi_ns_dump_objects(acpi_object_type type,u8 display_type,u32 max_depth,acpi_owner_id owner_id,acpi_handle start_handle)619  acpi_ns_dump_objects(acpi_object_type type,
620  		     u8 display_type,
621  		     u32 max_depth,
622  		     acpi_owner_id owner_id, acpi_handle start_handle)
623  {
624  	struct acpi_walk_info info;
625  	acpi_status status;
626  
627  	ACPI_FUNCTION_ENTRY();
628  
629  	/*
630  	 * Just lock the entire namespace for the duration of the dump.
631  	 * We don't want any changes to the namespace during this time,
632  	 * especially the temporary nodes since we are going to display
633  	 * them also.
634  	 */
635  	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
636  	if (ACPI_FAILURE(status)) {
637  		acpi_os_printf("Could not acquire namespace mutex\n");
638  		return;
639  	}
640  
641  	info.count = 0;
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  	acpi_os_printf("\nNamespace node count: %u\n\n", info.count);
653  	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
654  }
655  
656  /*******************************************************************************
657   *
658   * FUNCTION:    acpi_ns_dump_one_object_path, acpi_ns_get_max_depth
659   *
660   * PARAMETERS:  obj_handle          - Node to be dumped
661   *              level               - Nesting level of the handle
662   *              context             - Passed into walk_namespace
663   *              return_value        - Not used
664   *
665   * RETURN:      Status
666   *
667   * DESCRIPTION: Dump the full pathname to a namespace object. acp_ns_get_max_depth
668   *              computes the maximum nesting depth in the namespace tree, in
669   *              order to simplify formatting in acpi_ns_dump_one_object_path.
670   *              These procedures are user_functions called by acpi_ns_walk_namespace.
671   *
672   ******************************************************************************/
673  
674  static acpi_status
acpi_ns_dump_one_object_path(acpi_handle obj_handle,u32 level,void * context,void ** return_value)675  acpi_ns_dump_one_object_path(acpi_handle obj_handle,
676  			     u32 level, void *context, void **return_value)
677  {
678  	u32 max_level = *((u32 *)context);
679  	char *pathname;
680  	struct acpi_namespace_node *node;
681  	int path_indent;
682  
683  	if (!obj_handle) {
684  		return (AE_OK);
685  	}
686  
687  	node = acpi_ns_validate_handle(obj_handle);
688  	if (!node) {
689  
690  		/* Ignore bad node during namespace walk */
691  
692  		return (AE_OK);
693  	}
694  
695  	pathname = acpi_ns_get_normalized_pathname(node, TRUE);
696  
697  	path_indent = 1;
698  	if (level <= max_level) {
699  		path_indent = max_level - level + 1;
700  	}
701  
702  	acpi_os_printf("%2d%*s%-12s%*s",
703  		       level, level, " ", acpi_ut_get_type_name(node->type),
704  		       path_indent, " ");
705  
706  	acpi_os_printf("%s\n", &pathname[1]);
707  	ACPI_FREE(pathname);
708  	return (AE_OK);
709  }
710  
711  static acpi_status
acpi_ns_get_max_depth(acpi_handle obj_handle,u32 level,void * context,void ** return_value)712  acpi_ns_get_max_depth(acpi_handle obj_handle,
713  		      u32 level, void *context, void **return_value)
714  {
715  	u32 *max_level = (u32 *)context;
716  
717  	if (level > *max_level) {
718  		*max_level = level;
719  	}
720  	return (AE_OK);
721  }
722  
723  /*******************************************************************************
724   *
725   * FUNCTION:    acpi_ns_dump_object_paths
726   *
727   * PARAMETERS:  type                - Object type to be dumped
728   *              display_type        - 0 or ACPI_DISPLAY_SUMMARY
729   *              max_depth           - Maximum depth of dump. Use ACPI_UINT32_MAX
730   *                                    for an effectively unlimited depth.
731   *              owner_id            - Dump only objects owned by this ID. Use
732   *                                    ACPI_UINT32_MAX to match all owners.
733   *              start_handle        - Where in namespace to start/end search
734   *
735   * RETURN:      None
736   *
737   * DESCRIPTION: Dump full object pathnames within the loaded namespace. Uses
738   *              acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object_path.
739   *
740   ******************************************************************************/
741  
742  void
acpi_ns_dump_object_paths(acpi_object_type type,u8 display_type,u32 max_depth,acpi_owner_id owner_id,acpi_handle start_handle)743  acpi_ns_dump_object_paths(acpi_object_type type,
744  			  u8 display_type,
745  			  u32 max_depth,
746  			  acpi_owner_id owner_id, acpi_handle start_handle)
747  {
748  	acpi_status status;
749  	u32 max_level = 0;
750  
751  	ACPI_FUNCTION_ENTRY();
752  
753  	/*
754  	 * Just lock the entire namespace for the duration of the dump.
755  	 * We don't want any changes to the namespace during this time,
756  	 * especially the temporary nodes since we are going to display
757  	 * them also.
758  	 */
759  	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
760  	if (ACPI_FAILURE(status)) {
761  		acpi_os_printf("Could not acquire namespace mutex\n");
762  		return;
763  	}
764  
765  	/* Get the max depth of the namespace tree, for formatting later */
766  
767  	(void)acpi_ns_walk_namespace(type, start_handle, max_depth,
768  				     ACPI_NS_WALK_NO_UNLOCK |
769  				     ACPI_NS_WALK_TEMP_NODES,
770  				     acpi_ns_get_max_depth, NULL,
771  				     (void *)&max_level, NULL);
772  
773  	/* Now dump the entire namespace */
774  
775  	(void)acpi_ns_walk_namespace(type, start_handle, max_depth,
776  				     ACPI_NS_WALK_NO_UNLOCK |
777  				     ACPI_NS_WALK_TEMP_NODES,
778  				     acpi_ns_dump_one_object_path, NULL,
779  				     (void *)&max_level, NULL);
780  
781  	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
782  }
783  
784  /*******************************************************************************
785   *
786   * FUNCTION:    acpi_ns_dump_entry
787   *
788   * PARAMETERS:  handle              - Node to be dumped
789   *              debug_level         - Output level
790   *
791   * RETURN:      None
792   *
793   * DESCRIPTION: Dump a single Node
794   *
795   ******************************************************************************/
796  
acpi_ns_dump_entry(acpi_handle handle,u32 debug_level)797  void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level)
798  {
799  	struct acpi_walk_info info;
800  
801  	ACPI_FUNCTION_ENTRY();
802  
803  	info.debug_level = debug_level;
804  	info.owner_id = ACPI_OWNER_ID_MAX;
805  	info.display_type = ACPI_DISPLAY_SUMMARY;
806  
807  	(void)acpi_ns_dump_one_object(handle, 1, &info, NULL);
808  }
809  
810  #ifdef ACPI_ASL_COMPILER
811  /*******************************************************************************
812   *
813   * FUNCTION:    acpi_ns_dump_tables
814   *
815   * PARAMETERS:  search_base         - Root of subtree to be dumped, or
816   *                                    NS_ALL to dump the entire namespace
817   *              max_depth           - Maximum depth of dump. Use INT_MAX
818   *                                    for an effectively unlimited depth.
819   *
820   * RETURN:      None
821   *
822   * DESCRIPTION: Dump the name space, or a portion of it.
823   *
824   ******************************************************************************/
825  
acpi_ns_dump_tables(acpi_handle search_base,u32 max_depth)826  void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth)
827  {
828  	acpi_handle search_handle = search_base;
829  
830  	ACPI_FUNCTION_TRACE(ns_dump_tables);
831  
832  	if (!acpi_gbl_root_node) {
833  		/*
834  		 * If the name space has not been initialized,
835  		 * there is nothing to dump.
836  		 */
837  		ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
838  				  "namespace not initialized!\n"));
839  		return_VOID;
840  	}
841  
842  	if (ACPI_NS_ALL == search_base) {
843  
844  		/* Entire namespace */
845  
846  		search_handle = acpi_gbl_root_node;
847  		ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "\\\n"));
848  	}
849  
850  	acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth,
851  			     ACPI_OWNER_ID_MAX, search_handle);
852  	return_VOID;
853  }
854  #endif
855  #endif
856