root/drivers/acpi/acpica/pstree.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ps_append_arg
  3. acpi_ps_get_depth_next
  4. acpi_ps_get_child

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: pstree - Parser op tree manipulation/traversal/search
   5  *
   6  * Copyright (C) 2000 - 2019, Intel Corp.
   7  *
   8  *****************************************************************************/
   9 
  10 #include <acpi/acpi.h>
  11 #include "accommon.h"
  12 #include "acparser.h"
  13 #include "amlcode.h"
  14 #include "acconvert.h"
  15 
  16 #define _COMPONENT          ACPI_PARSER
  17 ACPI_MODULE_NAME("pstree")
  18 
  19 /* Local prototypes */
  20 #ifdef ACPI_OBSOLETE_FUNCTIONS
  21 union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op);
  22 #endif
  23 
  24 /*******************************************************************************
  25  *
  26  * FUNCTION:    acpi_ps_get_arg
  27  *
  28  * PARAMETERS:  op              - Get an argument for this op
  29  *              argn            - Nth argument to get
  30  *
  31  * RETURN:      The argument (as an Op object). NULL if argument does not exist
  32  *
  33  * DESCRIPTION: Get the specified op's argument.
  34  *
  35  ******************************************************************************/
  36 
  37 union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn)
  38 {
  39         union acpi_parse_object *arg = NULL;
  40         const struct acpi_opcode_info *op_info;
  41 
  42         ACPI_FUNCTION_ENTRY();
  43 
  44 /*
  45         if (Op->Common.aml_opcode == AML_INT_CONNECTION_OP)
  46         {
  47                 return (Op->Common.Value.Arg);
  48         }
  49 */
  50         /* Get the info structure for this opcode */
  51 
  52         op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
  53         if (op_info->class == AML_CLASS_UNKNOWN) {
  54 
  55                 /* Invalid opcode or ASCII character */
  56 
  57                 return (NULL);
  58         }
  59 
  60         /* Check if this opcode requires argument sub-objects */
  61 
  62         if (!(op_info->flags & AML_HAS_ARGS)) {
  63 
  64                 /* Has no linked argument objects */
  65 
  66                 return (NULL);
  67         }
  68 
  69         /* Get the requested argument object */
  70 
  71         arg = op->common.value.arg;
  72         while (arg && argn) {
  73                 argn--;
  74                 arg = arg->common.next;
  75         }
  76 
  77         return (arg);
  78 }
  79 
  80 /*******************************************************************************
  81  *
  82  * FUNCTION:    acpi_ps_append_arg
  83  *
  84  * PARAMETERS:  op              - Append an argument to this Op.
  85  *              arg             - Argument Op to append
  86  *
  87  * RETURN:      None.
  88  *
  89  * DESCRIPTION: Append an argument to an op's argument list (a NULL arg is OK)
  90  *
  91  ******************************************************************************/
  92 
  93 void
  94 acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
  95 {
  96         union acpi_parse_object *prev_arg;
  97         const struct acpi_opcode_info *op_info;
  98 
  99         ACPI_FUNCTION_TRACE(ps_append_arg);
 100 
 101         if (!op) {
 102                 return_VOID;
 103         }
 104 
 105         /* Get the info structure for this opcode */
 106 
 107         op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
 108         if (op_info->class == AML_CLASS_UNKNOWN) {
 109 
 110                 /* Invalid opcode */
 111 
 112                 ACPI_ERROR((AE_INFO, "Invalid AML Opcode: 0x%2.2X",
 113                             op->common.aml_opcode));
 114                 return_VOID;
 115         }
 116 
 117         /* Check if this opcode requires argument sub-objects */
 118 
 119         if (!(op_info->flags & AML_HAS_ARGS)) {
 120 
 121                 /* Has no linked argument objects */
 122 
 123                 return_VOID;
 124         }
 125 
 126         /* Append the argument to the linked argument list */
 127 
 128         if (op->common.value.arg) {
 129 
 130                 /* Append to existing argument list */
 131 
 132                 prev_arg = op->common.value.arg;
 133                 while (prev_arg->common.next) {
 134                         prev_arg = prev_arg->common.next;
 135                 }
 136                 prev_arg->common.next = arg;
 137         } else {
 138                 /* No argument list, this will be the first argument */
 139 
 140                 op->common.value.arg = arg;
 141         }
 142 
 143         /* Set the parent in this arg and any args linked after it */
 144 
 145         while (arg) {
 146                 arg->common.parent = op;
 147                 arg = arg->common.next;
 148 
 149                 op->common.arg_list_length++;
 150         }
 151 
 152         return_VOID;
 153 }
 154 
 155 /*******************************************************************************
 156  *
 157  * FUNCTION:    acpi_ps_get_depth_next
 158  *
 159  * PARAMETERS:  origin          - Root of subtree to search
 160  *              op              - Last (previous) Op that was found
 161  *
 162  * RETURN:      Next Op found in the search.
 163  *
 164  * DESCRIPTION: Get next op in tree (walking the tree in depth-first order)
 165  *              Return NULL when reaching "origin" or when walking up from root
 166  *
 167  ******************************************************************************/
 168 
 169 union acpi_parse_object *acpi_ps_get_depth_next(union acpi_parse_object *origin,
 170                                                 union acpi_parse_object *op)
 171 {
 172         union acpi_parse_object *next = NULL;
 173         union acpi_parse_object *parent;
 174         union acpi_parse_object *arg;
 175 
 176         ACPI_FUNCTION_ENTRY();
 177 
 178         if (!op) {
 179                 return (NULL);
 180         }
 181 
 182         /* Look for an argument or child */
 183 
 184         next = acpi_ps_get_arg(op, 0);
 185         if (next) {
 186                 ASL_CV_LABEL_FILENODE(next);
 187                 return (next);
 188         }
 189 
 190         /* Look for a sibling */
 191 
 192         next = op->common.next;
 193         if (next) {
 194                 ASL_CV_LABEL_FILENODE(next);
 195                 return (next);
 196         }
 197 
 198         /* Look for a sibling of parent */
 199 
 200         parent = op->common.parent;
 201 
 202         while (parent) {
 203                 arg = acpi_ps_get_arg(parent, 0);
 204                 while (arg && (arg != origin) && (arg != op)) {
 205 
 206                         ASL_CV_LABEL_FILENODE(arg);
 207                         arg = arg->common.next;
 208                 }
 209 
 210                 if (arg == origin) {
 211 
 212                         /* Reached parent of origin, end search */
 213 
 214                         return (NULL);
 215                 }
 216 
 217                 if (parent->common.next) {
 218 
 219                         /* Found sibling of parent */
 220 
 221                         ASL_CV_LABEL_FILENODE(parent->common.next);
 222                         return (parent->common.next);
 223                 }
 224 
 225                 op = parent;
 226                 parent = parent->common.parent;
 227         }
 228 
 229         ASL_CV_LABEL_FILENODE(next);
 230         return (next);
 231 }
 232 
 233 #ifdef ACPI_OBSOLETE_FUNCTIONS
 234 /*******************************************************************************
 235  *
 236  * FUNCTION:    acpi_ps_get_child
 237  *
 238  * PARAMETERS:  op              - Get the child of this Op
 239  *
 240  * RETURN:      Child Op, Null if none is found.
 241  *
 242  * DESCRIPTION: Get op's children or NULL if none
 243  *
 244  ******************************************************************************/
 245 
 246 union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op)
 247 {
 248         union acpi_parse_object *child = NULL;
 249 
 250         ACPI_FUNCTION_ENTRY();
 251 
 252         switch (op->common.aml_opcode) {
 253         case AML_SCOPE_OP:
 254         case AML_ELSE_OP:
 255         case AML_DEVICE_OP:
 256         case AML_THERMAL_ZONE_OP:
 257         case AML_INT_METHODCALL_OP:
 258 
 259                 child = acpi_ps_get_arg(op, 0);
 260                 break;
 261 
 262         case AML_BUFFER_OP:
 263         case AML_PACKAGE_OP:
 264         case AML_VARIABLE_PACKAGE_OP:
 265         case AML_METHOD_OP:
 266         case AML_IF_OP:
 267         case AML_WHILE_OP:
 268         case AML_FIELD_OP:
 269 
 270                 child = acpi_ps_get_arg(op, 1);
 271                 break;
 272 
 273         case AML_POWER_RESOURCE_OP:
 274         case AML_INDEX_FIELD_OP:
 275 
 276                 child = acpi_ps_get_arg(op, 2);
 277                 break;
 278 
 279         case AML_PROCESSOR_OP:
 280         case AML_BANK_FIELD_OP:
 281 
 282                 child = acpi_ps_get_arg(op, 3);
 283                 break;
 284 
 285         default:
 286 
 287                 /* All others have no children */
 288 
 289                 break;
 290         }
 291 
 292         return (child);
 293 }
 294 #endif

/* [<][>][^][v][top][bottom][index][help] */