Blame view

drivers/acpi/acpica/pstree.c 7.74 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
  /******************************************************************************
   *
   * Module Name: pstree - Parser op tree manipulation/traversal/search
   *
   *****************************************************************************/
  
  /*
b4e104eae   Bob Moore   ACPICA: Update al...
8
   * Copyright (C) 2000 - 2011, Intel Corp.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions, and the following disclaimer,
   *    without modification.
   * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   *    substantially similar to the "NO WARRANTY" disclaimer below
   *    ("Disclaimer") and any redistribution must be conditioned upon
   *    including a substantially similar Disclaimer requirement for further
   *    binary redistribution.
   * 3. Neither the names of the above-listed copyright holders nor the names
   *    of any contributors may be used to endorse or promote products derived
   *    from this software without specific prior written permission.
   *
   * Alternatively, this software may be distributed under the terms of the
   * GNU General Public License ("GPL") version 2 as published by the Free
   * Software Foundation.
   *
   * NO WARRANTY
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   * POSSIBILITY OF SUCH DAMAGES.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
  #include <acpi/acpi.h>
e2f7a7772   Len Brown   ACPICA: hide priv...
44
45
46
  #include "accommon.h"
  #include "acparser.h"
  #include "amlcode.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
47
48
  
  #define _COMPONENT          ACPI_PARSER
4be44fcd3   Len Brown   [ACPI] Lindent al...
49
  ACPI_MODULE_NAME("pstree")
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50

44f6c0124   Robert Moore   ACPICA 20050408 f...
51
  /* Local prototypes */
44f6c0124   Robert Moore   ACPICA 20050408 f...
52
  #ifdef ACPI_OBSOLETE_FUNCTIONS
4be44fcd3   Len Brown   [ACPI] Lindent al...
53
  union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op);
44f6c0124   Robert Moore   ACPICA 20050408 f...
54
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
56
57
58
59
60
61
  /*******************************************************************************
   *
   * FUNCTION:    acpi_ps_get_arg
   *
   * PARAMETERS:  Op              - Get an argument for this op
   *              Argn            - Nth argument to get
   *
44f6c0124   Robert Moore   ACPICA 20050408 f...
62
   * RETURN:      The argument (as an Op object). NULL if argument does not exist
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
64
65
66
   *
   * DESCRIPTION: Get the specified op's argument.
   *
   ******************************************************************************/
4be44fcd3   Len Brown   [ACPI] Lindent al...
67
  union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
69
70
  	union acpi_parse_object *arg = NULL;
  	const struct acpi_opcode_info *op_info;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71

4be44fcd3   Len Brown   [ACPI] Lindent al...
72
  	ACPI_FUNCTION_ENTRY();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
74
  
  	/* Get the info structure for this opcode */
4be44fcd3   Len Brown   [ACPI] Lindent al...
75
  	op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
  	if (op_info->class == AML_CLASS_UNKNOWN) {
52fc0b026   Bob Moore   [ACPI] ACPICA 200...
77

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
78
79
80
81
82
83
84
85
  		/* Invalid opcode or ASCII character */
  
  		return (NULL);
  	}
  
  	/* Check if this opcode requires argument sub-objects */
  
  	if (!(op_info->flags & AML_HAS_ARGS)) {
52fc0b026   Bob Moore   [ACPI] ACPICA 200...
86

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
  		/* Has no linked argument objects */
  
  		return (NULL);
  	}
  
  	/* Get the requested argument object */
  
  	arg = op->common.value.arg;
  	while (arg && argn) {
  		argn--;
  		arg = arg->common.next;
  	}
  
  	return (arg);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
103
104
105
106
107
108
109
110
111
112
113
114
115
  /*******************************************************************************
   *
   * FUNCTION:    acpi_ps_append_arg
   *
   * PARAMETERS:  Op              - Append an argument to this Op.
   *              Arg             - Argument Op to append
   *
   * RETURN:      None.
   *
   * DESCRIPTION: Append an argument to an op's argument list (a NULL arg is OK)
   *
   ******************************************************************************/
  
  void
4be44fcd3   Len Brown   [ACPI] Lindent al...
116
  acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
118
119
  	union acpi_parse_object *prev_arg;
  	const struct acpi_opcode_info *op_info;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120

4be44fcd3   Len Brown   [ACPI] Lindent al...
121
  	ACPI_FUNCTION_ENTRY();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
122
123
124
125
126
127
  
  	if (!op) {
  		return;
  	}
  
  	/* Get the info structure for this opcode */
4be44fcd3   Len Brown   [ACPI] Lindent al...
128
  	op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
  	if (op_info->class == AML_CLASS_UNKNOWN) {
52fc0b026   Bob Moore   [ACPI] ACPICA 200...
130

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
  		/* Invalid opcode */
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
132
133
  		ACPI_ERROR((AE_INFO, "Invalid AML Opcode: 0x%2.2X",
  			    op->common.aml_opcode));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
136
137
138
139
  		return;
  	}
  
  	/* Check if this opcode requires argument sub-objects */
  
  	if (!(op_info->flags & AML_HAS_ARGS)) {
52fc0b026   Bob Moore   [ACPI] ACPICA 200...
140

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
142
143
144
  		/* Has no linked argument objects */
  
  		return;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
147
  	/* Append the argument to the linked argument list */
  
  	if (op->common.value.arg) {
52fc0b026   Bob Moore   [ACPI] ACPICA 200...
148

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
151
152
153
154
155
  		/* Append to existing argument list */
  
  		prev_arg = op->common.value.arg;
  		while (prev_arg->common.next) {
  			prev_arg = prev_arg->common.next;
  		}
  		prev_arg->common.next = arg;
4be44fcd3   Len Brown   [ACPI] Lindent al...
156
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
158
159
160
  		/* No argument list, this will be the first argument */
  
  		op->common.value.arg = arg;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
162
163
164
165
  	/* Set the parent in this arg and any args linked after it */
  
  	while (arg) {
  		arg->common.parent = op;
  		arg = arg->common.next;
4e3156b18   Bob Moore   ACPICA: changed o...
166
167
  
  		op->common.arg_list_length++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
  #ifdef ACPI_FUTURE_USAGE
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
171
172
173
174
175
176
177
178
179
180
181
182
183
  /*******************************************************************************
   *
   * FUNCTION:    acpi_ps_get_depth_next
   *
   * PARAMETERS:  Origin          - Root of subtree to search
   *              Op              - Last (previous) Op that was found
   *
   * RETURN:      Next Op found in the search.
   *
   * DESCRIPTION: Get next op in tree (walking the tree in depth-first order)
   *              Return NULL when reaching "origin" or when walking up from root
   *
   ******************************************************************************/
4be44fcd3   Len Brown   [ACPI] Lindent al...
184
185
  union acpi_parse_object *acpi_ps_get_depth_next(union acpi_parse_object *origin,
  						union acpi_parse_object *op)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
187
188
189
  	union acpi_parse_object *next = NULL;
  	union acpi_parse_object *parent;
  	union acpi_parse_object *arg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190

4be44fcd3   Len Brown   [ACPI] Lindent al...
191
  	ACPI_FUNCTION_ENTRY();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
194
195
  
  	if (!op) {
  		return (NULL);
  	}
44f6c0124   Robert Moore   ACPICA 20050408 f...
196
  	/* Look for an argument or child */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197

4be44fcd3   Len Brown   [ACPI] Lindent al...
198
  	next = acpi_ps_get_arg(op, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
200
201
  	if (next) {
  		return (next);
  	}
44f6c0124   Robert Moore   ACPICA 20050408 f...
202
  	/* Look for a sibling */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
204
205
206
207
  
  	next = op->common.next;
  	if (next) {
  		return (next);
  	}
44f6c0124   Robert Moore   ACPICA 20050408 f...
208
  	/* Look for a sibling of parent */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
209
210
211
212
  
  	parent = op->common.parent;
  
  	while (parent) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
213
  		arg = acpi_ps_get_arg(parent, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
215
216
217
218
  		while (arg && (arg != origin) && (arg != op)) {
  			arg = arg->common.next;
  		}
  
  		if (arg == origin) {
52fc0b026   Bob Moore   [ACPI] ACPICA 200...
219

44f6c0124   Robert Moore   ACPICA 20050408 f...
220
  			/* Reached parent of origin, end search */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221
222
223
224
225
  
  			return (NULL);
  		}
  
  		if (parent->common.next) {
52fc0b026   Bob Moore   [ACPI] ACPICA 200...
226

44f6c0124   Robert Moore   ACPICA 20050408 f...
227
  			/* Found sibling of parent */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
229
230
231
232
233
234
235
236
237
  
  			return (parent->common.next);
  		}
  
  		op = parent;
  		parent = parent->common.parent;
  	}
  
  	return (next);
  }
44f6c0124   Robert Moore   ACPICA 20050408 f...
238
239
240
241
242
243
244
245
246
247
248
249
  #ifdef ACPI_OBSOLETE_FUNCTIONS
  /*******************************************************************************
   *
   * FUNCTION:    acpi_ps_get_child
   *
   * PARAMETERS:  Op              - Get the child of this Op
   *
   * RETURN:      Child Op, Null if none is found.
   *
   * DESCRIPTION: Get op's children or NULL if none
   *
   ******************************************************************************/
4be44fcd3   Len Brown   [ACPI] Lindent al...
250
  union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op)
44f6c0124   Robert Moore   ACPICA 20050408 f...
251
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
252
  	union acpi_parse_object *child = NULL;
44f6c0124   Robert Moore   ACPICA 20050408 f...
253

4be44fcd3   Len Brown   [ACPI] Lindent al...
254
  	ACPI_FUNCTION_ENTRY();
44f6c0124   Robert Moore   ACPICA 20050408 f...
255
256
257
258
259
260
261
  
  	switch (op->common.aml_opcode) {
  	case AML_SCOPE_OP:
  	case AML_ELSE_OP:
  	case AML_DEVICE_OP:
  	case AML_THERMAL_ZONE_OP:
  	case AML_INT_METHODCALL_OP:
4be44fcd3   Len Brown   [ACPI] Lindent al...
262
  		child = acpi_ps_get_arg(op, 0);
44f6c0124   Robert Moore   ACPICA 20050408 f...
263
  		break;
44f6c0124   Robert Moore   ACPICA 20050408 f...
264
265
266
267
268
269
  	case AML_BUFFER_OP:
  	case AML_PACKAGE_OP:
  	case AML_METHOD_OP:
  	case AML_IF_OP:
  	case AML_WHILE_OP:
  	case AML_FIELD_OP:
4be44fcd3   Len Brown   [ACPI] Lindent al...
270
  		child = acpi_ps_get_arg(op, 1);
44f6c0124   Robert Moore   ACPICA 20050408 f...
271
  		break;
44f6c0124   Robert Moore   ACPICA 20050408 f...
272
273
  	case AML_POWER_RES_OP:
  	case AML_INDEX_FIELD_OP:
4be44fcd3   Len Brown   [ACPI] Lindent al...
274
  		child = acpi_ps_get_arg(op, 2);
44f6c0124   Robert Moore   ACPICA 20050408 f...
275
  		break;
44f6c0124   Robert Moore   ACPICA 20050408 f...
276
277
  	case AML_PROCESSOR_OP:
  	case AML_BANK_FIELD_OP:
4be44fcd3   Len Brown   [ACPI] Lindent al...
278
  		child = acpi_ps_get_arg(op, 3);
44f6c0124   Robert Moore   ACPICA 20050408 f...
279
  		break;
44f6c0124   Robert Moore   ACPICA 20050408 f...
280
281
282
283
284
285
286
287
  	default:
  		/* All others have no children */
  		break;
  	}
  
  	return (child);
  }
  #endif
4be44fcd3   Len Brown   [ACPI] Lindent al...
288
  #endif				/*  ACPI_FUTURE_USAGE  */