diff options
Diffstat (limited to 'drivers/acpi/parser/psloop.c')
-rw-r--r-- | drivers/acpi/parser/psloop.c | 61 |
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) { |