linux/drivers/acpi/acpica/psscope.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Module Name: psscope - Parser scope stack management routines
   4 *
   5 *****************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2013, 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 <acpi/acpi.h>
  45#include "accommon.h"
  46#include "acparser.h"
  47
  48#define _COMPONENT          ACPI_PARSER
  49ACPI_MODULE_NAME("psscope")
  50
  51/*******************************************************************************
  52 *
  53 * FUNCTION:    acpi_ps_get_parent_scope
  54 *
  55 * PARAMETERS:  parser_state        - Current parser state object
  56 *
  57 * RETURN:      Pointer to an Op object
  58 *
  59 * DESCRIPTION: Get parent of current op being parsed
  60 *
  61 ******************************************************************************/
  62union acpi_parse_object *acpi_ps_get_parent_scope(struct acpi_parse_state
  63                                                  *parser_state)
  64{
  65
  66        return (parser_state->scope->parse_scope.op);
  67}
  68
  69/*******************************************************************************
  70 *
  71 * FUNCTION:    acpi_ps_has_completed_scope
  72 *
  73 * PARAMETERS:  parser_state        - Current parser state object
  74 *
  75 * RETURN:      Boolean, TRUE = scope completed.
  76 *
  77 * DESCRIPTION: Is parsing of current argument complete?  Determined by
  78 *              1) AML pointer is at or beyond the end of the scope
  79 *              2) The scope argument count has reached zero.
  80 *
  81 ******************************************************************************/
  82
  83u8 acpi_ps_has_completed_scope(struct acpi_parse_state * parser_state)
  84{
  85
  86        return ((u8)
  87                ((parser_state->aml >= parser_state->scope->parse_scope.arg_end
  88                  || !parser_state->scope->parse_scope.arg_count)));
  89}
  90
  91/*******************************************************************************
  92 *
  93 * FUNCTION:    acpi_ps_init_scope
  94 *
  95 * PARAMETERS:  parser_state        - Current parser state object
  96 *              root                - the Root Node of this new scope
  97 *
  98 * RETURN:      Status
  99 *
 100 * DESCRIPTION: Allocate and init a new scope object
 101 *
 102 ******************************************************************************/
 103
 104acpi_status
 105acpi_ps_init_scope(struct acpi_parse_state * parser_state,
 106                   union acpi_parse_object * root_op)
 107{
 108        union acpi_generic_state *scope;
 109
 110        ACPI_FUNCTION_TRACE_PTR(ps_init_scope, root_op);
 111
 112        scope = acpi_ut_create_generic_state();
 113        if (!scope) {
 114                return_ACPI_STATUS(AE_NO_MEMORY);
 115        }
 116
 117        scope->common.descriptor_type = ACPI_DESC_TYPE_STATE_RPSCOPE;
 118        scope->parse_scope.op = root_op;
 119        scope->parse_scope.arg_count = ACPI_VAR_ARGS;
 120        scope->parse_scope.arg_end = parser_state->aml_end;
 121        scope->parse_scope.pkg_end = parser_state->aml_end;
 122
 123        parser_state->scope = scope;
 124        parser_state->start_op = root_op;
 125
 126        return_ACPI_STATUS(AE_OK);
 127}
 128
 129/*******************************************************************************
 130 *
 131 * FUNCTION:    acpi_ps_push_scope
 132 *
 133 * PARAMETERS:  parser_state        - Current parser state object
 134 *              op                  - Current op to be pushed
 135 *              remaining_args      - List of args remaining
 136 *              arg_count           - Fixed or variable number of args
 137 *
 138 * RETURN:      Status
 139 *
 140 * DESCRIPTION: Push current op to begin parsing its argument
 141 *
 142 ******************************************************************************/
 143
 144acpi_status
 145acpi_ps_push_scope(struct acpi_parse_state *parser_state,
 146                   union acpi_parse_object *op,
 147                   u32 remaining_args, u32 arg_count)
 148{
 149        union acpi_generic_state *scope;
 150
 151        ACPI_FUNCTION_TRACE_PTR(ps_push_scope, op);
 152
 153        scope = acpi_ut_create_generic_state();
 154        if (!scope) {
 155                return_ACPI_STATUS(AE_NO_MEMORY);
 156        }
 157
 158        scope->common.descriptor_type = ACPI_DESC_TYPE_STATE_PSCOPE;
 159        scope->parse_scope.op = op;
 160        scope->parse_scope.arg_list = remaining_args;
 161        scope->parse_scope.arg_count = arg_count;
 162        scope->parse_scope.pkg_end = parser_state->pkg_end;
 163
 164        /* Push onto scope stack */
 165
 166        acpi_ut_push_generic_state(&parser_state->scope, scope);
 167
 168        if (arg_count == ACPI_VAR_ARGS) {
 169
 170                /* Multiple arguments */
 171
 172                scope->parse_scope.arg_end = parser_state->pkg_end;
 173        } else {
 174                /* Single argument */
 175
 176                scope->parse_scope.arg_end = ACPI_TO_POINTER(ACPI_MAX_PTR);
 177        }
 178
 179        return_ACPI_STATUS(AE_OK);
 180}
 181
 182/*******************************************************************************
 183 *
 184 * FUNCTION:    acpi_ps_pop_scope
 185 *
 186 * PARAMETERS:  parser_state        - Current parser state object
 187 *              op                  - Where the popped op is returned
 188 *              arg_list            - Where the popped "next argument" is
 189 *                                    returned
 190 *              arg_count           - Count of objects in arg_list
 191 *
 192 * RETURN:      Status
 193 *
 194 * DESCRIPTION: Return to parsing a previous op
 195 *
 196 ******************************************************************************/
 197
 198void
 199acpi_ps_pop_scope(struct acpi_parse_state *parser_state,
 200                  union acpi_parse_object **op, u32 * arg_list, u32 * arg_count)
 201{
 202        union acpi_generic_state *scope = parser_state->scope;
 203
 204        ACPI_FUNCTION_TRACE(ps_pop_scope);
 205
 206        /* Only pop the scope if there is in fact a next scope */
 207
 208        if (scope->common.next) {
 209                scope = acpi_ut_pop_generic_state(&parser_state->scope);
 210
 211                /* Return to parsing previous op */
 212
 213                *op = scope->parse_scope.op;
 214                *arg_list = scope->parse_scope.arg_list;
 215                *arg_count = scope->parse_scope.arg_count;
 216                parser_state->pkg_end = scope->parse_scope.pkg_end;
 217
 218                /* All done with this scope state structure */
 219
 220                acpi_ut_delete_generic_state(scope);
 221        } else {
 222                /* Empty parse stack, prepare to fetch next opcode */
 223
 224                *op = NULL;
 225                *arg_list = 0;
 226                *arg_count = 0;
 227        }
 228
 229        ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 230                          "Popped Op %p Args %X\n", *op, *arg_count));
 231        return_VOID;
 232}
 233
 234/*******************************************************************************
 235 *
 236 * FUNCTION:    acpi_ps_cleanup_scope
 237 *
 238 * PARAMETERS:  parser_state        - Current parser state object
 239 *
 240 * RETURN:      None
 241 *
 242 * DESCRIPTION: Destroy available list, remaining stack levels, and return
 243 *              root scope
 244 *
 245 ******************************************************************************/
 246
 247void acpi_ps_cleanup_scope(struct acpi_parse_state *parser_state)
 248{
 249        union acpi_generic_state *scope;
 250
 251        ACPI_FUNCTION_TRACE_PTR(ps_cleanup_scope, parser_state);
 252
 253        if (!parser_state) {
 254                return_VOID;
 255        }
 256
 257        /* Delete anything on the scope stack */
 258
 259        while (parser_state->scope) {
 260                scope = acpi_ut_pop_generic_state(&parser_state->scope);
 261                acpi_ut_delete_generic_state(scope);
 262        }
 263
 264        return_VOID;
 265}
 266