aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/parser/psloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/parser/psloop.c')
-rw-r--r--drivers/acpi/parser/psloop.c61
1 files changed, 45 insertions, 16 deletions
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c
index 773aee82fbb8..c06238e55d98 100644
--- a/drivers/acpi/parser/psloop.c
+++ b/drivers/acpi/parser/psloop.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -182,6 +182,7 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
182 ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state); 182 ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
183 183
184 unnamed_op->common.value.arg = NULL; 184 unnamed_op->common.value.arg = NULL;
185 unnamed_op->common.arg_list_length = 0;
185 unnamed_op->common.aml_opcode = walk_state->opcode; 186 unnamed_op->common.aml_opcode = walk_state->opcode;
186 187
187 /* 188 /*
@@ -241,7 +242,8 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
241 acpi_ps_append_arg(*op, unnamed_op->common.value.arg); 242 acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
242 acpi_gbl_depth++; 243 acpi_gbl_depth++;
243 244
244 if ((*op)->common.aml_opcode == AML_REGION_OP) { 245 if ((*op)->common.aml_opcode == AML_REGION_OP ||
246 (*op)->common.aml_opcode == AML_DATA_REGION_OP) {
245 /* 247 /*
246 * Defer final parsing of an operation_region body, because we don't 248 * Defer final parsing of an operation_region body, because we don't
247 * have enough info in the first pass to parse it correctly (i.e., 249 * have enough info in the first pass to parse it correctly (i.e.,
@@ -280,6 +282,9 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state,
280 acpi_status status = AE_OK; 282 acpi_status status = AE_OK;
281 union acpi_parse_object *op; 283 union acpi_parse_object *op;
282 union acpi_parse_object *named_op = NULL; 284 union acpi_parse_object *named_op = NULL;
285 union acpi_parse_object *parent_scope;
286 u8 argument_count;
287 const struct acpi_opcode_info *op_info;
283 288
284 ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state); 289 ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
285 290
@@ -320,8 +325,32 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state,
320 op->named.length = 0; 325 op->named.length = 0;
321 } 326 }
322 327
323 acpi_ps_append_arg(acpi_ps_get_parent_scope 328 if (walk_state->opcode == AML_BANK_FIELD_OP) {
324 (&(walk_state->parser_state)), op); 329 /*
330 * Backup to beginning of bank_field declaration
331 * body_length is unknown until we parse the body
332 */
333 op->named.data = aml_op_start;
334 op->named.length = 0;
335 }
336
337 parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
338 acpi_ps_append_arg(parent_scope, op);
339
340 if (parent_scope) {
341 op_info =
342 acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
343 if (op_info->flags & AML_HAS_TARGET) {
344 argument_count =
345 acpi_ps_get_argument_count(op_info->type);
346 if (parent_scope->common.arg_list_length >
347 argument_count) {
348 op->common.flags |= ACPI_PARSEOP_TARGET;
349 }
350 } else if (parent_scope->common.aml_opcode == AML_INCREMENT_OP) {
351 op->common.flags |= ACPI_PARSEOP_TARGET;
352 }
353 }
325 354
326 if (walk_state->descending_callback != NULL) { 355 if (walk_state->descending_callback != NULL) {
327 /* 356 /*
@@ -603,13 +632,6 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,
603 acpi_ps_pop_scope(&(walk_state->parser_state), op, 632 acpi_ps_pop_scope(&(walk_state->parser_state), op,
604 &walk_state->arg_types, 633 &walk_state->arg_types,
605 &walk_state->arg_count); 634 &walk_state->arg_count);
606
607 if ((*op)->common.aml_opcode != AML_WHILE_OP) {
608 status2 = acpi_ds_result_stack_pop(walk_state);
609 if (ACPI_FAILURE(status2)) {
610 return_ACPI_STATUS(status2);
611 }
612 }
613 } 635 }
614 636
615 /* Close this iteration of the While loop */ 637 /* Close this iteration of the While loop */
@@ -640,10 +662,6 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,
640 if (ACPI_FAILURE(status2)) { 662 if (ACPI_FAILURE(status2)) {
641 return_ACPI_STATUS(status2); 663 return_ACPI_STATUS(status2);
642 } 664 }
643 status2 = acpi_ds_result_stack_pop(walk_state);
644 if (ACPI_FAILURE(status2)) {
645 return_ACPI_STATUS(status2);
646 }
647 665
648 acpi_ut_delete_generic_state 666 acpi_ut_delete_generic_state
649 (acpi_ut_pop_generic_state 667 (acpi_ut_pop_generic_state
@@ -1005,7 +1023,8 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
1005 acpi_gbl_depth--; 1023 acpi_gbl_depth--;
1006 } 1024 }
1007 1025
1008 if (op->common.aml_opcode == AML_REGION_OP) { 1026 if (op->common.aml_opcode == AML_REGION_OP ||
1027 op->common.aml_opcode == AML_DATA_REGION_OP) {
1009 /* 1028 /*
1010 * Skip parsing of control method or opregion body, 1029 * Skip parsing of control method or opregion body,
1011 * because we don't have enough info in the first pass 1030 * because we don't have enough info in the first pass
@@ -1030,6 +1049,16 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
1030 (u32) (parser_state->aml - op->named.data); 1049 (u32) (parser_state->aml - op->named.data);
1031 } 1050 }
1032 1051
1052 if (op->common.aml_opcode == AML_BANK_FIELD_OP) {
1053 /*
1054 * Backup to beginning of bank_field declaration
1055 *
1056 * body_length is unknown until we parse the body
1057 */
1058 op->named.length =
1059 (u32) (parser_state->aml - op->named.data);
1060 }
1061
1033 /* This op complete, notify the dispatcher */ 1062 /* This op complete, notify the dispatcher */
1034 1063
1035 if (walk_state->ascending_callback != NULL) { 1064 if (walk_state->ascending_callback != NULL) {