ACPICA 20050408 from Bob Moore
[sfrench/cifs-2.6.git] / drivers / acpi / namespace / nsdump.c
1 /******************************************************************************
2  *
3  * Module Name: nsdump - table dumping routines for debug
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2005, R. Byron Moore
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
45 #include <acpi/acpi.h>
46 #include <acpi/acnamesp.h>
47 #include <acpi/acparser.h>
48
49
50 #define _COMPONENT          ACPI_NAMESPACE
51          ACPI_MODULE_NAME    ("nsdump")
52
53 /* Local prototypes */
54
55 #ifdef ACPI_OBSOLETE_FUNCTIONS
56 void
57 acpi_ns_dump_root_devices (
58         void);
59
60 static acpi_status
61 acpi_ns_dump_one_device (
62         acpi_handle                     obj_handle,
63         u32                             level,
64         void                            *context,
65         void                            **return_value);
66 #endif
67
68
69 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
70 /*******************************************************************************
71  *
72  * FUNCTION:    acpi_ns_print_pathname
73  *
74  * PARAMETERS:  num_segments        - Number of ACPI name segments
75  *              Pathname            - The compressed (internal) path
76  *
77  * RETURN:      None
78  *
79  * DESCRIPTION: Print an object's full namespace pathname
80  *
81  ******************************************************************************/
82
83 void
84 acpi_ns_print_pathname (
85         u32                             num_segments,
86         char                            *pathname)
87 {
88         ACPI_FUNCTION_NAME ("ns_print_pathname");
89
90
91         if (!(acpi_dbg_level & ACPI_LV_NAMES) || !(acpi_dbg_layer & ACPI_NAMESPACE)) {
92                 return;
93         }
94
95         /* Print the entire name */
96
97         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "["));
98
99         while (num_segments) {
100                 acpi_os_printf ("%4.4s", pathname);
101                 pathname += ACPI_NAME_SIZE;
102
103                 num_segments--;
104                 if (num_segments) {
105                         acpi_os_printf (".");
106                 }
107         }
108
109         acpi_os_printf ("]\n");
110 }
111
112
113 /*******************************************************************************
114  *
115  * FUNCTION:    acpi_ns_dump_pathname
116  *
117  * PARAMETERS:  Handle              - Object
118  *              Msg                 - Prefix message
119  *              Level               - Desired debug level
120  *              Component           - Caller's component ID
121  *
122  * RETURN:      None
123  *
124  * DESCRIPTION: Print an object's full namespace pathname
125  *              Manages allocation/freeing of a pathname buffer
126  *
127  ******************************************************************************/
128
129 void
130 acpi_ns_dump_pathname (
131         acpi_handle                     handle,
132         char                            *msg,
133         u32                             level,
134         u32                             component)
135 {
136
137         ACPI_FUNCTION_TRACE ("ns_dump_pathname");
138
139
140         /* Do this only if the requested debug level and component are enabled */
141
142         if (!(acpi_dbg_level & level) || !(acpi_dbg_layer & component)) {
143                 return_VOID;
144         }
145
146         /* Convert handle to a full pathname and print it (with supplied message) */
147
148         acpi_ns_print_node_pathname (handle, msg);
149         acpi_os_printf ("\n");
150         return_VOID;
151 }
152
153
154 /*******************************************************************************
155  *
156  * FUNCTION:    acpi_ns_dump_one_object
157  *
158  * PARAMETERS:  obj_handle          - Node to be dumped
159  *              Level               - Nesting level of the handle
160  *              Context             - Passed into walk_namespace
161  *              return_value        - Not used
162  *
163  * RETURN:      Status
164  *
165  * DESCRIPTION: Dump a single Node
166  *              This procedure is a user_function called by acpi_ns_walk_namespace.
167  *
168  ******************************************************************************/
169
170 acpi_status
171 acpi_ns_dump_one_object (
172         acpi_handle                     obj_handle,
173         u32                             level,
174         void                            *context,
175         void                            **return_value)
176 {
177         struct acpi_walk_info           *info = (struct acpi_walk_info *) context;
178         struct acpi_namespace_node      *this_node;
179         union acpi_operand_object       *obj_desc = NULL;
180         acpi_object_type                obj_type;
181         acpi_object_type                type;
182         u32                             bytes_to_dump;
183         u32                             dbg_level;
184         u32                             i;
185
186
187         ACPI_FUNCTION_NAME ("ns_dump_one_object");
188
189
190         /* Is output enabled? */
191
192         if (!(acpi_dbg_level & info->debug_level)) {
193                 return (AE_OK);
194         }
195
196         if (!obj_handle) {
197                 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n"));
198                 return (AE_OK);
199         }
200
201         this_node = acpi_ns_map_handle_to_node (obj_handle);
202         type = this_node->type;
203
204         /* Check if the owner matches */
205
206         if ((info->owner_id != ACPI_UINT32_MAX) &&
207                 (info->owner_id != this_node->owner_id)) {
208                 return (AE_OK);
209         }
210
211         /* Indent the object according to the level */
212
213         acpi_os_printf ("%2d%*s", (u32) level - 1, (int) level * 2, " ");
214
215         /* Check the node type and name */
216
217         if (type > ACPI_TYPE_LOCAL_MAX) {
218                 ACPI_REPORT_WARNING (("Invalid ACPI Type %08X\n", type));
219         }
220
221         if (!acpi_ut_valid_acpi_name (this_node->name.integer)) {
222                 ACPI_REPORT_WARNING (("Invalid ACPI Name %08X\n",
223                         this_node->name.integer));
224         }
225
226         /*
227          * Now we can print out the pertinent information
228          */
229         acpi_os_printf ("%4.4s %-12s %p ",
230                         acpi_ut_get_node_name (this_node), acpi_ut_get_type_name (type), this_node);
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         switch (info->display_type) {
238         case ACPI_DISPLAY_SUMMARY:
239
240                 if (!obj_desc) {
241                         /* No attached object, we are done */
242
243                         acpi_os_printf ("\n");
244                         return (AE_OK);
245                 }
246
247                 switch (type) {
248                 case ACPI_TYPE_PROCESSOR:
249
250                         acpi_os_printf ("ID %X Len %.4X Addr %p\n",
251                                 obj_desc->processor.proc_id, obj_desc->processor.length,
252                                 (char *) obj_desc->processor.address);
253                         break;
254
255
256                 case ACPI_TYPE_DEVICE:
257
258                         acpi_os_printf ("Notify Object: %p\n", obj_desc);
259                         break;
260
261
262                 case ACPI_TYPE_METHOD:
263
264                         acpi_os_printf ("Args %X Len %.4X Aml %p\n",
265                                 (u32) obj_desc->method.param_count,
266                                 obj_desc->method.aml_length, obj_desc->method.aml_start);
267                         break;
268
269
270                 case ACPI_TYPE_INTEGER:
271
272                         acpi_os_printf ("= %8.8X%8.8X\n",
273                                 ACPI_FORMAT_UINT64 (obj_desc->integer.value));
274                         break;
275
276
277                 case ACPI_TYPE_PACKAGE:
278
279                         if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
280                                 acpi_os_printf ("Elements %.2X\n",
281                                         obj_desc->package.count);
282                         }
283                         else {
284                                 acpi_os_printf ("[Length not yet evaluated]\n");
285                         }
286                         break;
287
288
289                 case ACPI_TYPE_BUFFER:
290
291                         if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
292                                 acpi_os_printf ("Len %.2X",
293                                                  obj_desc->buffer.length);
294
295                                 /* Dump some of the buffer */
296
297                                 if (obj_desc->buffer.length > 0) {
298                                         acpi_os_printf (" =");
299                                         for (i = 0; (i < obj_desc->buffer.length && i < 12); i++) {
300                                                 acpi_os_printf (" %.2hX", obj_desc->buffer.pointer[i]);
301                                         }
302                                 }
303                                 acpi_os_printf ("\n");
304                         }
305                         else {
306                                 acpi_os_printf ("[Length not yet evaluated]\n");
307                         }
308                         break;
309
310
311                 case ACPI_TYPE_STRING:
312
313                         acpi_os_printf ("Len %.2X ", obj_desc->string.length);
314                         acpi_ut_print_string (obj_desc->string.pointer, 32);
315                         acpi_os_printf ("\n");
316                         break;
317
318
319                 case ACPI_TYPE_REGION:
320
321                         acpi_os_printf ("[%s]",
322                                 acpi_ut_get_region_name (obj_desc->region.space_id));
323                         if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
324                                 acpi_os_printf (" Addr %8.8X%8.8X Len %.4X\n",
325                                         ACPI_FORMAT_UINT64 (obj_desc->region.address),
326                                         obj_desc->region.length);
327                         }
328                         else {
329                                 acpi_os_printf (" [Address/Length not yet evaluated]\n");
330                         }
331                         break;
332
333
334                 case ACPI_TYPE_LOCAL_REFERENCE:
335
336                         acpi_os_printf ("[%s]\n",
337                                 acpi_ps_get_opcode_name (obj_desc->reference.opcode));
338                         break;
339
340
341                 case ACPI_TYPE_BUFFER_FIELD:
342
343                         if (obj_desc->buffer_field.buffer_obj &&
344                                 obj_desc->buffer_field.buffer_obj->buffer.node) {
345                                 acpi_os_printf ("Buf [%4.4s]",
346                                         acpi_ut_get_node_name (obj_desc->buffer_field.buffer_obj->buffer.node));
347                         }
348                         break;
349
350
351                 case ACPI_TYPE_LOCAL_REGION_FIELD:
352
353                         acpi_os_printf ("Rgn [%4.4s]",
354                                 acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node));
355                         break;
356
357
358                 case ACPI_TYPE_LOCAL_BANK_FIELD:
359
360                         acpi_os_printf ("Rgn [%4.4s] Bnk [%4.4s]",
361                                 acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node),
362                                 acpi_ut_get_node_name (obj_desc->bank_field.bank_obj->common_field.node));
363                         break;
364
365
366                 case ACPI_TYPE_LOCAL_INDEX_FIELD:
367
368                         acpi_os_printf ("Idx [%4.4s] Dat [%4.4s]",
369                                 acpi_ut_get_node_name (obj_desc->index_field.index_obj->common_field.node),
370                                 acpi_ut_get_node_name (obj_desc->index_field.data_obj->common_field.node));
371                         break;
372
373
374                 case ACPI_TYPE_LOCAL_ALIAS:
375                 case ACPI_TYPE_LOCAL_METHOD_ALIAS:
376
377                         acpi_os_printf ("Target %4.4s (%p)\n",
378                                 acpi_ut_get_node_name (obj_desc), obj_desc);
379                         break;
380
381                 default:
382
383                         acpi_os_printf ("Object %p\n", obj_desc);
384                         break;
385                 }
386
387                 /* Common field handling */
388
389                 switch (type) {
390                 case ACPI_TYPE_BUFFER_FIELD:
391                 case ACPI_TYPE_LOCAL_REGION_FIELD:
392                 case ACPI_TYPE_LOCAL_BANK_FIELD:
393                 case ACPI_TYPE_LOCAL_INDEX_FIELD:
394
395                         acpi_os_printf (" Off %.3X Len %.2X Acc %.2hd\n",
396                                 (obj_desc->common_field.base_byte_offset * 8)
397                                         + obj_desc->common_field.start_field_bit_offset,
398                                 obj_desc->common_field.bit_length,
399                                 obj_desc->common_field.access_byte_width);
400                         break;
401
402                 default:
403                         break;
404                 }
405                 break;
406
407
408         case ACPI_DISPLAY_OBJECTS:
409
410                 acpi_os_printf ("O:%p", obj_desc);
411                 if (!obj_desc) {
412                         /* No attached object, we are done */
413
414                         acpi_os_printf ("\n");
415                         return (AE_OK);
416                 }
417
418                 acpi_os_printf ("(R%d)", obj_desc->common.reference_count);
419
420                 switch (type) {
421                 case ACPI_TYPE_METHOD:
422
423                         /* Name is a Method and its AML offset/length are set */
424
425                         acpi_os_printf (" M:%p-%X\n", obj_desc->method.aml_start,
426                                           obj_desc->method.aml_length);
427                         break;
428
429                 case ACPI_TYPE_INTEGER:
430
431                         acpi_os_printf (" I:%8.8X8.8%X\n",
432                                         ACPI_FORMAT_UINT64 (obj_desc->integer.value));
433                         break;
434
435                 case ACPI_TYPE_STRING:
436
437                         acpi_os_printf (" S:%p-%X\n", obj_desc->string.pointer,
438                                           obj_desc->string.length);
439                         break;
440
441                 case ACPI_TYPE_BUFFER:
442
443                         acpi_os_printf (" B:%p-%X\n", obj_desc->buffer.pointer,
444                                           obj_desc->buffer.length);
445                         break;
446
447                 default:
448
449                         acpi_os_printf ("\n");
450                         break;
451                 }
452                 break;
453
454
455         default:
456                 acpi_os_printf ("\n");
457                 break;
458         }
459
460         /* If debug turned off, done */
461
462         if (!(acpi_dbg_level & ACPI_LV_VALUES)) {
463                 return (AE_OK);
464         }
465
466
467         /* If there is an attached object, display it */
468
469         dbg_level    = acpi_dbg_level;
470         acpi_dbg_level = 0;
471         obj_desc     = acpi_ns_get_attached_object (this_node);
472         acpi_dbg_level = dbg_level;
473
474         /* Dump attached objects */
475
476         while (obj_desc) {
477                 obj_type = ACPI_TYPE_INVALID;
478                 acpi_os_printf ("      Attached Object %p: ", obj_desc);
479
480                 /* Decode the type of attached object and dump the contents */
481
482                 switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
483                 case ACPI_DESC_TYPE_NAMED:
484
485                         acpi_os_printf ("(Ptr to Node)\n");
486                         bytes_to_dump = sizeof (struct acpi_namespace_node);
487                         break;
488
489
490                 case ACPI_DESC_TYPE_OPERAND:
491
492                         obj_type = ACPI_GET_OBJECT_TYPE (obj_desc);
493
494                         if (obj_type > ACPI_TYPE_LOCAL_MAX) {
495                                 acpi_os_printf ("(Ptr to ACPI Object type %X [UNKNOWN])\n",
496                                         obj_type);
497                                 bytes_to_dump = 32;
498                         }
499                         else {
500                                 acpi_os_printf ("(Ptr to ACPI Object type %s, %X)\n",
501                                         acpi_ut_get_type_name (obj_type), obj_type);
502                                 bytes_to_dump = sizeof (union acpi_operand_object);
503                         }
504                         break;
505
506
507                 default:
508
509                         acpi_os_printf (
510                                 "(String or Buffer ptr - not an object descriptor) [%s]\n",
511                                 acpi_ut_get_descriptor_name (obj_desc));
512                         bytes_to_dump = 16;
513                         break;
514                 }
515
516                 ACPI_DUMP_BUFFER (obj_desc, bytes_to_dump);
517
518                 /* If value is NOT an internal object, we are done */
519
520                 if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
521                         goto cleanup;
522                 }
523
524                 /*
525                  * Valid object, get the pointer to next level, if any
526                  */
527                 switch (obj_type) {
528                 case ACPI_TYPE_STRING:
529                         obj_desc = (void *) obj_desc->string.pointer;
530                         break;
531
532                 case ACPI_TYPE_BUFFER:
533                         obj_desc = (void *) obj_desc->buffer.pointer;
534                         break;
535
536                 case ACPI_TYPE_BUFFER_FIELD:
537                         obj_desc = (union acpi_operand_object *) obj_desc->buffer_field.buffer_obj;
538                         break;
539
540                 case ACPI_TYPE_PACKAGE:
541                         obj_desc = (void *) obj_desc->package.elements;
542                         break;
543
544                 case ACPI_TYPE_METHOD:
545                         obj_desc = (void *) obj_desc->method.aml_start;
546                         break;
547
548                 case ACPI_TYPE_LOCAL_REGION_FIELD:
549                         obj_desc = (void *) obj_desc->field.region_obj;
550                         break;
551
552                 case ACPI_TYPE_LOCAL_BANK_FIELD:
553                         obj_desc = (void *) obj_desc->bank_field.region_obj;
554                         break;
555
556                 case ACPI_TYPE_LOCAL_INDEX_FIELD:
557                         obj_desc = (void *) obj_desc->index_field.index_obj;
558                         break;
559
560                 default:
561                         goto cleanup;
562                 }
563
564                 obj_type = ACPI_TYPE_INVALID;  /* Terminate loop after next pass */
565         }
566
567 cleanup:
568         acpi_os_printf ("\n");
569         return (AE_OK);
570 }
571
572
573 #ifdef ACPI_FUTURE_USAGE
574 /*******************************************************************************
575  *
576  * FUNCTION:    acpi_ns_dump_objects
577  *
578  * PARAMETERS:  Type                - Object type to be dumped
579  *              display_type        - 0 or ACPI_DISPLAY_SUMMARY
580  *              max_depth           - Maximum depth of dump. Use ACPI_UINT32_MAX
581  *                                    for an effectively unlimited depth.
582  *              owner_id            - Dump only objects owned by this ID.  Use
583  *                                    ACPI_UINT32_MAX to match all owners.
584  *              start_handle        - Where in namespace to start/end search
585  *
586  * RETURN:      None
587  *
588  * DESCRIPTION: Dump typed objects within the loaded namespace.
589  *              Uses acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
590  *
591  ******************************************************************************/
592
593 void
594 acpi_ns_dump_objects (
595         acpi_object_type                type,
596         u8                              display_type,
597         u32                             max_depth,
598         u32                             owner_id,
599         acpi_handle                     start_handle)
600 {
601         struct acpi_walk_info           info;
602
603
604         ACPI_FUNCTION_ENTRY ();
605
606
607         info.debug_level = ACPI_LV_TABLES;
608         info.owner_id = owner_id;
609         info.display_type = display_type;
610
611         (void) acpi_ns_walk_namespace (type, start_handle, max_depth,
612                          ACPI_NS_WALK_NO_UNLOCK, acpi_ns_dump_one_object,
613                          (void *) &info, NULL);
614 }
615
616
617 /*******************************************************************************
618  *
619  * FUNCTION:    acpi_ns_dump_entry
620  *
621  * PARAMETERS:  Handle              - Node to be dumped
622  *              debug_level         - Output level
623  *
624  * RETURN:      None
625  *
626  * DESCRIPTION: Dump a single Node
627  *
628  ******************************************************************************/
629
630 void
631 acpi_ns_dump_entry (
632         acpi_handle                     handle,
633         u32                             debug_level)
634 {
635         struct acpi_walk_info           info;
636
637
638         ACPI_FUNCTION_ENTRY ();
639
640
641         info.debug_level = debug_level;
642         info.owner_id = ACPI_UINT32_MAX;
643         info.display_type = ACPI_DISPLAY_SUMMARY;
644
645         (void) acpi_ns_dump_one_object (handle, 1, &info, NULL);
646 }
647
648
649 #ifdef _ACPI_ASL_COMPILER
650 /*******************************************************************************
651  *
652  * FUNCTION:    acpi_ns_dump_tables
653  *
654  * PARAMETERS:  search_base         - Root of subtree to be dumped, or
655  *                                    NS_ALL to dump the entire namespace
656  *              max_depth           - Maximum depth of dump.  Use INT_MAX
657  *                                    for an effectively unlimited depth.
658  *
659  * RETURN:      None
660  *
661  * DESCRIPTION: Dump the name space, or a portion of it.
662  *
663  ******************************************************************************/
664
665 void
666 acpi_ns_dump_tables (
667         acpi_handle                     search_base,
668         u32                             max_depth)
669 {
670         acpi_handle                     search_handle = search_base;
671
672
673         ACPI_FUNCTION_TRACE ("ns_dump_tables");
674
675
676         if (!acpi_gbl_root_node) {
677                 /*
678                  * If the name space has not been initialized,
679                  * there is nothing to dump.
680                  */
681                 ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "namespace not initialized!\n"));
682                 return_VOID;
683         }
684
685         if (ACPI_NS_ALL == search_base) {
686                 /* Entire namespace */
687
688                 search_handle = acpi_gbl_root_node;
689                 ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "\\\n"));
690         }
691
692         acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth,
693                         ACPI_UINT32_MAX, search_handle);
694         return_VOID;
695 }
696 #endif  /* _ACPI_ASL_COMPILER */
697 #endif  /* ACPI_FUTURE_USAGE */
698 #endif  /* defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) */