cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

psobject.c (19901B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: psobject - Support for parse objects
      5 *
      6 * Copyright (C) 2000 - 2022, 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#include "acnamesp.h"
     16
     17#define _COMPONENT          ACPI_PARSER
     18ACPI_MODULE_NAME("psobject")
     19
     20/* Local prototypes */
     21static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
     22
     23/*******************************************************************************
     24 *
     25 * FUNCTION:    acpi_ps_get_aml_opcode
     26 *
     27 * PARAMETERS:  walk_state          - Current state
     28 *
     29 * RETURN:      Status
     30 *
     31 * DESCRIPTION: Extract the next AML opcode from the input stream.
     32 *
     33 ******************************************************************************/
     34
     35static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
     36{
     37	ACPI_ERROR_ONLY(u32 aml_offset);
     38
     39	ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
     40
     41	walk_state->aml = walk_state->parser_state.aml;
     42	walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
     43
     44	/*
     45	 * First cut to determine what we have found:
     46	 * 1) A valid AML opcode
     47	 * 2) A name string
     48	 * 3) An unknown/invalid opcode
     49	 */
     50	walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
     51
     52	switch (walk_state->op_info->class) {
     53	case AML_CLASS_ASCII:
     54	case AML_CLASS_PREFIX:
     55		/*
     56		 * Starts with a valid prefix or ASCII char, this is a name
     57		 * string. Convert the bare name string to a namepath.
     58		 */
     59		walk_state->opcode = AML_INT_NAMEPATH_OP;
     60		walk_state->arg_types = ARGP_NAMESTRING;
     61		break;
     62
     63	case AML_CLASS_UNKNOWN:
     64
     65		/* The opcode is unrecognized. Complain and skip unknown opcodes */
     66
     67		if (walk_state->pass_number == 2) {
     68			ACPI_ERROR_ONLY(aml_offset =
     69					(u32)ACPI_PTR_DIFF(walk_state->aml,
     70							   walk_state->
     71							   parser_state.
     72							   aml_start));
     73
     74			ACPI_ERROR((AE_INFO,
     75				    "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
     76				    walk_state->opcode,
     77				    (u32)(aml_offset +
     78					  sizeof(struct acpi_table_header))));
     79
     80			ACPI_DUMP_BUFFER((walk_state->parser_state.aml - 16),
     81					 48);
     82
     83#ifdef ACPI_ASL_COMPILER
     84			/*
     85			 * This is executed for the disassembler only. Output goes
     86			 * to the disassembled ASL output file.
     87			 */
     88			acpi_os_printf
     89			    ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
     90			     walk_state->opcode,
     91			     (u32)(aml_offset +
     92				   sizeof(struct acpi_table_header)));
     93
     94			ACPI_ERROR((AE_INFO,
     95				    "Aborting disassembly, AML byte code is corrupt"));
     96
     97			/* Dump the context surrounding the invalid opcode */
     98
     99			acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
    100					     aml - 16), 48, DB_BYTE_DISPLAY,
    101					    (aml_offset +
    102					     sizeof(struct acpi_table_header) -
    103					     16));
    104			acpi_os_printf(" */\n");
    105
    106			/*
    107			 * Just abort the disassembly, cannot continue because the
    108			 * parser is essentially lost. The disassembler can then
    109			 * randomly fail because an ill-constructed parse tree
    110			 * can result.
    111			 */
    112			return_ACPI_STATUS(AE_AML_BAD_OPCODE);
    113#endif
    114		}
    115
    116		/* Increment past one-byte or two-byte opcode */
    117
    118		walk_state->parser_state.aml++;
    119		if (walk_state->opcode > 0xFF) {	/* Can only happen if first byte is 0x5B */
    120			walk_state->parser_state.aml++;
    121		}
    122
    123		return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
    124
    125	default:
    126
    127		/* Found opcode info, this is a normal opcode */
    128
    129		walk_state->parser_state.aml +=
    130		    acpi_ps_get_opcode_size(walk_state->opcode);
    131		walk_state->arg_types = walk_state->op_info->parse_args;
    132		break;
    133	}
    134
    135	return_ACPI_STATUS(AE_OK);
    136}
    137
    138/*******************************************************************************
    139 *
    140 * FUNCTION:    acpi_ps_build_named_op
    141 *
    142 * PARAMETERS:  walk_state          - Current state
    143 *              aml_op_start        - Begin of named Op in AML
    144 *              unnamed_op          - Early Op (not a named Op)
    145 *              op                  - Returned Op
    146 *
    147 * RETURN:      Status
    148 *
    149 * DESCRIPTION: Parse a named Op
    150 *
    151 ******************************************************************************/
    152
    153acpi_status
    154acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
    155		       u8 *aml_op_start,
    156		       union acpi_parse_object *unnamed_op,
    157		       union acpi_parse_object **op)
    158{
    159	acpi_status status = AE_OK;
    160	union acpi_parse_object *arg = NULL;
    161
    162	ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
    163
    164	unnamed_op->common.value.arg = NULL;
    165	unnamed_op->common.arg_list_length = 0;
    166	unnamed_op->common.aml_opcode = walk_state->opcode;
    167
    168	/*
    169	 * Get and append arguments until we find the node that contains
    170	 * the name (the type ARGP_NAME).
    171	 */
    172	while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
    173	       (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) {
    174		ASL_CV_CAPTURE_COMMENTS(walk_state);
    175		status =
    176		    acpi_ps_get_next_arg(walk_state,
    177					 &(walk_state->parser_state),
    178					 GET_CURRENT_ARG_TYPE(walk_state->
    179							      arg_types), &arg);
    180		if (ACPI_FAILURE(status)) {
    181			return_ACPI_STATUS(status);
    182		}
    183
    184		acpi_ps_append_arg(unnamed_op, arg);
    185		INCREMENT_ARG_LIST(walk_state->arg_types);
    186	}
    187
    188	/* are there any inline comments associated with the name_seg?? If so, save this. */
    189
    190	ASL_CV_CAPTURE_COMMENTS(walk_state);
    191
    192#ifdef ACPI_ASL_COMPILER
    193	if (acpi_gbl_current_inline_comment != NULL) {
    194		unnamed_op->common.name_comment =
    195		    acpi_gbl_current_inline_comment;
    196		acpi_gbl_current_inline_comment = NULL;
    197	}
    198#endif
    199
    200	/*
    201	 * Make sure that we found a NAME and didn't run out of arguments
    202	 */
    203	if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
    204		return_ACPI_STATUS(AE_AML_NO_OPERAND);
    205	}
    206
    207	/* We know that this arg is a name, move to next arg */
    208
    209	INCREMENT_ARG_LIST(walk_state->arg_types);
    210
    211	/*
    212	 * Find the object. This will either insert the object into
    213	 * the namespace or simply look it up
    214	 */
    215	walk_state->op = NULL;
    216
    217	status = walk_state->descending_callback(walk_state, op);
    218	if (ACPI_FAILURE(status)) {
    219		if (status != AE_CTRL_TERMINATE) {
    220			ACPI_EXCEPTION((AE_INFO, status,
    221					"During name lookup/catalog"));
    222		}
    223		return_ACPI_STATUS(status);
    224	}
    225
    226	if (!*op) {
    227		return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
    228	}
    229
    230	status = acpi_ps_next_parse_state(walk_state, *op, status);
    231	if (ACPI_FAILURE(status)) {
    232		if (status == AE_CTRL_PENDING) {
    233			status = AE_CTRL_PARSE_PENDING;
    234		}
    235		return_ACPI_STATUS(status);
    236	}
    237
    238	acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
    239
    240#ifdef ACPI_ASL_COMPILER
    241
    242	/* save any comments that might be associated with unnamed_op. */
    243
    244	(*op)->common.inline_comment = unnamed_op->common.inline_comment;
    245	(*op)->common.end_node_comment = unnamed_op->common.end_node_comment;
    246	(*op)->common.close_brace_comment =
    247	    unnamed_op->common.close_brace_comment;
    248	(*op)->common.name_comment = unnamed_op->common.name_comment;
    249	(*op)->common.comment_list = unnamed_op->common.comment_list;
    250	(*op)->common.end_blk_comment = unnamed_op->common.end_blk_comment;
    251	(*op)->common.cv_filename = unnamed_op->common.cv_filename;
    252	(*op)->common.cv_parent_filename =
    253	    unnamed_op->common.cv_parent_filename;
    254	(*op)->named.aml = unnamed_op->common.aml;
    255
    256	unnamed_op->common.inline_comment = NULL;
    257	unnamed_op->common.end_node_comment = NULL;
    258	unnamed_op->common.close_brace_comment = NULL;
    259	unnamed_op->common.name_comment = NULL;
    260	unnamed_op->common.comment_list = NULL;
    261	unnamed_op->common.end_blk_comment = NULL;
    262#endif
    263
    264	if ((*op)->common.aml_opcode == AML_REGION_OP ||
    265	    (*op)->common.aml_opcode == AML_DATA_REGION_OP) {
    266		/*
    267		 * Defer final parsing of an operation_region body, because we don't
    268		 * have enough info in the first pass to parse it correctly (i.e.,
    269		 * there may be method calls within the term_arg elements of the body.)
    270		 *
    271		 * However, we must continue parsing because the opregion is not a
    272		 * standalone package -- we don't know where the end is at this point.
    273		 *
    274		 * (Length is unknown until parse of the body complete)
    275		 */
    276		(*op)->named.data = aml_op_start;
    277		(*op)->named.length = 0;
    278	}
    279
    280	return_ACPI_STATUS(AE_OK);
    281}
    282
    283/*******************************************************************************
    284 *
    285 * FUNCTION:    acpi_ps_create_op
    286 *
    287 * PARAMETERS:  walk_state          - Current state
    288 *              aml_op_start        - Op start in AML
    289 *              new_op              - Returned Op
    290 *
    291 * RETURN:      Status
    292 *
    293 * DESCRIPTION: Get Op from AML
    294 *
    295 ******************************************************************************/
    296
    297acpi_status
    298acpi_ps_create_op(struct acpi_walk_state *walk_state,
    299		  u8 *aml_op_start, union acpi_parse_object **new_op)
    300{
    301	acpi_status status = AE_OK;
    302	union acpi_parse_object *op;
    303	union acpi_parse_object *named_op = NULL;
    304	union acpi_parse_object *parent_scope;
    305	u8 argument_count;
    306	const struct acpi_opcode_info *op_info;
    307
    308	ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
    309
    310	status = acpi_ps_get_aml_opcode(walk_state);
    311	if (status == AE_CTRL_PARSE_CONTINUE) {
    312		return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
    313	}
    314	if (ACPI_FAILURE(status)) {
    315		return_ACPI_STATUS(status);
    316	}
    317
    318	/* Create Op structure and append to parent's argument list */
    319
    320	walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
    321	op = acpi_ps_alloc_op(walk_state->opcode, aml_op_start);
    322	if (!op) {
    323		return_ACPI_STATUS(AE_NO_MEMORY);
    324	}
    325
    326	if (walk_state->op_info->flags & AML_NAMED) {
    327		status =
    328		    acpi_ps_build_named_op(walk_state, aml_op_start, op,
    329					   &named_op);
    330		acpi_ps_free_op(op);
    331
    332#ifdef ACPI_ASL_COMPILER
    333		if (acpi_gbl_disasm_flag
    334		    && walk_state->opcode == AML_EXTERNAL_OP
    335		    && status == AE_NOT_FOUND) {
    336			/*
    337			 * If parsing of AML_EXTERNAL_OP's name path fails, then skip
    338			 * past this opcode and keep parsing. This is a much better
    339			 * alternative than to abort the entire disassembler. At this
    340			 * point, the parser_state is at the end of the namepath of the
    341			 * external declaration opcode. Setting walk_state->Aml to
    342			 * walk_state->parser_state.Aml + 2 moves increments the
    343			 * walk_state->Aml past the object type and the paramcount of the
    344			 * external opcode.
    345			 */
    346			walk_state->aml = walk_state->parser_state.aml + 2;
    347			walk_state->parser_state.aml = walk_state->aml;
    348			return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
    349		}
    350#endif
    351		if (ACPI_FAILURE(status)) {
    352			return_ACPI_STATUS(status);
    353		}
    354
    355		*new_op = named_op;
    356		return_ACPI_STATUS(AE_OK);
    357	}
    358
    359	/* Not a named opcode, just allocate Op and append to parent */
    360
    361	if (walk_state->op_info->flags & AML_CREATE) {
    362		/*
    363		 * Backup to beginning of create_XXXfield declaration
    364		 * body_length is unknown until we parse the body
    365		 */
    366		op->named.data = aml_op_start;
    367		op->named.length = 0;
    368	}
    369
    370	if (walk_state->opcode == AML_BANK_FIELD_OP) {
    371		/*
    372		 * Backup to beginning of bank_field declaration
    373		 * body_length is unknown until we parse the body
    374		 */
    375		op->named.data = aml_op_start;
    376		op->named.length = 0;
    377	}
    378
    379	parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
    380	acpi_ps_append_arg(parent_scope, op);
    381
    382	if (parent_scope) {
    383		op_info =
    384		    acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
    385		if (op_info->flags & AML_HAS_TARGET) {
    386			argument_count =
    387			    acpi_ps_get_argument_count(op_info->type);
    388			if (parent_scope->common.arg_list_length >
    389			    argument_count) {
    390				op->common.flags |= ACPI_PARSEOP_TARGET;
    391			}
    392		}
    393
    394		/*
    395		 * Special case for both Increment() and Decrement(), where
    396		 * the lone argument is both a source and a target.
    397		 */
    398		else if ((parent_scope->common.aml_opcode == AML_INCREMENT_OP)
    399			 || (parent_scope->common.aml_opcode ==
    400			     AML_DECREMENT_OP)) {
    401			op->common.flags |= ACPI_PARSEOP_TARGET;
    402		}
    403	}
    404
    405	if (walk_state->descending_callback != NULL) {
    406		/*
    407		 * Find the object. This will either insert the object into
    408		 * the namespace or simply look it up
    409		 */
    410		walk_state->op = *new_op = op;
    411
    412		status = walk_state->descending_callback(walk_state, &op);
    413		status = acpi_ps_next_parse_state(walk_state, op, status);
    414		if (status == AE_CTRL_PENDING) {
    415			status = AE_CTRL_PARSE_PENDING;
    416		}
    417	}
    418
    419	return_ACPI_STATUS(status);
    420}
    421
    422/*******************************************************************************
    423 *
    424 * FUNCTION:    acpi_ps_complete_op
    425 *
    426 * PARAMETERS:  walk_state          - Current state
    427 *              op                  - Returned Op
    428 *              status              - Parse status before complete Op
    429 *
    430 * RETURN:      Status
    431 *
    432 * DESCRIPTION: Complete Op
    433 *
    434 ******************************************************************************/
    435
    436acpi_status
    437acpi_ps_complete_op(struct acpi_walk_state *walk_state,
    438		    union acpi_parse_object **op, acpi_status status)
    439{
    440	acpi_status status2;
    441
    442	ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
    443
    444	/*
    445	 * Finished one argument of the containing scope
    446	 */
    447	walk_state->parser_state.scope->parse_scope.arg_count--;
    448
    449	/* Close this Op (will result in parse subtree deletion) */
    450
    451	status2 = acpi_ps_complete_this_op(walk_state, *op);
    452	if (ACPI_FAILURE(status2)) {
    453		return_ACPI_STATUS(status2);
    454	}
    455
    456	*op = NULL;
    457
    458	switch (status) {
    459	case AE_OK:
    460
    461		break;
    462
    463	case AE_CTRL_TRANSFER:
    464
    465		/* We are about to transfer to a called method */
    466
    467		walk_state->prev_op = NULL;
    468		walk_state->prev_arg_types = walk_state->arg_types;
    469		return_ACPI_STATUS(status);
    470
    471	case AE_CTRL_END:
    472
    473		acpi_ps_pop_scope(&(walk_state->parser_state), op,
    474				  &walk_state->arg_types,
    475				  &walk_state->arg_count);
    476
    477		if (*op) {
    478			walk_state->op = *op;
    479			walk_state->op_info =
    480			    acpi_ps_get_opcode_info((*op)->common.aml_opcode);
    481			walk_state->opcode = (*op)->common.aml_opcode;
    482
    483			status = walk_state->ascending_callback(walk_state);
    484			(void)acpi_ps_next_parse_state(walk_state, *op, status);
    485
    486			status2 = acpi_ps_complete_this_op(walk_state, *op);
    487			if (ACPI_FAILURE(status2)) {
    488				return_ACPI_STATUS(status2);
    489			}
    490		}
    491
    492		break;
    493
    494	case AE_CTRL_BREAK:
    495	case AE_CTRL_CONTINUE:
    496
    497		/* Pop off scopes until we find the While */
    498
    499		while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
    500			acpi_ps_pop_scope(&(walk_state->parser_state), op,
    501					  &walk_state->arg_types,
    502					  &walk_state->arg_count);
    503		}
    504
    505		/* Close this iteration of the While loop */
    506
    507		walk_state->op = *op;
    508		walk_state->op_info =
    509		    acpi_ps_get_opcode_info((*op)->common.aml_opcode);
    510		walk_state->opcode = (*op)->common.aml_opcode;
    511
    512		status = walk_state->ascending_callback(walk_state);
    513		(void)acpi_ps_next_parse_state(walk_state, *op, status);
    514
    515		status2 = acpi_ps_complete_this_op(walk_state, *op);
    516		if (ACPI_FAILURE(status2)) {
    517			return_ACPI_STATUS(status2);
    518		}
    519
    520		break;
    521
    522	case AE_CTRL_TERMINATE:
    523
    524		/* Clean up */
    525		do {
    526			if (*op) {
    527				status2 =
    528				    acpi_ps_complete_this_op(walk_state, *op);
    529				if (ACPI_FAILURE(status2)) {
    530					return_ACPI_STATUS(status2);
    531				}
    532
    533				acpi_ut_delete_generic_state
    534				    (acpi_ut_pop_generic_state
    535				     (&walk_state->control_state));
    536			}
    537
    538			acpi_ps_pop_scope(&(walk_state->parser_state), op,
    539					  &walk_state->arg_types,
    540					  &walk_state->arg_count);
    541
    542		} while (*op);
    543
    544		return_ACPI_STATUS(AE_OK);
    545
    546	default:		/* All other non-AE_OK status */
    547
    548		do {
    549			if (*op) {
    550				/*
    551				 * These Opcodes need to be removed from the namespace because they
    552				 * get created even if these opcodes cannot be created due to
    553				 * errors.
    554				 */
    555				if (((*op)->common.aml_opcode == AML_REGION_OP)
    556				    || ((*op)->common.aml_opcode ==
    557					AML_DATA_REGION_OP)) {
    558					acpi_ns_delete_children((*op)->common.
    559								node);
    560					acpi_ns_remove_node((*op)->common.node);
    561					(*op)->common.node = NULL;
    562					acpi_ps_delete_parse_tree(*op);
    563				}
    564
    565				status2 =
    566				    acpi_ps_complete_this_op(walk_state, *op);
    567				if (ACPI_FAILURE(status2)) {
    568					return_ACPI_STATUS(status2);
    569				}
    570			}
    571
    572			acpi_ps_pop_scope(&(walk_state->parser_state), op,
    573					  &walk_state->arg_types,
    574					  &walk_state->arg_count);
    575
    576		} while (*op);
    577
    578#if 0
    579		/*
    580		 * TBD: Cleanup parse ops on error
    581		 */
    582		if (*op == NULL) {
    583			acpi_ps_pop_scope(parser_state, op,
    584					  &walk_state->arg_types,
    585					  &walk_state->arg_count);
    586		}
    587#endif
    588		walk_state->prev_op = NULL;
    589		walk_state->prev_arg_types = walk_state->arg_types;
    590
    591		if (walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL) {
    592			/*
    593			 * There was something that went wrong while executing code at the
    594			 * module-level. We need to skip parsing whatever caused the
    595			 * error and keep going. One runtime error during the table load
    596			 * should not cause the entire table to not be loaded. This is
    597			 * because there could be correct AML beyond the parts that caused
    598			 * the runtime error.
    599			 */
    600			ACPI_INFO(("Ignoring error and continuing table load"));
    601			return_ACPI_STATUS(AE_OK);
    602		}
    603		return_ACPI_STATUS(status);
    604	}
    605
    606	/* This scope complete? */
    607
    608	if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
    609		acpi_ps_pop_scope(&(walk_state->parser_state), op,
    610				  &walk_state->arg_types,
    611				  &walk_state->arg_count);
    612		ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
    613	} else {
    614		*op = NULL;
    615	}
    616
    617	return_ACPI_STATUS(AE_OK);
    618}
    619
    620/*******************************************************************************
    621 *
    622 * FUNCTION:    acpi_ps_complete_final_op
    623 *
    624 * PARAMETERS:  walk_state          - Current state
    625 *              op                  - Current Op
    626 *              status              - Current parse status before complete last
    627 *                                    Op
    628 *
    629 * RETURN:      Status
    630 *
    631 * DESCRIPTION: Complete last Op.
    632 *
    633 ******************************************************************************/
    634
    635acpi_status
    636acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
    637			  union acpi_parse_object *op, acpi_status status)
    638{
    639	acpi_status status2;
    640
    641	ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
    642
    643	/*
    644	 * Complete the last Op (if not completed), and clear the scope stack.
    645	 * It is easily possible to end an AML "package" with an unbounded number
    646	 * of open scopes (such as when several ASL blocks are closed with
    647	 * sequential closing braces). We want to terminate each one cleanly.
    648	 */
    649	ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
    650			  op));
    651	do {
    652		if (op) {
    653			if (walk_state->ascending_callback != NULL) {
    654				walk_state->op = op;
    655				walk_state->op_info =
    656				    acpi_ps_get_opcode_info(op->common.
    657							    aml_opcode);
    658				walk_state->opcode = op->common.aml_opcode;
    659
    660				status =
    661				    walk_state->ascending_callback(walk_state);
    662				status =
    663				    acpi_ps_next_parse_state(walk_state, op,
    664							     status);
    665				if (status == AE_CTRL_PENDING) {
    666					status =
    667					    acpi_ps_complete_op(walk_state, &op,
    668								AE_OK);
    669					if (ACPI_FAILURE(status)) {
    670						return_ACPI_STATUS(status);
    671					}
    672				}
    673
    674				if (status == AE_CTRL_TERMINATE) {
    675					status = AE_OK;
    676
    677					/* Clean up */
    678					do {
    679						if (op) {
    680							status2 =
    681							    acpi_ps_complete_this_op
    682							    (walk_state, op);
    683							if (ACPI_FAILURE
    684							    (status2)) {
    685								return_ACPI_STATUS
    686								    (status2);
    687							}
    688						}
    689
    690						acpi_ps_pop_scope(&
    691								  (walk_state->
    692								   parser_state),
    693								  &op,
    694								  &walk_state->
    695								  arg_types,
    696								  &walk_state->
    697								  arg_count);
    698
    699					} while (op);
    700
    701					return_ACPI_STATUS(status);
    702				}
    703
    704				else if (ACPI_FAILURE(status)) {
    705
    706					/* First error is most important */
    707
    708					(void)
    709					    acpi_ps_complete_this_op(walk_state,
    710								     op);
    711					return_ACPI_STATUS(status);
    712				}
    713			}
    714
    715			status2 = acpi_ps_complete_this_op(walk_state, op);
    716			if (ACPI_FAILURE(status2)) {
    717				return_ACPI_STATUS(status2);
    718			}
    719		}
    720
    721		acpi_ps_pop_scope(&(walk_state->parser_state), &op,
    722				  &walk_state->arg_types,
    723				  &walk_state->arg_count);
    724
    725	} while (op);
    726
    727	return_ACPI_STATUS(status);
    728}