Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.13 334 lines 8.1 kB view raw
1/****************************************************************************** 2 * 3 * Module Name: pstree - Parser op tree manipulation/traversal/search 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/acparser.h> 47#include <acpi/amlcode.h> 48 49#define _COMPONENT ACPI_PARSER 50 ACPI_MODULE_NAME ("pstree") 51 52/* Local prototypes */ 53 54#ifdef ACPI_OBSOLETE_FUNCTIONS 55union acpi_parse_object * 56acpi_ps_get_child ( 57 union acpi_parse_object *op); 58#endif 59 60 61/******************************************************************************* 62 * 63 * FUNCTION: acpi_ps_get_arg 64 * 65 * PARAMETERS: Op - Get an argument for this op 66 * Argn - Nth argument to get 67 * 68 * RETURN: The argument (as an Op object). NULL if argument does not exist 69 * 70 * DESCRIPTION: Get the specified op's argument. 71 * 72 ******************************************************************************/ 73 74union acpi_parse_object * 75acpi_ps_get_arg ( 76 union acpi_parse_object *op, 77 u32 argn) 78{ 79 union acpi_parse_object *arg = NULL; 80 const struct acpi_opcode_info *op_info; 81 82 83 ACPI_FUNCTION_ENTRY (); 84 85 86 /* Get the info structure for this opcode */ 87 88 op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); 89 if (op_info->class == AML_CLASS_UNKNOWN) { 90 /* Invalid opcode or ASCII character */ 91 92 return (NULL); 93 } 94 95 /* Check if this opcode requires argument sub-objects */ 96 97 if (!(op_info->flags & AML_HAS_ARGS)) { 98 /* Has no linked argument objects */ 99 100 return (NULL); 101 } 102 103 /* Get the requested argument object */ 104 105 arg = op->common.value.arg; 106 while (arg && argn) { 107 argn--; 108 arg = arg->common.next; 109 } 110 111 return (arg); 112} 113 114 115/******************************************************************************* 116 * 117 * FUNCTION: acpi_ps_append_arg 118 * 119 * PARAMETERS: Op - Append an argument to this Op. 120 * Arg - Argument Op to append 121 * 122 * RETURN: None. 123 * 124 * DESCRIPTION: Append an argument to an op's argument list (a NULL arg is OK) 125 * 126 ******************************************************************************/ 127 128void 129acpi_ps_append_arg ( 130 union acpi_parse_object *op, 131 union acpi_parse_object *arg) 132{ 133 union acpi_parse_object *prev_arg; 134 const struct acpi_opcode_info *op_info; 135 136 137 ACPI_FUNCTION_ENTRY (); 138 139 140 if (!op) { 141 return; 142 } 143 144 /* Get the info structure for this opcode */ 145 146 op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); 147 if (op_info->class == AML_CLASS_UNKNOWN) { 148 /* Invalid opcode */ 149 150 ACPI_REPORT_ERROR (("ps_append_arg: Invalid AML Opcode: 0x%2.2X\n", 151 op->common.aml_opcode)); 152 return; 153 } 154 155 /* Check if this opcode requires argument sub-objects */ 156 157 if (!(op_info->flags & AML_HAS_ARGS)) { 158 /* Has no linked argument objects */ 159 160 return; 161 } 162 163 /* Append the argument to the linked argument list */ 164 165 if (op->common.value.arg) { 166 /* Append to existing argument list */ 167 168 prev_arg = op->common.value.arg; 169 while (prev_arg->common.next) { 170 prev_arg = prev_arg->common.next; 171 } 172 prev_arg->common.next = arg; 173 } 174 else { 175 /* No argument list, this will be the first argument */ 176 177 op->common.value.arg = arg; 178 } 179 180 /* Set the parent in this arg and any args linked after it */ 181 182 while (arg) { 183 arg->common.parent = op; 184 arg = arg->common.next; 185 } 186} 187 188 189#ifdef ACPI_FUTURE_USAGE 190/******************************************************************************* 191 * 192 * FUNCTION: acpi_ps_get_depth_next 193 * 194 * PARAMETERS: Origin - Root of subtree to search 195 * Op - Last (previous) Op that was found 196 * 197 * RETURN: Next Op found in the search. 198 * 199 * DESCRIPTION: Get next op in tree (walking the tree in depth-first order) 200 * Return NULL when reaching "origin" or when walking up from root 201 * 202 ******************************************************************************/ 203 204union acpi_parse_object * 205acpi_ps_get_depth_next ( 206 union acpi_parse_object *origin, 207 union acpi_parse_object *op) 208{ 209 union acpi_parse_object *next = NULL; 210 union acpi_parse_object *parent; 211 union acpi_parse_object *arg; 212 213 214 ACPI_FUNCTION_ENTRY (); 215 216 217 if (!op) { 218 return (NULL); 219 } 220 221 /* Look for an argument or child */ 222 223 next = acpi_ps_get_arg (op, 0); 224 if (next) { 225 return (next); 226 } 227 228 /* Look for a sibling */ 229 230 next = op->common.next; 231 if (next) { 232 return (next); 233 } 234 235 /* Look for a sibling of parent */ 236 237 parent = op->common.parent; 238 239 while (parent) { 240 arg = acpi_ps_get_arg (parent, 0); 241 while (arg && (arg != origin) && (arg != op)) { 242 arg = arg->common.next; 243 } 244 245 if (arg == origin) { 246 /* Reached parent of origin, end search */ 247 248 return (NULL); 249 } 250 251 if (parent->common.next) { 252 /* Found sibling of parent */ 253 254 return (parent->common.next); 255 } 256 257 op = parent; 258 parent = parent->common.parent; 259 } 260 261 return (next); 262} 263 264 265#ifdef ACPI_OBSOLETE_FUNCTIONS 266/******************************************************************************* 267 * 268 * FUNCTION: acpi_ps_get_child 269 * 270 * PARAMETERS: Op - Get the child of this Op 271 * 272 * RETURN: Child Op, Null if none is found. 273 * 274 * DESCRIPTION: Get op's children or NULL if none 275 * 276 ******************************************************************************/ 277 278union acpi_parse_object * 279acpi_ps_get_child ( 280 union acpi_parse_object *op) 281{ 282 union acpi_parse_object *child = NULL; 283 284 285 ACPI_FUNCTION_ENTRY (); 286 287 288 switch (op->common.aml_opcode) { 289 case AML_SCOPE_OP: 290 case AML_ELSE_OP: 291 case AML_DEVICE_OP: 292 case AML_THERMAL_ZONE_OP: 293 case AML_INT_METHODCALL_OP: 294 295 child = acpi_ps_get_arg (op, 0); 296 break; 297 298 299 case AML_BUFFER_OP: 300 case AML_PACKAGE_OP: 301 case AML_METHOD_OP: 302 case AML_IF_OP: 303 case AML_WHILE_OP: 304 case AML_FIELD_OP: 305 306 child = acpi_ps_get_arg (op, 1); 307 break; 308 309 310 case AML_POWER_RES_OP: 311 case AML_INDEX_FIELD_OP: 312 313 child = acpi_ps_get_arg (op, 2); 314 break; 315 316 317 case AML_PROCESSOR_OP: 318 case AML_BANK_FIELD_OP: 319 320 child = acpi_ps_get_arg (op, 3); 321 break; 322 323 324 default: 325 /* All others have no children */ 326 break; 327 } 328 329 return (child); 330} 331#endif 332 333#endif /* ACPI_FUTURE_USAGE */ 334