Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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