diff options
author | Lin Ming <ming.m.lin@intel.com> | 2008-04-10 11:06:41 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-04-22 14:29:28 -0400 |
commit | ef805d956320ffa36d068673d5c5eb2a7d13209b (patch) | |
tree | efc621915bc0909d99f523551c062390cc3afa0b | |
parent | 57345ee6b807d32e5eecf724a463378b80cc261c (diff) |
ACPICA: Implemented full argument resolution support for the BankValue argument to BankField
Previously, only constants were supported, now any TermArg may
be used.
http://www.acpica.org/bugzilla/show_bug.cgi?id=387
http://www.acpica.org/bugzilla/show_bug.cgi?id=393
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r-- | drivers/acpi/dispatcher/dsfield.c | 80 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dsopcode.c | 144 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dsutils.c | 4 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dswexec.c | 11 | ||||
-rw-r--r-- | drivers/acpi/executer/exprep.c | 15 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsinit.c | 10 | ||||
-rw-r--r-- | drivers/acpi/parser/psloop.c | 19 | ||||
-rw-r--r-- | drivers/acpi/parser/psopcode.c | 5 | ||||
-rw-r--r-- | drivers/acpi/parser/psparse.c | 2 | ||||
-rw-r--r-- | drivers/acpi/utilities/utdelete.c | 11 | ||||
-rw-r--r-- | drivers/acpi/utilities/utobject.c | 1 | ||||
-rw-r--r-- | include/acpi/acdispat.h | 7 |
12 files changed, 267 insertions, 42 deletions
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c index f049639bac35..e87f6bfbfa5c 100644 --- a/drivers/acpi/dispatcher/dsfield.c +++ b/drivers/acpi/dispatcher/dsfield.c | |||
@@ -281,11 +281,17 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, | |||
281 | arg->common.node = info->field_node; | 281 | arg->common.node = info->field_node; |
282 | info->field_bit_length = arg->common.value.size; | 282 | info->field_bit_length = arg->common.value.size; |
283 | 283 | ||
284 | /* Create and initialize an object for the new Field Node */ | 284 | /* |
285 | 285 | * If there is no object attached to the node, this node was just created | |
286 | status = acpi_ex_prep_field_value(info); | 286 | * and we need to create the field object. Otherwise, this was a lookup |
287 | if (ACPI_FAILURE(status)) { | 287 | * of an existing node and we don't want to create the field object again. |
288 | return_ACPI_STATUS(status); | 288 | */ |
289 | if (!acpi_ns_get_attached_object | ||
290 | (info->field_node)) { | ||
291 | status = acpi_ex_prep_field_value(info); | ||
292 | if (ACPI_FAILURE(status)) { | ||
293 | return_ACPI_STATUS(status); | ||
294 | } | ||
289 | } | 295 | } |
290 | } | 296 | } |
291 | 297 | ||
@@ -399,9 +405,22 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
399 | union acpi_parse_object *arg = NULL; | 405 | union acpi_parse_object *arg = NULL; |
400 | struct acpi_namespace_node *node; | 406 | struct acpi_namespace_node *node; |
401 | u8 type = 0; | 407 | u8 type = 0; |
408 | u32 flags; | ||
402 | 409 | ||
403 | ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op); | 410 | ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op); |
404 | 411 | ||
412 | /* | ||
413 | * During the load phase, we want to enter the name of the field into | ||
414 | * the namespace. During the execute phase (when we evaluate the bank_value | ||
415 | * operand), we want to lookup the name. | ||
416 | */ | ||
417 | if (walk_state->deferred_node) { | ||
418 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE; | ||
419 | } else { | ||
420 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | | ||
421 | ACPI_NS_ERROR_IF_FOUND; | ||
422 | } | ||
423 | |||
405 | switch (walk_state->opcode) { | 424 | switch (walk_state->opcode) { |
406 | case AML_FIELD_OP: | 425 | case AML_FIELD_OP: |
407 | arg = acpi_ps_get_arg(op, 2); | 426 | arg = acpi_ps_get_arg(op, 2); |
@@ -433,10 +452,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
433 | status = acpi_ns_lookup(walk_state->scope_info, | 452 | status = acpi_ns_lookup(walk_state->scope_info, |
434 | (char *)&arg->named.name, | 453 | (char *)&arg->named.name, |
435 | type, ACPI_IMODE_LOAD_PASS1, | 454 | type, ACPI_IMODE_LOAD_PASS1, |
436 | ACPI_NS_NO_UPSEARCH | | 455 | flags, walk_state, &node); |
437 | ACPI_NS_DONT_OPEN_SCOPE | | ||
438 | ACPI_NS_ERROR_IF_FOUND, | ||
439 | walk_state, &node); | ||
440 | if (ACPI_FAILURE(status)) { | 456 | if (ACPI_FAILURE(status)) { |
441 | ACPI_ERROR_NAMESPACE((char *)&arg->named.name, | 457 | ACPI_ERROR_NAMESPACE((char *)&arg->named.name, |
442 | status); | 458 | status); |
@@ -466,7 +482,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
466 | * | 482 | * |
467 | * PARAMETERS: Op - Op containing the Field definition and args | 483 | * PARAMETERS: Op - Op containing the Field definition and args |
468 | * region_node - Object for the containing Operation Region | 484 | * region_node - Object for the containing Operation Region |
469 | * ` walk_state - Current method state | 485 | * walk_state - Current method state |
470 | * | 486 | * |
471 | * RETURN: Status | 487 | * RETURN: Status |
472 | * | 488 | * |
@@ -513,36 +529,13 @@ acpi_ds_create_bank_field(union acpi_parse_object *op, | |||
513 | return_ACPI_STATUS(status); | 529 | return_ACPI_STATUS(status); |
514 | } | 530 | } |
515 | 531 | ||
516 | /* Third arg is the bank_value */ | 532 | /* |
517 | 533 | * Third arg is the bank_value | |
518 | /* TBD: This arg is a term_arg, not a constant, and must be evaluated */ | 534 | * This arg is a term_arg, not a constant |
519 | 535 | * It will be evaluated later, by acpi_ds_eval_bank_field_operands | |
536 | */ | ||
520 | arg = arg->common.next; | 537 | arg = arg->common.next; |
521 | 538 | ||
522 | /* Currently, only the following constants are supported */ | ||
523 | |||
524 | switch (arg->common.aml_opcode) { | ||
525 | case AML_ZERO_OP: | ||
526 | info.bank_value = 0; | ||
527 | break; | ||
528 | |||
529 | case AML_ONE_OP: | ||
530 | info.bank_value = 1; | ||
531 | break; | ||
532 | |||
533 | case AML_BYTE_OP: | ||
534 | case AML_WORD_OP: | ||
535 | case AML_DWORD_OP: | ||
536 | case AML_QWORD_OP: | ||
537 | info.bank_value = (u32) arg->common.value.integer; | ||
538 | break; | ||
539 | |||
540 | default: | ||
541 | info.bank_value = 0; | ||
542 | ACPI_ERROR((AE_INFO, | ||
543 | "Non-constant BankValue for BankField is not implemented")); | ||
544 | } | ||
545 | |||
546 | /* Fourth arg is the field flags */ | 539 | /* Fourth arg is the field flags */ |
547 | 540 | ||
548 | arg = arg->common.next; | 541 | arg = arg->common.next; |
@@ -553,8 +546,17 @@ acpi_ds_create_bank_field(union acpi_parse_object *op, | |||
553 | info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD; | 546 | info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD; |
554 | info.region_node = region_node; | 547 | info.region_node = region_node; |
555 | 548 | ||
556 | status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); | 549 | /* |
550 | * Use Info.data_register_node to store bank_field Op | ||
551 | * It's safe because data_register_node will never be used when create bank field | ||
552 | * We store aml_start and aml_length in the bank_field Op for late evaluation | ||
553 | * Used in acpi_ex_prep_field_value(Info) | ||
554 | * | ||
555 | * TBD: Or, should we add a field in struct acpi_create_field_info, like "void *ParentOp"? | ||
556 | */ | ||
557 | info.data_register_node = (struct acpi_namespace_node *)op; | ||
557 | 558 | ||
559 | status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); | ||
558 | return_ACPI_STATUS(status); | 560 | return_ACPI_STATUS(status); |
559 | } | 561 | } |
560 | 562 | ||
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index a3f29798d1d1..35a7efdb5ad9 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c | |||
@@ -220,6 +220,50 @@ acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc) | |||
220 | 220 | ||
221 | /******************************************************************************* | 221 | /******************************************************************************* |
222 | * | 222 | * |
223 | * FUNCTION: acpi_ds_get_bank_field_arguments | ||
224 | * | ||
225 | * PARAMETERS: obj_desc - A valid bank_field object | ||
226 | * | ||
227 | * RETURN: Status. | ||
228 | * | ||
229 | * DESCRIPTION: Get bank_field bank_value. This implements the late | ||
230 | * evaluation of these field attributes. | ||
231 | * | ||
232 | ******************************************************************************/ | ||
233 | |||
234 | acpi_status | ||
235 | acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc) | ||
236 | { | ||
237 | union acpi_operand_object *extra_desc; | ||
238 | struct acpi_namespace_node *node; | ||
239 | acpi_status status; | ||
240 | |||
241 | ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc); | ||
242 | |||
243 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
244 | return_ACPI_STATUS(AE_OK); | ||
245 | } | ||
246 | |||
247 | /* Get the AML pointer (method object) and bank_field node */ | ||
248 | |||
249 | extra_desc = acpi_ns_get_secondary_object(obj_desc); | ||
250 | node = obj_desc->bank_field.node; | ||
251 | |||
252 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname | ||
253 | (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL)); | ||
254 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n", | ||
255 | acpi_ut_get_node_name(node))); | ||
256 | |||
257 | /* Execute the AML code for the term_arg arguments */ | ||
258 | |||
259 | status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), | ||
260 | extra_desc->extra.aml_length, | ||
261 | extra_desc->extra.aml_start); | ||
262 | return_ACPI_STATUS(status); | ||
263 | } | ||
264 | |||
265 | /******************************************************************************* | ||
266 | * | ||
223 | * FUNCTION: acpi_ds_get_buffer_arguments | 267 | * FUNCTION: acpi_ds_get_buffer_arguments |
224 | * | 268 | * |
225 | * PARAMETERS: obj_desc - A valid Buffer object | 269 | * PARAMETERS: obj_desc - A valid Buffer object |
@@ -987,6 +1031,106 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, | |||
987 | 1031 | ||
988 | /******************************************************************************* | 1032 | /******************************************************************************* |
989 | * | 1033 | * |
1034 | * FUNCTION: acpi_ds_eval_bank_field_operands | ||
1035 | * | ||
1036 | * PARAMETERS: walk_state - Current walk | ||
1037 | * Op - A valid bank_field Op object | ||
1038 | * | ||
1039 | * RETURN: Status | ||
1040 | * | ||
1041 | * DESCRIPTION: Get bank_field bank_value | ||
1042 | * Called from acpi_ds_exec_end_op during bank_field parse tree walk | ||
1043 | * | ||
1044 | ******************************************************************************/ | ||
1045 | |||
1046 | acpi_status | ||
1047 | acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state, | ||
1048 | union acpi_parse_object *op) | ||
1049 | { | ||
1050 | acpi_status status; | ||
1051 | union acpi_operand_object *obj_desc; | ||
1052 | union acpi_operand_object *operand_desc; | ||
1053 | struct acpi_namespace_node *node; | ||
1054 | union acpi_parse_object *next_op; | ||
1055 | union acpi_parse_object *arg; | ||
1056 | |||
1057 | ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op); | ||
1058 | |||
1059 | /* | ||
1060 | * This is where we evaluate the bank_value field of the | ||
1061 | * bank_field declaration | ||
1062 | */ | ||
1063 | |||
1064 | /* next_op points to the op that holds the Region */ | ||
1065 | |||
1066 | next_op = op->common.value.arg; | ||
1067 | |||
1068 | /* next_op points to the op that holds the Bank Register */ | ||
1069 | |||
1070 | next_op = next_op->common.next; | ||
1071 | |||
1072 | /* next_op points to the op that holds the Bank Value */ | ||
1073 | |||
1074 | next_op = next_op->common.next; | ||
1075 | |||
1076 | /* | ||
1077 | * Set proper index into operand stack for acpi_ds_obj_stack_push | ||
1078 | * invoked inside acpi_ds_create_operand. | ||
1079 | * | ||
1080 | * We use walk_state->Operands[0] to store the evaluated bank_value | ||
1081 | */ | ||
1082 | walk_state->operand_index = 0; | ||
1083 | |||
1084 | status = acpi_ds_create_operand(walk_state, next_op, 0); | ||
1085 | if (ACPI_FAILURE(status)) { | ||
1086 | return_ACPI_STATUS(status); | ||
1087 | } | ||
1088 | |||
1089 | status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state); | ||
1090 | if (ACPI_FAILURE(status)) { | ||
1091 | return_ACPI_STATUS(status); | ||
1092 | } | ||
1093 | |||
1094 | ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, | ||
1095 | acpi_ps_get_opcode_name(op->common.aml_opcode), | ||
1096 | 1, "after AcpiExResolveOperands"); | ||
1097 | |||
1098 | /* | ||
1099 | * Get the bank_value operand and save it | ||
1100 | * (at Top of stack) | ||
1101 | */ | ||
1102 | operand_desc = walk_state->operands[0]; | ||
1103 | |||
1104 | /* Arg points to the start Bank Field */ | ||
1105 | |||
1106 | arg = acpi_ps_get_arg(op, 4); | ||
1107 | while (arg) { | ||
1108 | |||
1109 | /* Ignore OFFSET and ACCESSAS terms here */ | ||
1110 | |||
1111 | if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { | ||
1112 | node = arg->common.node; | ||
1113 | |||
1114 | obj_desc = acpi_ns_get_attached_object(node); | ||
1115 | if (!obj_desc) { | ||
1116 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
1117 | } | ||
1118 | |||
1119 | obj_desc->bank_field.value = | ||
1120 | (u32) operand_desc->integer.value; | ||
1121 | } | ||
1122 | |||
1123 | /* Move to next field in the list */ | ||
1124 | |||
1125 | arg = arg->common.next; | ||
1126 | } | ||
1127 | |||
1128 | acpi_ut_remove_reference(operand_desc); | ||
1129 | return_ACPI_STATUS(status); | ||
1130 | } | ||
1131 | |||
1132 | /******************************************************************************* | ||
1133 | * | ||
990 | * FUNCTION: acpi_ds_exec_begin_control_op | 1134 | * FUNCTION: acpi_ds_exec_begin_control_op |
991 | * | 1135 | * |
992 | * PARAMETERS: walk_list - The list that owns the walk stack | 1136 | * PARAMETERS: walk_list - The list that owns the walk stack |
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index 97d01dcdc972..f6c28d7b46c5 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.c | |||
@@ -278,7 +278,9 @@ acpi_ds_is_result_used(union acpi_parse_object * op, | |||
278 | AML_VAR_PACKAGE_OP) | 278 | AML_VAR_PACKAGE_OP) |
279 | || (op->common.parent->common.aml_opcode == AML_BUFFER_OP) | 279 | || (op->common.parent->common.aml_opcode == AML_BUFFER_OP) |
280 | || (op->common.parent->common.aml_opcode == | 280 | || (op->common.parent->common.aml_opcode == |
281 | AML_INT_EVAL_SUBTREE_OP)) { | 281 | AML_INT_EVAL_SUBTREE_OP) |
282 | || (op->common.parent->common.aml_opcode == | ||
283 | AML_BANK_FIELD_OP)) { | ||
282 | /* | 284 | /* |
283 | * These opcodes allow term_arg(s) as operands and therefore | 285 | * These opcodes allow term_arg(s) as operands and therefore |
284 | * the operands can be method calls. The result is used. | 286 | * the operands can be method calls. The result is used. |
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index 8ba4bb36af9f..bfe4450fa588 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c | |||
@@ -652,6 +652,17 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
652 | if (ACPI_FAILURE(status)) { | 652 | if (ACPI_FAILURE(status)) { |
653 | break; | 653 | break; |
654 | } | 654 | } |
655 | } else if (op->common.aml_opcode == AML_BANK_FIELD_OP) { | ||
656 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
657 | "Executing BankField Op=%p\n", | ||
658 | op)); | ||
659 | |||
660 | status = | ||
661 | acpi_ds_eval_bank_field_operands(walk_state, | ||
662 | op); | ||
663 | if (ACPI_FAILURE(status)) { | ||
664 | break; | ||
665 | } | ||
655 | } | 666 | } |
656 | break; | 667 | break; |
657 | 668 | ||
diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c index efe5d4b461a4..6eb45bf355f1 100644 --- a/drivers/acpi/executer/exprep.c +++ b/drivers/acpi/executer/exprep.c | |||
@@ -412,6 +412,7 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc, | |||
412 | acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) | 412 | acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) |
413 | { | 413 | { |
414 | union acpi_operand_object *obj_desc; | 414 | union acpi_operand_object *obj_desc; |
415 | union acpi_operand_object *second_desc = NULL; | ||
415 | u32 type; | 416 | u32 type; |
416 | acpi_status status; | 417 | acpi_status status; |
417 | 418 | ||
@@ -494,6 +495,20 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) | |||
494 | obj_desc->field.access_byte_width, | 495 | obj_desc->field.access_byte_width, |
495 | obj_desc->bank_field.region_obj, | 496 | obj_desc->bank_field.region_obj, |
496 | obj_desc->bank_field.bank_obj)); | 497 | obj_desc->bank_field.bank_obj)); |
498 | |||
499 | /* | ||
500 | * Remember location in AML stream of the field unit | ||
501 | * opcode and operands -- since the bank_value | ||
502 | * operands must be evaluated. | ||
503 | */ | ||
504 | second_desc = obj_desc->common.next_object; | ||
505 | second_desc->extra.aml_start = | ||
506 | ((union acpi_parse_object *)(info->data_register_node))-> | ||
507 | named.data; | ||
508 | second_desc->extra.aml_length = | ||
509 | ((union acpi_parse_object *)(info->data_register_node))-> | ||
510 | named.length; | ||
511 | |||
497 | break; | 512 | break; |
498 | 513 | ||
499 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | 514 | case ACPI_TYPE_LOCAL_INDEX_FIELD: |
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c index 33db2241044e..72b32454ce3c 100644 --- a/drivers/acpi/namespace/nsinit.c +++ b/drivers/acpi/namespace/nsinit.c | |||
@@ -244,6 +244,10 @@ acpi_ns_init_one_object(acpi_handle obj_handle, | |||
244 | info->field_count++; | 244 | info->field_count++; |
245 | break; | 245 | break; |
246 | 246 | ||
247 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
248 | info->field_count++; | ||
249 | break; | ||
250 | |||
247 | case ACPI_TYPE_BUFFER: | 251 | case ACPI_TYPE_BUFFER: |
248 | info->buffer_count++; | 252 | info->buffer_count++; |
249 | break; | 253 | break; |
@@ -287,6 +291,12 @@ acpi_ns_init_one_object(acpi_handle obj_handle, | |||
287 | status = acpi_ds_get_buffer_field_arguments(obj_desc); | 291 | status = acpi_ds_get_buffer_field_arguments(obj_desc); |
288 | break; | 292 | break; |
289 | 293 | ||
294 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
295 | |||
296 | info->field_init++; | ||
297 | status = acpi_ds_get_bank_field_arguments(obj_desc); | ||
298 | break; | ||
299 | |||
290 | case ACPI_TYPE_BUFFER: | 300 | case ACPI_TYPE_BUFFER: |
291 | 301 | ||
292 | info->buffer_init++; | 302 | info->buffer_init++; |
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c index a079975f671f..a7c768860648 100644 --- a/drivers/acpi/parser/psloop.c +++ b/drivers/acpi/parser/psloop.c | |||
@@ -325,6 +325,15 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state, | |||
325 | op->named.length = 0; | 325 | op->named.length = 0; |
326 | } | 326 | } |
327 | 327 | ||
328 | if (walk_state->opcode == AML_BANK_FIELD_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 | |||
328 | parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state)); | 337 | parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state)); |
329 | acpi_ps_append_arg(parent_scope, op); | 338 | acpi_ps_append_arg(parent_scope, op); |
330 | 339 | ||
@@ -1040,6 +1049,16 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) | |||
1040 | (u32) (parser_state->aml - op->named.data); | 1049 | (u32) (parser_state->aml - op->named.data); |
1041 | } | 1050 | } |
1042 | 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 | |||
1043 | /* This op complete, notify the dispatcher */ | 1062 | /* This op complete, notify the dispatcher */ |
1044 | 1063 | ||
1045 | if (walk_state->ascending_callback != NULL) { | 1064 | if (walk_state->ascending_callback != NULL) { |
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c index b273a0a127e6..18ed59dd2a6e 100644 --- a/drivers/acpi/parser/psopcode.c +++ b/drivers/acpi/parser/psopcode.c | |||
@@ -520,9 +520,10 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = { | |||
520 | AML_TYPE_NAMED_FIELD, | 520 | AML_TYPE_NAMED_FIELD, |
521 | AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), | 521 | AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), |
522 | /* 5F */ ACPI_OP("BankField", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP, | 522 | /* 5F */ ACPI_OP("BankField", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP, |
523 | ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, | 523 | ACPI_TYPE_LOCAL_BANK_FIELD, AML_CLASS_NAMED_OBJECT, |
524 | AML_TYPE_NAMED_FIELD, | 524 | AML_TYPE_NAMED_FIELD, |
525 | AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), | 525 | AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD | |
526 | AML_DEFER), | ||
526 | 527 | ||
527 | /* Internal opcodes that map to invalid AML opcodes */ | 528 | /* Internal opcodes that map to invalid AML opcodes */ |
528 | 529 | ||
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 1442e55c40d1..a8995ca52ee7 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c | |||
@@ -205,6 +205,8 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, | |||
205 | || (op->common.parent->common.aml_opcode == | 205 | || (op->common.parent->common.aml_opcode == |
206 | AML_PACKAGE_OP) | 206 | AML_PACKAGE_OP) |
207 | || (op->common.parent->common.aml_opcode == | 207 | || (op->common.parent->common.aml_opcode == |
208 | AML_BANK_FIELD_OP) | ||
209 | || (op->common.parent->common.aml_opcode == | ||
208 | AML_VAR_PACKAGE_OP)) { | 210 | AML_VAR_PACKAGE_OP)) { |
209 | replacement_op = | 211 | replacement_op = |
210 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); | 212 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); |
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c index 6a763cd85f8c..f5b2f6a358b5 100644 --- a/drivers/acpi/utilities/utdelete.c +++ b/drivers/acpi/utilities/utdelete.c | |||
@@ -252,6 +252,17 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
252 | } | 252 | } |
253 | break; | 253 | break; |
254 | 254 | ||
255 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
256 | |||
257 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
258 | "***** Bank Field %p\n", object)); | ||
259 | |||
260 | second_desc = acpi_ns_get_secondary_object(object); | ||
261 | if (second_desc) { | ||
262 | acpi_ut_delete_object_desc(second_desc); | ||
263 | } | ||
264 | break; | ||
265 | |||
255 | default: | 266 | default: |
256 | break; | 267 | break; |
257 | } | 268 | } |
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index e08b3fa6639f..1eccd3db876f 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c | |||
@@ -107,6 +107,7 @@ union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name, | |||
107 | switch (type) { | 107 | switch (type) { |
108 | case ACPI_TYPE_REGION: | 108 | case ACPI_TYPE_REGION: |
109 | case ACPI_TYPE_BUFFER_FIELD: | 109 | case ACPI_TYPE_BUFFER_FIELD: |
110 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
110 | 111 | ||
111 | /* These types require a secondary object */ | 112 | /* These types require a secondary object */ |
112 | 113 | ||
diff --git a/include/acpi/acdispat.h b/include/acpi/acdispat.h index d8dabe893973..a5b97f0f0133 100644 --- a/include/acpi/acdispat.h +++ b/include/acpi/acdispat.h | |||
@@ -53,6 +53,9 @@ | |||
53 | acpi_status | 53 | acpi_status |
54 | acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc); | 54 | acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc); |
55 | 55 | ||
56 | acpi_status | ||
57 | acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc); | ||
58 | |||
56 | acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *rgn_desc); | 59 | acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *rgn_desc); |
57 | 60 | ||
58 | acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc); | 61 | acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc); |
@@ -76,6 +79,10 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, | |||
76 | union acpi_parse_object *op, | 79 | union acpi_parse_object *op, |
77 | union acpi_operand_object *obj_desc); | 80 | union acpi_operand_object *obj_desc); |
78 | 81 | ||
82 | acpi_status | ||
83 | acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state, | ||
84 | union acpi_parse_object *op); | ||
85 | |||
79 | acpi_status acpi_ds_initialize_region(acpi_handle obj_handle); | 86 | acpi_status acpi_ds_initialize_region(acpi_handle obj_handle); |
80 | 87 | ||
81 | /* | 88 | /* |