diff options
Diffstat (limited to 'drivers/acpi/dispatcher')
-rw-r--r-- | drivers/acpi/dispatcher/dsfield.c | 173 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dsinit.c | 2 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dsmethod.c | 57 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dsmthdat.c | 2 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dsobject.c | 101 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dsopcode.c | 260 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dsutils.c | 167 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dswexec.c | 78 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dswload.c | 37 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dswscope.c | 2 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dswstate.c | 517 |
11 files changed, 783 insertions, 613 deletions
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c index f049639bac35..c78078315be9 100644 --- a/drivers/acpi/dispatcher/dsfield.c +++ b/drivers/acpi/dispatcher/dsfield.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 |
@@ -89,12 +89,16 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
89 | 89 | ||
90 | ACPI_FUNCTION_TRACE(ds_create_buffer_field); | 90 | ACPI_FUNCTION_TRACE(ds_create_buffer_field); |
91 | 91 | ||
92 | /* Get the name_string argument */ | 92 | /* |
93 | 93 | * Get the name_string argument (name of the new buffer_field) | |
94 | */ | ||
94 | if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { | 95 | if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { |
96 | |||
97 | /* For create_field, name is the 4th argument */ | ||
98 | |||
95 | arg = acpi_ps_get_arg(op, 3); | 99 | arg = acpi_ps_get_arg(op, 3); |
96 | } else { | 100 | } else { |
97 | /* Create Bit/Byte/Word/Dword field */ | 101 | /* For all other create_xXXField operators, name is the 3rd argument */ |
98 | 102 | ||
99 | arg = acpi_ps_get_arg(op, 2); | 103 | arg = acpi_ps_get_arg(op, 2); |
100 | } | 104 | } |
@@ -107,26 +111,30 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
107 | node = walk_state->deferred_node; | 111 | node = walk_state->deferred_node; |
108 | status = AE_OK; | 112 | status = AE_OK; |
109 | } else { | 113 | } else { |
110 | /* | 114 | /* Execute flag should always be set when this function is entered */ |
111 | * During the load phase, we want to enter the name of the field into | 115 | |
112 | * the namespace. During the execute phase (when we evaluate the size | 116 | if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) { |
113 | * operand), we want to lookup the name | 117 | return_ACPI_STATUS(AE_AML_INTERNAL); |
114 | */ | ||
115 | if (walk_state->parse_flags & ACPI_PARSE_EXECUTE) { | ||
116 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE; | ||
117 | } else { | ||
118 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | | ||
119 | ACPI_NS_ERROR_IF_FOUND; | ||
120 | } | 118 | } |
121 | 119 | ||
122 | /* | 120 | /* Creating new namespace node, should not already exist */ |
123 | * Enter the name_string into the namespace | 121 | |
124 | */ | 122 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | |
123 | ACPI_NS_ERROR_IF_FOUND; | ||
124 | |||
125 | /* Mark node temporary if we are executing a method */ | ||
126 | |||
127 | if (walk_state->method_node) { | ||
128 | flags |= ACPI_NS_TEMPORARY; | ||
129 | } | ||
130 | |||
131 | /* Enter the name_string into the namespace */ | ||
132 | |||
125 | status = | 133 | status = |
126 | acpi_ns_lookup(walk_state->scope_info, | 134 | acpi_ns_lookup(walk_state->scope_info, |
127 | arg->common.value.string, ACPI_TYPE_ANY, | 135 | arg->common.value.string, ACPI_TYPE_ANY, |
128 | ACPI_IMODE_LOAD_PASS1, flags, walk_state, | 136 | ACPI_IMODE_LOAD_PASS1, flags, walk_state, |
129 | &(node)); | 137 | &node); |
130 | if (ACPI_FAILURE(status)) { | 138 | if (ACPI_FAILURE(status)) { |
131 | ACPI_ERROR_NAMESPACE(arg->common.value.string, status); | 139 | ACPI_ERROR_NAMESPACE(arg->common.value.string, status); |
132 | return_ACPI_STATUS(status); | 140 | return_ACPI_STATUS(status); |
@@ -136,13 +144,13 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
136 | /* | 144 | /* |
137 | * We could put the returned object (Node) on the object stack for later, | 145 | * We could put the returned object (Node) on the object stack for later, |
138 | * but for now, we will put it in the "op" object that the parser uses, | 146 | * but for now, we will put it in the "op" object that the parser uses, |
139 | * so we can get it again at the end of this scope | 147 | * so we can get it again at the end of this scope. |
140 | */ | 148 | */ |
141 | op->common.node = node; | 149 | op->common.node = node; |
142 | 150 | ||
143 | /* | 151 | /* |
144 | * If there is no object attached to the node, this node was just created | 152 | * If there is no object attached to the node, this node was just created |
145 | * and we need to create the field object. Otherwise, this was a lookup | 153 | * and we need to create the field object. Otherwise, this was a lookup |
146 | * of an existing node and we don't want to create the field object again. | 154 | * of an existing node and we don't want to create the field object again. |
147 | */ | 155 | */ |
148 | obj_desc = acpi_ns_get_attached_object(node); | 156 | obj_desc = acpi_ns_get_attached_object(node); |
@@ -164,9 +172,8 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
164 | } | 172 | } |
165 | 173 | ||
166 | /* | 174 | /* |
167 | * Remember location in AML stream of the field unit | 175 | * Remember location in AML stream of the field unit opcode and operands -- |
168 | * opcode and operands -- since the buffer and index | 176 | * since the buffer and index operands must be evaluated. |
169 | * operands must be evaluated. | ||
170 | */ | 177 | */ |
171 | second_desc = obj_desc->common.next_object; | 178 | second_desc = obj_desc->common.next_object; |
172 | second_desc->extra.aml_start = op->named.data; | 179 | second_desc->extra.aml_start = op->named.data; |
@@ -261,7 +268,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, | |||
261 | 268 | ||
262 | case AML_INT_NAMEDFIELD_OP: | 269 | case AML_INT_NAMEDFIELD_OP: |
263 | 270 | ||
264 | /* Lookup the name */ | 271 | /* Lookup the name, it should already exist */ |
265 | 272 | ||
266 | status = acpi_ns_lookup(walk_state->scope_info, | 273 | status = acpi_ns_lookup(walk_state->scope_info, |
267 | (char *)&arg->named.name, | 274 | (char *)&arg->named.name, |
@@ -272,20 +279,23 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, | |||
272 | if (ACPI_FAILURE(status)) { | 279 | if (ACPI_FAILURE(status)) { |
273 | ACPI_ERROR_NAMESPACE((char *)&arg->named.name, | 280 | ACPI_ERROR_NAMESPACE((char *)&arg->named.name, |
274 | status); | 281 | status); |
275 | if (status != AE_ALREADY_EXISTS) { | 282 | return_ACPI_STATUS(status); |
276 | return_ACPI_STATUS(status); | ||
277 | } | ||
278 | |||
279 | /* Already exists, ignore error */ | ||
280 | } else { | 283 | } else { |
281 | arg->common.node = info->field_node; | 284 | arg->common.node = info->field_node; |
282 | info->field_bit_length = arg->common.value.size; | 285 | info->field_bit_length = arg->common.value.size; |
283 | 286 | ||
284 | /* Create and initialize an object for the new Field Node */ | 287 | /* |
285 | 288 | * If there is no object attached to the node, this node was | |
286 | status = acpi_ex_prep_field_value(info); | 289 | * just created and we need to create the field object. |
287 | if (ACPI_FAILURE(status)) { | 290 | * Otherwise, this was a lookup of an existing node and we |
288 | return_ACPI_STATUS(status); | 291 | * don't want to create the field object again. |
292 | */ | ||
293 | if (!acpi_ns_get_attached_object | ||
294 | (info->field_node)) { | ||
295 | status = acpi_ex_prep_field_value(info); | ||
296 | if (ACPI_FAILURE(status)) { | ||
297 | return_ACPI_STATUS(status); | ||
298 | } | ||
289 | } | 299 | } |
290 | } | 300 | } |
291 | 301 | ||
@@ -399,9 +409,27 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
399 | union acpi_parse_object *arg = NULL; | 409 | union acpi_parse_object *arg = NULL; |
400 | struct acpi_namespace_node *node; | 410 | struct acpi_namespace_node *node; |
401 | u8 type = 0; | 411 | u8 type = 0; |
412 | u32 flags; | ||
402 | 413 | ||
403 | ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op); | 414 | ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op); |
404 | 415 | ||
416 | /* Execute flag should always be set when this function is entered */ | ||
417 | |||
418 | if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) { | ||
419 | if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) { | ||
420 | |||
421 | /* bank_field Op is deferred, just return OK */ | ||
422 | |||
423 | return_ACPI_STATUS(AE_OK); | ||
424 | } | ||
425 | |||
426 | return_ACPI_STATUS(AE_AML_INTERNAL); | ||
427 | } | ||
428 | |||
429 | /* | ||
430 | * Get the field_list argument for this opcode. This is the start of the | ||
431 | * list of field elements. | ||
432 | */ | ||
405 | switch (walk_state->opcode) { | 433 | switch (walk_state->opcode) { |
406 | case AML_FIELD_OP: | 434 | case AML_FIELD_OP: |
407 | arg = acpi_ps_get_arg(op, 2); | 435 | arg = acpi_ps_get_arg(op, 2); |
@@ -422,20 +450,33 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
422 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 450 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
423 | } | 451 | } |
424 | 452 | ||
453 | if (!arg) { | ||
454 | return_ACPI_STATUS(AE_AML_NO_OPERAND); | ||
455 | } | ||
456 | |||
457 | /* Creating new namespace node(s), should not already exist */ | ||
458 | |||
459 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | | ||
460 | ACPI_NS_ERROR_IF_FOUND; | ||
461 | |||
462 | /* Mark node(s) temporary if we are executing a method */ | ||
463 | |||
464 | if (walk_state->method_node) { | ||
465 | flags |= ACPI_NS_TEMPORARY; | ||
466 | } | ||
467 | |||
425 | /* | 468 | /* |
426 | * Walk the list of entries in the field_list | 469 | * Walk the list of entries in the field_list |
427 | */ | 470 | */ |
428 | while (arg) { | 471 | while (arg) { |
429 | 472 | /* | |
430 | /* Ignore OFFSET and ACCESSAS terms here */ | 473 | * Ignore OFFSET and ACCESSAS terms here; we are only interested in the |
431 | 474 | * field names in order to enter them into the namespace. | |
475 | */ | ||
432 | if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { | 476 | if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { |
433 | status = acpi_ns_lookup(walk_state->scope_info, | 477 | status = acpi_ns_lookup(walk_state->scope_info, |
434 | (char *)&arg->named.name, | 478 | (char *)&arg->named.name, type, |
435 | type, ACPI_IMODE_LOAD_PASS1, | 479 | ACPI_IMODE_LOAD_PASS1, flags, |
436 | ACPI_NS_NO_UPSEARCH | | ||
437 | ACPI_NS_DONT_OPEN_SCOPE | | ||
438 | ACPI_NS_ERROR_IF_FOUND, | ||
439 | walk_state, &node); | 480 | walk_state, &node); |
440 | if (ACPI_FAILURE(status)) { | 481 | if (ACPI_FAILURE(status)) { |
441 | ACPI_ERROR_NAMESPACE((char *)&arg->named.name, | 482 | ACPI_ERROR_NAMESPACE((char *)&arg->named.name, |
@@ -452,7 +493,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
452 | arg->common.node = node; | 493 | arg->common.node = node; |
453 | } | 494 | } |
454 | 495 | ||
455 | /* Move to next field in the list */ | 496 | /* Get the next field element in the list */ |
456 | 497 | ||
457 | arg = arg->common.next; | 498 | arg = arg->common.next; |
458 | } | 499 | } |
@@ -466,7 +507,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
466 | * | 507 | * |
467 | * PARAMETERS: Op - Op containing the Field definition and args | 508 | * PARAMETERS: Op - Op containing the Field definition and args |
468 | * region_node - Object for the containing Operation Region | 509 | * region_node - Object for the containing Operation Region |
469 | * ` walk_state - Current method state | 510 | * walk_state - Current method state |
470 | * | 511 | * |
471 | * RETURN: Status | 512 | * RETURN: Status |
472 | * | 513 | * |
@@ -513,36 +554,13 @@ acpi_ds_create_bank_field(union acpi_parse_object *op, | |||
513 | return_ACPI_STATUS(status); | 554 | return_ACPI_STATUS(status); |
514 | } | 555 | } |
515 | 556 | ||
516 | /* Third arg is the bank_value */ | 557 | /* |
517 | 558 | * Third arg is the bank_value | |
518 | /* TBD: This arg is a term_arg, not a constant, and must be evaluated */ | 559 | * This arg is a term_arg, not a constant |
519 | 560 | * It will be evaluated later, by acpi_ds_eval_bank_field_operands | |
561 | */ | ||
520 | arg = arg->common.next; | 562 | arg = arg->common.next; |
521 | 563 | ||
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 */ | 564 | /* Fourth arg is the field flags */ |
547 | 565 | ||
548 | arg = arg->common.next; | 566 | arg = arg->common.next; |
@@ -553,8 +571,17 @@ acpi_ds_create_bank_field(union acpi_parse_object *op, | |||
553 | info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD; | 571 | info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD; |
554 | info.region_node = region_node; | 572 | info.region_node = region_node; |
555 | 573 | ||
556 | status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); | 574 | /* |
575 | * Use Info.data_register_node to store bank_field Op | ||
576 | * It's safe because data_register_node will never be used when create bank field | ||
577 | * We store aml_start and aml_length in the bank_field Op for late evaluation | ||
578 | * Used in acpi_ex_prep_field_value(Info) | ||
579 | * | ||
580 | * TBD: Or, should we add a field in struct acpi_create_field_info, like "void *ParentOp"? | ||
581 | */ | ||
582 | info.data_register_node = (struct acpi_namespace_node *)op; | ||
557 | 583 | ||
584 | status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); | ||
558 | return_ACPI_STATUS(status); | 585 | return_ACPI_STATUS(status); |
559 | } | 586 | } |
560 | 587 | ||
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c index af923c388520..610b1ee102b0 100644 --- a/drivers/acpi/dispatcher/dsinit.c +++ b/drivers/acpi/dispatcher/dsinit.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 |
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 1cbe61905824..e48a3ea03117 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.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 |
@@ -42,7 +42,6 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acparser.h> | ||
46 | #include <acpi/amlcode.h> | 45 | #include <acpi/amlcode.h> |
47 | #include <acpi/acdispat.h> | 46 | #include <acpi/acdispat.h> |
48 | #include <acpi/acinterp.h> | 47 | #include <acpi/acinterp.h> |
@@ -102,7 +101,7 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state) | |||
102 | walk_state->opcode, | 101 | walk_state->opcode, |
103 | walk_state->aml_offset, | 102 | walk_state->aml_offset, |
104 | NULL); | 103 | NULL); |
105 | (void)acpi_ex_enter_interpreter(); | 104 | acpi_ex_enter_interpreter(); |
106 | } | 105 | } |
107 | #ifdef ACPI_DISASSEMBLER | 106 | #ifdef ACPI_DISASSEMBLER |
108 | if (ACPI_FAILURE(status)) { | 107 | if (ACPI_FAILURE(status)) { |
@@ -232,9 +231,9 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, | |||
232 | * recursive call. | 231 | * recursive call. |
233 | */ | 232 | */ |
234 | if (!walk_state || | 233 | if (!walk_state || |
235 | !obj_desc->method.mutex->mutex.owner_thread || | 234 | !obj_desc->method.mutex->mutex.thread_id || |
236 | (walk_state->thread != | 235 | (walk_state->thread->thread_id != |
237 | obj_desc->method.mutex->mutex.owner_thread)) { | 236 | obj_desc->method.mutex->mutex.thread_id)) { |
238 | /* | 237 | /* |
239 | * Acquire the method mutex. This releases the interpreter if we | 238 | * Acquire the method mutex. This releases the interpreter if we |
240 | * block (and reacquires it before it returns) | 239 | * block (and reacquires it before it returns) |
@@ -254,8 +253,8 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, | |||
254 | original_sync_level = | 253 | original_sync_level = |
255 | walk_state->thread->current_sync_level; | 254 | walk_state->thread->current_sync_level; |
256 | 255 | ||
257 | obj_desc->method.mutex->mutex.owner_thread = | 256 | obj_desc->method.mutex->mutex.thread_id = |
258 | walk_state->thread; | 257 | walk_state->thread->thread_id; |
259 | walk_state->thread->current_sync_level = | 258 | walk_state->thread->current_sync_level = |
260 | obj_desc->method.sync_level; | 259 | obj_desc->method.sync_level; |
261 | } else { | 260 | } else { |
@@ -535,8 +534,6 @@ void | |||
535 | acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | 534 | acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, |
536 | struct acpi_walk_state *walk_state) | 535 | struct acpi_walk_state *walk_state) |
537 | { | 536 | { |
538 | struct acpi_namespace_node *method_node; | ||
539 | acpi_status status; | ||
540 | 537 | ||
541 | ACPI_FUNCTION_TRACE_PTR(ds_terminate_control_method, walk_state); | 538 | ACPI_FUNCTION_TRACE_PTR(ds_terminate_control_method, walk_state); |
542 | 539 | ||
@@ -551,34 +548,26 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
551 | /* Delete all arguments and locals */ | 548 | /* Delete all arguments and locals */ |
552 | 549 | ||
553 | acpi_ds_method_data_delete_all(walk_state); | 550 | acpi_ds_method_data_delete_all(walk_state); |
554 | } | ||
555 | 551 | ||
556 | /* | 552 | /* |
557 | * If method is serialized, release the mutex and restore the | 553 | * If method is serialized, release the mutex and restore the |
558 | * current sync level for this thread | 554 | * current sync level for this thread |
559 | */ | 555 | */ |
560 | if (method_desc->method.mutex) { | 556 | if (method_desc->method.mutex) { |
561 | 557 | ||
562 | /* Acquisition Depth handles recursive calls */ | 558 | /* Acquisition Depth handles recursive calls */ |
563 | 559 | ||
564 | method_desc->method.mutex->mutex.acquisition_depth--; | 560 | method_desc->method.mutex->mutex.acquisition_depth--; |
565 | if (!method_desc->method.mutex->mutex.acquisition_depth) { | 561 | if (!method_desc->method.mutex->mutex.acquisition_depth) { |
566 | walk_state->thread->current_sync_level = | 562 | walk_state->thread->current_sync_level = |
567 | method_desc->method.mutex->mutex. | 563 | method_desc->method.mutex->mutex. |
568 | original_sync_level; | 564 | original_sync_level; |
569 | 565 | ||
570 | acpi_os_release_mutex(method_desc->method.mutex->mutex. | 566 | acpi_os_release_mutex(method_desc->method. |
571 | os_mutex); | 567 | mutex->mutex.os_mutex); |
572 | method_desc->method.mutex->mutex.owner_thread = NULL; | 568 | method_desc->method.mutex->mutex.thread_id = 0; |
569 | } | ||
573 | } | 570 | } |
574 | } | ||
575 | |||
576 | if (walk_state) { | ||
577 | /* | ||
578 | * Delete any objects created by this method during execution. | ||
579 | * The method Node is stored in the walk state | ||
580 | */ | ||
581 | method_node = walk_state->method_node; | ||
582 | 571 | ||
583 | /* | 572 | /* |
584 | * Delete any namespace objects created anywhere within | 573 | * Delete any namespace objects created anywhere within |
@@ -620,7 +609,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
620 | */ | 609 | */ |
621 | if ((method_desc->method.method_flags & AML_METHOD_SERIALIZED) | 610 | if ((method_desc->method.method_flags & AML_METHOD_SERIALIZED) |
622 | && (!method_desc->method.mutex)) { | 611 | && (!method_desc->method.mutex)) { |
623 | status = acpi_ds_create_method_mutex(method_desc); | 612 | (void)acpi_ds_create_method_mutex(method_desc); |
624 | } | 613 | } |
625 | 614 | ||
626 | /* No more threads, we can free the owner_id */ | 615 | /* No more threads, we can free the owner_id */ |
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c index ba4626e06a5e..13c43eac35db 100644 --- a/drivers/acpi/dispatcher/dsmthdat.c +++ b/drivers/acpi/dispatcher/dsmthdat.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 |
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index 954ac8ce958a..1022e38994c2 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.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 |
@@ -157,7 +157,9 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, | |||
157 | * will remain as named references. This behavior is not described | 157 | * will remain as named references. This behavior is not described |
158 | * in the ACPI spec, but it appears to be an oversight. | 158 | * in the ACPI spec, but it appears to be an oversight. |
159 | */ | 159 | */ |
160 | obj_desc = (union acpi_operand_object *)op->common.node; | 160 | obj_desc = |
161 | ACPI_CAST_PTR(union acpi_operand_object, | ||
162 | op->common.node); | ||
161 | 163 | ||
162 | status = | 164 | status = |
163 | acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR | 165 | acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR |
@@ -172,7 +174,19 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, | |||
172 | switch (op->common.node->type) { | 174 | switch (op->common.node->type) { |
173 | /* | 175 | /* |
174 | * For these types, we need the actual node, not the subobject. | 176 | * For these types, we need the actual node, not the subobject. |
175 | * However, the subobject got an extra reference count above. | 177 | * However, the subobject did not get an extra reference count above. |
178 | * | ||
179 | * TBD: should ex_resolve_node_to_value be changed to fix this? | ||
180 | */ | ||
181 | case ACPI_TYPE_DEVICE: | ||
182 | case ACPI_TYPE_THERMAL: | ||
183 | |||
184 | acpi_ut_add_reference(op->common.node->object); | ||
185 | |||
186 | /*lint -fallthrough */ | ||
187 | /* | ||
188 | * For these types, we need the actual node, not the subobject. | ||
189 | * The subobject got an extra reference count in ex_resolve_node_to_value. | ||
176 | */ | 190 | */ |
177 | case ACPI_TYPE_MUTEX: | 191 | case ACPI_TYPE_MUTEX: |
178 | case ACPI_TYPE_METHOD: | 192 | case ACPI_TYPE_METHOD: |
@@ -180,25 +194,15 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, | |||
180 | case ACPI_TYPE_PROCESSOR: | 194 | case ACPI_TYPE_PROCESSOR: |
181 | case ACPI_TYPE_EVENT: | 195 | case ACPI_TYPE_EVENT: |
182 | case ACPI_TYPE_REGION: | 196 | case ACPI_TYPE_REGION: |
183 | case ACPI_TYPE_DEVICE: | ||
184 | case ACPI_TYPE_THERMAL: | ||
185 | 197 | ||
186 | obj_desc = | 198 | /* We will create a reference object for these types below */ |
187 | (union acpi_operand_object *)op->common. | ||
188 | node; | ||
189 | break; | 199 | break; |
190 | 200 | ||
191 | default: | 201 | default: |
192 | break; | 202 | /* |
193 | } | 203 | * All other types - the node was resolved to an actual |
194 | 204 | * object, we are done. | |
195 | /* | 205 | */ |
196 | * If above resolved to an operand object, we are done. Otherwise, | ||
197 | * we have a NS node, we must create the package entry as a named | ||
198 | * reference. | ||
199 | */ | ||
200 | if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != | ||
201 | ACPI_DESC_TYPE_NAMED) { | ||
202 | goto exit; | 206 | goto exit; |
203 | } | 207 | } |
204 | } | 208 | } |
@@ -223,7 +227,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, | |||
223 | 227 | ||
224 | exit: | 228 | exit: |
225 | *obj_desc_ptr = obj_desc; | 229 | *obj_desc_ptr = obj_desc; |
226 | return_ACPI_STATUS(AE_OK); | 230 | return_ACPI_STATUS(status); |
227 | } | 231 | } |
228 | 232 | ||
229 | /******************************************************************************* | 233 | /******************************************************************************* |
@@ -369,7 +373,9 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, | |||
369 | union acpi_parse_object *parent; | 373 | union acpi_parse_object *parent; |
370 | union acpi_operand_object *obj_desc = NULL; | 374 | union acpi_operand_object *obj_desc = NULL; |
371 | acpi_status status = AE_OK; | 375 | acpi_status status = AE_OK; |
372 | acpi_native_uint i; | 376 | unsigned i; |
377 | u16 index; | ||
378 | u16 reference_count; | ||
373 | 379 | ||
374 | ACPI_FUNCTION_TRACE(ds_build_internal_package_obj); | 380 | ACPI_FUNCTION_TRACE(ds_build_internal_package_obj); |
375 | 381 | ||
@@ -447,13 +453,60 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, | |||
447 | package. | 453 | package. |
448 | elements[i]); | 454 | elements[i]); |
449 | } | 455 | } |
456 | |||
457 | if (*obj_desc_ptr) { | ||
458 | |||
459 | /* Existing package, get existing reference count */ | ||
460 | |||
461 | reference_count = | ||
462 | (*obj_desc_ptr)->common.reference_count; | ||
463 | if (reference_count > 1) { | ||
464 | |||
465 | /* Make new element ref count match original ref count */ | ||
466 | |||
467 | for (index = 0; index < (reference_count - 1); | ||
468 | index++) { | ||
469 | acpi_ut_add_reference((obj_desc-> | ||
470 | package. | ||
471 | elements[i])); | ||
472 | } | ||
473 | } | ||
474 | } | ||
475 | |||
450 | arg = arg->common.next; | 476 | arg = arg->common.next; |
451 | } | 477 | } |
452 | 478 | ||
453 | if (!arg) { | 479 | /* Check for match between num_elements and actual length of package_list */ |
480 | |||
481 | if (arg) { | ||
482 | /* | ||
483 | * num_elements was exhausted, but there are remaining elements in the | ||
484 | * package_list. | ||
485 | * | ||
486 | * Note: technically, this is an error, from ACPI spec: "It is an error | ||
487 | * for NumElements to be less than the number of elements in the | ||
488 | * PackageList". However, for now, we just print an error message and | ||
489 | * no exception is returned. | ||
490 | */ | ||
491 | while (arg) { | ||
492 | |||
493 | /* Find out how many elements there really are */ | ||
494 | |||
495 | i++; | ||
496 | arg = arg->common.next; | ||
497 | } | ||
498 | |||
499 | ACPI_ERROR((AE_INFO, | ||
500 | "Package List length (%X) larger than NumElements count (%X), truncated\n", | ||
501 | i, element_count)); | ||
502 | } else if (i < element_count) { | ||
503 | /* | ||
504 | * Arg list (elements) was exhausted, but we did not reach num_elements count. | ||
505 | * Note: this is not an error, the package is padded out with NULLs. | ||
506 | */ | ||
454 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 507 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
455 | "Package List length larger than NumElements count (%X), truncated\n", | 508 | "Package List length (%X) smaller than NumElements count (%X), padded with null elements\n", |
456 | element_count)); | 509 | i, element_count)); |
457 | } | 510 | } |
458 | 511 | ||
459 | obj_desc->package.flags |= AOPOBJ_DATA_VALID; | 512 | obj_desc->package.flags |= AOPOBJ_DATA_VALID; |
@@ -721,6 +774,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, | |||
721 | /* Node was saved in Op */ | 774 | /* Node was saved in Op */ |
722 | 775 | ||
723 | obj_desc->reference.node = op->common.node; | 776 | obj_desc->reference.node = op->common.node; |
777 | obj_desc->reference.object = | ||
778 | op->common.node->object; | ||
724 | } | 779 | } |
725 | 780 | ||
726 | obj_desc->reference.opcode = opcode; | 781 | obj_desc->reference.opcode = opcode; |
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index f501e083aac7..a818e0ddb996 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -49,6 +49,7 @@ | |||
49 | #include <acpi/acinterp.h> | 49 | #include <acpi/acinterp.h> |
50 | #include <acpi/acnamesp.h> | 50 | #include <acpi/acnamesp.h> |
51 | #include <acpi/acevents.h> | 51 | #include <acpi/acevents.h> |
52 | #include <acpi/actables.h> | ||
52 | 53 | ||
53 | #define _COMPONENT ACPI_DISPATCHER | 54 | #define _COMPONENT ACPI_DISPATCHER |
54 | ACPI_MODULE_NAME("dsopcode") | 55 | ACPI_MODULE_NAME("dsopcode") |
@@ -219,6 +220,50 @@ acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc) | |||
219 | 220 | ||
220 | /******************************************************************************* | 221 | /******************************************************************************* |
221 | * | 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 | * | ||
222 | * FUNCTION: acpi_ds_get_buffer_arguments | 267 | * FUNCTION: acpi_ds_get_buffer_arguments |
223 | * | 268 | * |
224 | * PARAMETERS: obj_desc - A valid Buffer object | 269 | * PARAMETERS: obj_desc - A valid Buffer object |
@@ -770,7 +815,109 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, | |||
770 | 815 | ||
771 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", | 816 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", |
772 | obj_desc, | 817 | obj_desc, |
773 | ACPI_FORMAT_UINT64(obj_desc->region.address), | 818 | ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address), |
819 | obj_desc->region.length)); | ||
820 | |||
821 | /* Now the address and length are valid for this opregion */ | ||
822 | |||
823 | obj_desc->region.flags |= AOPOBJ_DATA_VALID; | ||
824 | |||
825 | return_ACPI_STATUS(status); | ||
826 | } | ||
827 | |||
828 | /******************************************************************************* | ||
829 | * | ||
830 | * FUNCTION: acpi_ds_eval_table_region_operands | ||
831 | * | ||
832 | * PARAMETERS: walk_state - Current walk | ||
833 | * Op - A valid region Op object | ||
834 | * | ||
835 | * RETURN: Status | ||
836 | * | ||
837 | * DESCRIPTION: Get region address and length | ||
838 | * Called from acpi_ds_exec_end_op during data_table_region parse tree walk | ||
839 | * | ||
840 | ******************************************************************************/ | ||
841 | |||
842 | acpi_status | ||
843 | acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, | ||
844 | union acpi_parse_object *op) | ||
845 | { | ||
846 | acpi_status status; | ||
847 | union acpi_operand_object *obj_desc; | ||
848 | union acpi_operand_object **operand; | ||
849 | struct acpi_namespace_node *node; | ||
850 | union acpi_parse_object *next_op; | ||
851 | acpi_native_uint table_index; | ||
852 | struct acpi_table_header *table; | ||
853 | |||
854 | ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op); | ||
855 | |||
856 | /* | ||
857 | * This is where we evaluate the signature_string and oem_iDString | ||
858 | * and oem_table_iDString of the data_table_region declaration | ||
859 | */ | ||
860 | node = op->common.node; | ||
861 | |||
862 | /* next_op points to signature_string op */ | ||
863 | |||
864 | next_op = op->common.value.arg; | ||
865 | |||
866 | /* | ||
867 | * Evaluate/create the signature_string and oem_iDString | ||
868 | * and oem_table_iDString operands | ||
869 | */ | ||
870 | status = acpi_ds_create_operands(walk_state, next_op); | ||
871 | if (ACPI_FAILURE(status)) { | ||
872 | return_ACPI_STATUS(status); | ||
873 | } | ||
874 | |||
875 | /* | ||
876 | * Resolve the signature_string and oem_iDString | ||
877 | * and oem_table_iDString operands | ||
878 | */ | ||
879 | status = acpi_ex_resolve_operands(op->common.aml_opcode, | ||
880 | ACPI_WALK_OPERANDS, walk_state); | ||
881 | if (ACPI_FAILURE(status)) { | ||
882 | return_ACPI_STATUS(status); | ||
883 | } | ||
884 | |||
885 | ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, | ||
886 | acpi_ps_get_opcode_name(op->common.aml_opcode), | ||
887 | 1, "after AcpiExResolveOperands"); | ||
888 | |||
889 | operand = &walk_state->operands[0]; | ||
890 | |||
891 | /* Find the ACPI table */ | ||
892 | |||
893 | status = acpi_tb_find_table(operand[0]->string.pointer, | ||
894 | operand[1]->string.pointer, | ||
895 | operand[2]->string.pointer, &table_index); | ||
896 | if (ACPI_FAILURE(status)) { | ||
897 | return_ACPI_STATUS(status); | ||
898 | } | ||
899 | |||
900 | acpi_ut_remove_reference(operand[0]); | ||
901 | acpi_ut_remove_reference(operand[1]); | ||
902 | acpi_ut_remove_reference(operand[2]); | ||
903 | |||
904 | status = acpi_get_table_by_index(table_index, &table); | ||
905 | if (ACPI_FAILURE(status)) { | ||
906 | return_ACPI_STATUS(status); | ||
907 | } | ||
908 | |||
909 | obj_desc = acpi_ns_get_attached_object(node); | ||
910 | if (!obj_desc) { | ||
911 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
912 | } | ||
913 | |||
914 | obj_desc->region.address = | ||
915 | (acpi_physical_address) ACPI_TO_INTEGER(table); | ||
916 | obj_desc->region.length = table->length; | ||
917 | |||
918 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", | ||
919 | obj_desc, | ||
920 | ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address), | ||
774 | obj_desc->region.length)); | 921 | obj_desc->region.length)); |
775 | 922 | ||
776 | /* Now the address and length are valid for this opregion */ | 923 | /* Now the address and length are valid for this opregion */ |
@@ -808,6 +955,12 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, | |||
808 | 955 | ||
809 | /* The first operand (for all of these data objects) is the length */ | 956 | /* The first operand (for all of these data objects) is the length */ |
810 | 957 | ||
958 | /* | ||
959 | * Set proper index into operand stack for acpi_ds_obj_stack_push | ||
960 | * invoked inside acpi_ds_create_operand. | ||
961 | */ | ||
962 | walk_state->operand_index = walk_state->num_operands; | ||
963 | |||
811 | status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1); | 964 | status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1); |
812 | if (ACPI_FAILURE(status)) { | 965 | if (ACPI_FAILURE(status)) { |
813 | return_ACPI_STATUS(status); | 966 | return_ACPI_STATUS(status); |
@@ -878,6 +1031,106 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, | |||
878 | 1031 | ||
879 | /******************************************************************************* | 1032 | /******************************************************************************* |
880 | * | 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 | * | ||
881 | * FUNCTION: acpi_ds_exec_begin_control_op | 1134 | * FUNCTION: acpi_ds_exec_begin_control_op |
882 | * | 1135 | * |
883 | * PARAMETERS: walk_list - The list that owns the walk stack | 1136 | * PARAMETERS: walk_list - The list that owns the walk stack |
@@ -1070,8 +1323,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, | |||
1070 | * is set to anything other than zero! | 1323 | * is set to anything other than zero! |
1071 | */ | 1324 | */ |
1072 | walk_state->return_desc = walk_state->operands[0]; | 1325 | walk_state->return_desc = walk_state->operands[0]; |
1073 | } else if ((walk_state->results) && | 1326 | } else if (walk_state->result_count) { |
1074 | (walk_state->results->results.num_results > 0)) { | ||
1075 | 1327 | ||
1076 | /* Since we have a real Return(), delete any implicit return */ | 1328 | /* Since we have a real Return(), delete any implicit return */ |
1077 | 1329 | ||
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index 71503c036f7c..b398982f0d8b 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.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 |
@@ -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. |
@@ -472,7 +474,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, | |||
472 | /* A valid name must be looked up in the namespace */ | 474 | /* A valid name must be looked up in the namespace */ |
473 | 475 | ||
474 | if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && | 476 | if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && |
475 | (arg->common.value.string)) { | 477 | (arg->common.value.string) && |
478 | !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) { | ||
476 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", | 479 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", |
477 | arg)); | 480 | arg)); |
478 | 481 | ||
@@ -595,7 +598,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, | |||
595 | } else { | 598 | } else { |
596 | /* Check for null name case */ | 599 | /* Check for null name case */ |
597 | 600 | ||
598 | if (arg->common.aml_opcode == AML_INT_NAMEPATH_OP) { | 601 | if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && |
602 | !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) { | ||
599 | /* | 603 | /* |
600 | * If the name is null, this means that this is an | 604 | * If the name is null, this means that this is an |
601 | * optional result parameter that was not specified | 605 | * optional result parameter that was not specified |
@@ -617,7 +621,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, | |||
617 | return_ACPI_STATUS(AE_NOT_IMPLEMENTED); | 621 | return_ACPI_STATUS(AE_NOT_IMPLEMENTED); |
618 | } | 622 | } |
619 | 623 | ||
620 | if (op_info->flags & AML_HAS_RETVAL) { | 624 | if ((op_info->flags & AML_HAS_RETVAL) |
625 | || (arg->common.flags & ACPI_PARSEOP_IN_STACK)) { | ||
621 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 626 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
622 | "Argument previously created, already stacked\n")); | 627 | "Argument previously created, already stacked\n")); |
623 | 628 | ||
@@ -630,9 +635,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, | |||
630 | * Use value that was already previously returned | 635 | * Use value that was already previously returned |
631 | * by the evaluation of this argument | 636 | * by the evaluation of this argument |
632 | */ | 637 | */ |
633 | status = | 638 | status = acpi_ds_result_pop(&obj_desc, walk_state); |
634 | acpi_ds_result_pop_from_bottom(&obj_desc, | ||
635 | walk_state); | ||
636 | if (ACPI_FAILURE(status)) { | 639 | if (ACPI_FAILURE(status)) { |
637 | /* | 640 | /* |
638 | * Only error is underflow, and this indicates | 641 | * Only error is underflow, and this indicates |
@@ -698,27 +701,52 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, | |||
698 | { | 701 | { |
699 | acpi_status status = AE_OK; | 702 | acpi_status status = AE_OK; |
700 | union acpi_parse_object *arg; | 703 | union acpi_parse_object *arg; |
704 | union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS]; | ||
701 | u32 arg_count = 0; | 705 | u32 arg_count = 0; |
706 | u32 index = walk_state->num_operands; | ||
707 | u32 i; | ||
702 | 708 | ||
703 | ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg); | 709 | ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg); |
704 | 710 | ||
705 | /* For all arguments in the list... */ | 711 | /* Get all arguments in the list */ |
706 | 712 | ||
707 | arg = first_arg; | 713 | arg = first_arg; |
708 | while (arg) { | 714 | while (arg) { |
709 | status = acpi_ds_create_operand(walk_state, arg, arg_count); | 715 | if (index >= ACPI_OBJ_NUM_OPERANDS) { |
710 | if (ACPI_FAILURE(status)) { | 716 | return_ACPI_STATUS(AE_BAD_DATA); |
711 | goto cleanup; | ||
712 | } | 717 | } |
713 | 718 | ||
714 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 719 | arguments[index] = arg; |
715 | "Arg #%d (%p) done, Arg1=%p\n", arg_count, | 720 | walk_state->operands[index] = NULL; |
716 | arg, first_arg)); | ||
717 | 721 | ||
718 | /* Move on to next argument, if any */ | 722 | /* Move on to next argument, if any */ |
719 | 723 | ||
720 | arg = arg->common.next; | 724 | arg = arg->common.next; |
721 | arg_count++; | 725 | arg_count++; |
726 | index++; | ||
727 | } | ||
728 | |||
729 | index--; | ||
730 | |||
731 | /* It is the appropriate order to get objects from the Result stack */ | ||
732 | |||
733 | for (i = 0; i < arg_count; i++) { | ||
734 | arg = arguments[index]; | ||
735 | |||
736 | /* Force the filling of the operand stack in inverse order */ | ||
737 | |||
738 | walk_state->operand_index = (u8) index; | ||
739 | |||
740 | status = acpi_ds_create_operand(walk_state, arg, index); | ||
741 | if (ACPI_FAILURE(status)) { | ||
742 | goto cleanup; | ||
743 | } | ||
744 | |||
745 | index--; | ||
746 | |||
747 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
748 | "Arg #%d (%p) done, Arg1=%p\n", index, arg, | ||
749 | first_arg)); | ||
722 | } | 750 | } |
723 | 751 | ||
724 | return_ACPI_STATUS(status); | 752 | return_ACPI_STATUS(status); |
@@ -729,9 +757,112 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, | |||
729 | * pop everything off of the operand stack and delete those | 757 | * pop everything off of the operand stack and delete those |
730 | * objects | 758 | * objects |
731 | */ | 759 | */ |
732 | (void)acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); | 760 | acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); |
761 | |||
762 | ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index)); | ||
763 | return_ACPI_STATUS(status); | ||
764 | } | ||
765 | |||
766 | /***************************************************************************** | ||
767 | * | ||
768 | * FUNCTION: acpi_ds_evaluate_name_path | ||
769 | * | ||
770 | * PARAMETERS: walk_state - Current state of the parse tree walk, | ||
771 | * the opcode of current operation should be | ||
772 | * AML_INT_NAMEPATH_OP | ||
773 | * | ||
774 | * RETURN: Status | ||
775 | * | ||
776 | * DESCRIPTION: Translate the -name_path- parse tree object to the equivalent | ||
777 | * interpreter object, convert it to value, if needed, duplicate | ||
778 | * it, if needed, and push it onto the current result stack. | ||
779 | * | ||
780 | ****************************************************************************/ | ||
781 | |||
782 | acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state) | ||
783 | { | ||
784 | acpi_status status = AE_OK; | ||
785 | union acpi_parse_object *op = walk_state->op; | ||
786 | union acpi_operand_object **operand = &walk_state->operands[0]; | ||
787 | union acpi_operand_object *new_obj_desc; | ||
788 | u8 type; | ||
789 | |||
790 | ACPI_FUNCTION_TRACE_PTR(ds_evaluate_name_path, walk_state); | ||
791 | |||
792 | if (!op->common.parent) { | ||
793 | |||
794 | /* This happens after certain exception processing */ | ||
795 | |||
796 | goto exit; | ||
797 | } | ||
798 | |||
799 | if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) || | ||
800 | (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) || | ||
801 | (op->common.parent->common.aml_opcode == AML_REF_OF_OP)) { | ||
802 | |||
803 | /* TBD: Should we specify this feature as a bit of op_info->Flags of these opcodes? */ | ||
804 | |||
805 | goto exit; | ||
806 | } | ||
807 | |||
808 | status = acpi_ds_create_operand(walk_state, op, 0); | ||
809 | if (ACPI_FAILURE(status)) { | ||
810 | goto exit; | ||
811 | } | ||
812 | |||
813 | if (op->common.flags & ACPI_PARSEOP_TARGET) { | ||
814 | new_obj_desc = *operand; | ||
815 | goto push_result; | ||
816 | } | ||
817 | |||
818 | type = ACPI_GET_OBJECT_TYPE(*operand); | ||
819 | |||
820 | status = acpi_ex_resolve_to_value(operand, walk_state); | ||
821 | if (ACPI_FAILURE(status)) { | ||
822 | goto exit; | ||
823 | } | ||
824 | |||
825 | if (type == ACPI_TYPE_INTEGER) { | ||
826 | |||
827 | /* It was incremented by acpi_ex_resolve_to_value */ | ||
828 | |||
829 | acpi_ut_remove_reference(*operand); | ||
830 | |||
831 | status = | ||
832 | acpi_ut_copy_iobject_to_iobject(*operand, &new_obj_desc, | ||
833 | walk_state); | ||
834 | if (ACPI_FAILURE(status)) { | ||
835 | goto exit; | ||
836 | } | ||
837 | } else { | ||
838 | /* | ||
839 | * The object either was anew created or is | ||
840 | * a Namespace node - don't decrement it. | ||
841 | */ | ||
842 | new_obj_desc = *operand; | ||
843 | } | ||
844 | |||
845 | /* Cleanup for name-path operand */ | ||
846 | |||
847 | status = acpi_ds_obj_stack_pop(1, walk_state); | ||
848 | if (ACPI_FAILURE(status)) { | ||
849 | walk_state->result_obj = new_obj_desc; | ||
850 | goto exit; | ||
851 | } | ||
852 | |||
853 | push_result: | ||
854 | |||
855 | walk_state->result_obj = new_obj_desc; | ||
856 | |||
857 | status = acpi_ds_result_push(walk_state->result_obj, walk_state); | ||
858 | if (ACPI_SUCCESS(status)) { | ||
859 | |||
860 | /* Force to take it from stack */ | ||
861 | |||
862 | op->common.flags |= ACPI_PARSEOP_IN_STACK; | ||
863 | } | ||
864 | |||
865 | exit: | ||
733 | 866 | ||
734 | ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", | ||
735 | (arg_count + 1))); | ||
736 | return_ACPI_STATUS(status); | 867 | return_ACPI_STATUS(status); |
737 | } | 868 | } |
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index 69693fa07224..b246b9657ead 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -285,11 +285,6 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, | |||
285 | switch (opcode_class) { | 285 | switch (opcode_class) { |
286 | case AML_CLASS_CONTROL: | 286 | case AML_CLASS_CONTROL: |
287 | 287 | ||
288 | status = acpi_ds_result_stack_push(walk_state); | ||
289 | if (ACPI_FAILURE(status)) { | ||
290 | goto error_exit; | ||
291 | } | ||
292 | |||
293 | status = acpi_ds_exec_begin_control_op(walk_state, op); | 288 | status = acpi_ds_exec_begin_control_op(walk_state, op); |
294 | break; | 289 | break; |
295 | 290 | ||
@@ -305,20 +300,11 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, | |||
305 | status = acpi_ds_load2_begin_op(walk_state, NULL); | 300 | status = acpi_ds_load2_begin_op(walk_state, NULL); |
306 | } | 301 | } |
307 | 302 | ||
308 | if (op->common.aml_opcode == AML_REGION_OP) { | ||
309 | status = acpi_ds_result_stack_push(walk_state); | ||
310 | } | ||
311 | break; | 303 | break; |
312 | 304 | ||
313 | case AML_CLASS_EXECUTE: | 305 | case AML_CLASS_EXECUTE: |
314 | case AML_CLASS_CREATE: | 306 | case AML_CLASS_CREATE: |
315 | /* | 307 | |
316 | * Most operators with arguments (except create_xxx_field operators) | ||
317 | * Start a new result/operand state | ||
318 | */ | ||
319 | if (walk_state->op_info->object_type != ACPI_TYPE_BUFFER_FIELD) { | ||
320 | status = acpi_ds_result_stack_push(walk_state); | ||
321 | } | ||
322 | break; | 308 | break; |
323 | 309 | ||
324 | default: | 310 | default: |
@@ -374,6 +360,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
374 | /* Init the walk state */ | 360 | /* Init the walk state */ |
375 | 361 | ||
376 | walk_state->num_operands = 0; | 362 | walk_state->num_operands = 0; |
363 | walk_state->operand_index = 0; | ||
377 | walk_state->return_desc = NULL; | 364 | walk_state->return_desc = NULL; |
378 | walk_state->result_obj = NULL; | 365 | walk_state->result_obj = NULL; |
379 | 366 | ||
@@ -388,10 +375,17 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
388 | /* Decode the Opcode Class */ | 375 | /* Decode the Opcode Class */ |
389 | 376 | ||
390 | switch (op_class) { | 377 | switch (op_class) { |
391 | case AML_CLASS_ARGUMENT: /* constants, literals, etc. - do nothing */ | 378 | case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */ |
379 | |||
380 | if (walk_state->opcode == AML_INT_NAMEPATH_OP) { | ||
381 | status = acpi_ds_evaluate_name_path(walk_state); | ||
382 | if (ACPI_FAILURE(status)) { | ||
383 | goto cleanup; | ||
384 | } | ||
385 | } | ||
392 | break; | 386 | break; |
393 | 387 | ||
394 | case AML_CLASS_EXECUTE: /* most operators with arguments */ | 388 | case AML_CLASS_EXECUTE: /* Most operators with arguments */ |
395 | 389 | ||
396 | /* Build resolved operand stack */ | 390 | /* Build resolved operand stack */ |
397 | 391 | ||
@@ -400,13 +394,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
400 | goto cleanup; | 394 | goto cleanup; |
401 | } | 395 | } |
402 | 396 | ||
403 | /* Done with this result state (Now that operand stack is built) */ | ||
404 | |||
405 | status = acpi_ds_result_stack_pop(walk_state); | ||
406 | if (ACPI_FAILURE(status)) { | ||
407 | goto cleanup; | ||
408 | } | ||
409 | |||
410 | /* | 397 | /* |
411 | * All opcodes require operand resolution, with the only exceptions | 398 | * All opcodes require operand resolution, with the only exceptions |
412 | * being the object_type and size_of operators. | 399 | * being the object_type and size_of operators. |
@@ -487,16 +474,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
487 | 474 | ||
488 | status = acpi_ds_exec_end_control_op(walk_state, op); | 475 | status = acpi_ds_exec_end_control_op(walk_state, op); |
489 | 476 | ||
490 | /* Make sure to properly pop the result stack */ | ||
491 | |||
492 | if (ACPI_SUCCESS(status)) { | ||
493 | status = acpi_ds_result_stack_pop(walk_state); | ||
494 | } else if (status == AE_CTRL_PENDING) { | ||
495 | status = acpi_ds_result_stack_pop(walk_state); | ||
496 | if (ACPI_SUCCESS(status)) { | ||
497 | status = AE_CTRL_PENDING; | ||
498 | } | ||
499 | } | ||
500 | break; | 477 | break; |
501 | 478 | ||
502 | case AML_TYPE_METHOD_CALL: | 479 | case AML_TYPE_METHOD_CALL: |
@@ -516,7 +493,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
516 | 493 | ||
517 | op->common.node = | 494 | op->common.node = |
518 | (struct acpi_namespace_node *)op->asl.value. | 495 | (struct acpi_namespace_node *)op->asl.value. |
519 | arg->asl.node->object; | 496 | arg->asl.node; |
520 | acpi_ut_add_reference(op->asl.value.arg->asl. | 497 | acpi_ut_add_reference(op->asl.value.arg->asl. |
521 | node->object); | 498 | node->object); |
522 | return_ACPI_STATUS(AE_OK); | 499 | return_ACPI_STATUS(AE_OK); |
@@ -632,13 +609,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
632 | break; | 609 | break; |
633 | } | 610 | } |
634 | 611 | ||
635 | /* Done with result state (Now that operand stack is built) */ | ||
636 | |||
637 | status = acpi_ds_result_stack_pop(walk_state); | ||
638 | if (ACPI_FAILURE(status)) { | ||
639 | goto cleanup; | ||
640 | } | ||
641 | |||
642 | /* | 612 | /* |
643 | * If a result object was returned from above, push it on the | 613 | * If a result object was returned from above, push it on the |
644 | * current result stack | 614 | * current result stack |
@@ -671,8 +641,28 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
671 | if (ACPI_FAILURE(status)) { | 641 | if (ACPI_FAILURE(status)) { |
672 | break; | 642 | break; |
673 | } | 643 | } |
644 | } else if (op->common.aml_opcode == AML_DATA_REGION_OP) { | ||
645 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
646 | "Executing DataTableRegion Strings Op=%p\n", | ||
647 | op)); | ||
648 | |||
649 | status = | ||
650 | acpi_ds_eval_table_region_operands | ||
651 | (walk_state, op); | ||
652 | if (ACPI_FAILURE(status)) { | ||
653 | break; | ||
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)); | ||
674 | 659 | ||
675 | status = acpi_ds_result_stack_pop(walk_state); | 660 | status = |
661 | acpi_ds_eval_bank_field_operands(walk_state, | ||
662 | op); | ||
663 | if (ACPI_FAILURE(status)) { | ||
664 | break; | ||
665 | } | ||
676 | } | 666 | } |
677 | break; | 667 | break; |
678 | 668 | ||
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index 8ab9d1b29a4c..dff7a3e445a8 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.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 |
@@ -443,6 +443,15 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) | |||
443 | if (ACPI_FAILURE(status)) { | 443 | if (ACPI_FAILURE(status)) { |
444 | return_ACPI_STATUS(status); | 444 | return_ACPI_STATUS(status); |
445 | } | 445 | } |
446 | } else if (op->common.aml_opcode == AML_DATA_REGION_OP) { | ||
447 | status = | ||
448 | acpi_ex_create_region(op->named.data, | ||
449 | op->named.length, | ||
450 | REGION_DATA_TABLE, | ||
451 | walk_state); | ||
452 | if (ACPI_FAILURE(status)) { | ||
453 | return_ACPI_STATUS(status); | ||
454 | } | ||
446 | } | 455 | } |
447 | } | 456 | } |
448 | #endif | 457 | #endif |
@@ -767,6 +776,12 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, | |||
767 | acpi_ns_lookup(walk_state->scope_info, buffer_ptr, | 776 | acpi_ns_lookup(walk_state->scope_info, buffer_ptr, |
768 | object_type, ACPI_IMODE_LOAD_PASS2, flags, | 777 | object_type, ACPI_IMODE_LOAD_PASS2, flags, |
769 | walk_state, &node); | 778 | walk_state, &node); |
779 | |||
780 | if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) { | ||
781 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
782 | "***New Node [%4.4s] %p is temporary\n", | ||
783 | acpi_ut_get_node_name(node), node)); | ||
784 | } | ||
770 | break; | 785 | break; |
771 | } | 786 | } |
772 | 787 | ||
@@ -823,6 +838,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
823 | struct acpi_namespace_node *new_node; | 838 | struct acpi_namespace_node *new_node; |
824 | #ifndef ACPI_NO_METHOD_EXECUTION | 839 | #ifndef ACPI_NO_METHOD_EXECUTION |
825 | u32 i; | 840 | u32 i; |
841 | u8 region_space; | ||
826 | #endif | 842 | #endif |
827 | 843 | ||
828 | ACPI_FUNCTION_TRACE(ds_load2_end_op); | 844 | ACPI_FUNCTION_TRACE(ds_load2_end_op); |
@@ -1003,11 +1019,6 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
1003 | status = acpi_ex_create_event(walk_state); | 1019 | status = acpi_ex_create_event(walk_state); |
1004 | break; | 1020 | break; |
1005 | 1021 | ||
1006 | case AML_DATA_REGION_OP: | ||
1007 | |||
1008 | status = acpi_ex_create_table_region(walk_state); | ||
1009 | break; | ||
1010 | |||
1011 | case AML_ALIAS_OP: | 1022 | case AML_ALIAS_OP: |
1012 | 1023 | ||
1013 | status = acpi_ex_create_alias(walk_state); | 1024 | status = acpi_ex_create_alias(walk_state); |
@@ -1035,6 +1046,15 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
1035 | switch (op->common.aml_opcode) { | 1046 | switch (op->common.aml_opcode) { |
1036 | #ifndef ACPI_NO_METHOD_EXECUTION | 1047 | #ifndef ACPI_NO_METHOD_EXECUTION |
1037 | case AML_REGION_OP: | 1048 | case AML_REGION_OP: |
1049 | case AML_DATA_REGION_OP: | ||
1050 | |||
1051 | if (op->common.aml_opcode == AML_REGION_OP) { | ||
1052 | region_space = (acpi_adr_space_type) | ||
1053 | ((op->common.value.arg)->common.value. | ||
1054 | integer); | ||
1055 | } else { | ||
1056 | region_space = REGION_DATA_TABLE; | ||
1057 | } | ||
1038 | 1058 | ||
1039 | /* | 1059 | /* |
1040 | * If we are executing a method, initialize the region | 1060 | * If we are executing a method, initialize the region |
@@ -1043,10 +1063,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
1043 | status = | 1063 | status = |
1044 | acpi_ex_create_region(op->named.data, | 1064 | acpi_ex_create_region(op->named.data, |
1045 | op->named.length, | 1065 | op->named.length, |
1046 | (acpi_adr_space_type) | 1066 | region_space, |
1047 | ((op->common.value. | ||
1048 | arg)->common.value. | ||
1049 | integer), | ||
1050 | walk_state); | 1067 | walk_state); |
1051 | if (ACPI_FAILURE(status)) { | 1068 | if (ACPI_FAILURE(status)) { |
1052 | return (status); | 1069 | return (status); |
diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c index 3927c495e4bf..9e6073265873 100644 --- a/drivers/acpi/dispatcher/dswscope.c +++ b/drivers/acpi/dispatcher/dswscope.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 |
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c index 5afcdd9c7449..1386ced332ec 100644 --- a/drivers/acpi/dispatcher/dswstate.c +++ b/drivers/acpi/dispatcher/dswstate.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 |
@@ -49,85 +49,9 @@ | |||
49 | #define _COMPONENT ACPI_DISPATCHER | 49 | #define _COMPONENT ACPI_DISPATCHER |
50 | ACPI_MODULE_NAME("dswstate") | 50 | ACPI_MODULE_NAME("dswstate") |
51 | 51 | ||
52 | /* Local prototypes */ | 52 | /* Local prototypes */ |
53 | #ifdef ACPI_OBSOLETE_FUNCTIONS | 53 | static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *ws); |
54 | acpi_status | 54 | static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *ws); |
55 | acpi_ds_result_insert(void *object, | ||
56 | u32 index, struct acpi_walk_state *walk_state); | ||
57 | |||
58 | acpi_status acpi_ds_obj_stack_delete_all(struct acpi_walk_state *walk_state); | ||
59 | |||
60 | acpi_status | ||
61 | acpi_ds_obj_stack_pop_object(union acpi_operand_object **object, | ||
62 | struct acpi_walk_state *walk_state); | ||
63 | |||
64 | void *acpi_ds_obj_stack_get_value(u32 index, | ||
65 | struct acpi_walk_state *walk_state); | ||
66 | #endif | ||
67 | |||
68 | #ifdef ACPI_FUTURE_USAGE | ||
69 | /******************************************************************************* | ||
70 | * | ||
71 | * FUNCTION: acpi_ds_result_remove | ||
72 | * | ||
73 | * PARAMETERS: Object - Where to return the popped object | ||
74 | * Index - Where to extract the object | ||
75 | * walk_state - Current Walk state | ||
76 | * | ||
77 | * RETURN: Status | ||
78 | * | ||
79 | * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In | ||
80 | * other words, this is a FIFO. | ||
81 | * | ||
82 | ******************************************************************************/ | ||
83 | |||
84 | acpi_status | ||
85 | acpi_ds_result_remove(union acpi_operand_object **object, | ||
86 | u32 index, struct acpi_walk_state *walk_state) | ||
87 | { | ||
88 | union acpi_generic_state *state; | ||
89 | |||
90 | ACPI_FUNCTION_NAME(ds_result_remove); | ||
91 | |||
92 | state = walk_state->results; | ||
93 | if (!state) { | ||
94 | ACPI_ERROR((AE_INFO, "No result object pushed! State=%p", | ||
95 | walk_state)); | ||
96 | return (AE_NOT_EXIST); | ||
97 | } | ||
98 | |||
99 | if (index >= ACPI_OBJ_MAX_OPERAND) { | ||
100 | ACPI_ERROR((AE_INFO, | ||
101 | "Index out of range: %X State=%p Num=%X", | ||
102 | index, walk_state, state->results.num_results)); | ||
103 | } | ||
104 | |||
105 | /* Check for a valid result object */ | ||
106 | |||
107 | if (!state->results.obj_desc[index]) { | ||
108 | ACPI_ERROR((AE_INFO, | ||
109 | "Null operand! State=%p #Ops=%X, Index=%X", | ||
110 | walk_state, state->results.num_results, index)); | ||
111 | return (AE_AML_NO_RETURN_VALUE); | ||
112 | } | ||
113 | |||
114 | /* Remove the object */ | ||
115 | |||
116 | state->results.num_results--; | ||
117 | |||
118 | *object = state->results.obj_desc[index]; | ||
119 | state->results.obj_desc[index] = NULL; | ||
120 | |||
121 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
122 | "Obj=%p [%s] Index=%X State=%p Num=%X\n", | ||
123 | *object, | ||
124 | (*object) ? acpi_ut_get_object_type_name(*object) : | ||
125 | "NULL", index, walk_state, | ||
126 | state->results.num_results)); | ||
127 | |||
128 | return (AE_OK); | ||
129 | } | ||
130 | #endif /* ACPI_FUTURE_USAGE */ | ||
131 | 55 | ||
132 | /******************************************************************************* | 56 | /******************************************************************************* |
133 | * | 57 | * |
@@ -138,122 +62,67 @@ acpi_ds_result_remove(union acpi_operand_object **object, | |||
138 | * | 62 | * |
139 | * RETURN: Status | 63 | * RETURN: Status |
140 | * | 64 | * |
141 | * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In | 65 | * DESCRIPTION: Pop an object off the top of this walk's result stack |
142 | * other words, this is a FIFO. | ||
143 | * | 66 | * |
144 | ******************************************************************************/ | 67 | ******************************************************************************/ |
145 | 68 | ||
146 | acpi_status | 69 | acpi_status |
147 | acpi_ds_result_pop(union acpi_operand_object ** object, | 70 | acpi_ds_result_pop(union acpi_operand_object **object, |
148 | struct acpi_walk_state * walk_state) | 71 | struct acpi_walk_state *walk_state) |
149 | { | 72 | { |
150 | acpi_native_uint index; | 73 | acpi_native_uint index; |
151 | union acpi_generic_state *state; | 74 | union acpi_generic_state *state; |
75 | acpi_status status; | ||
152 | 76 | ||
153 | ACPI_FUNCTION_NAME(ds_result_pop); | 77 | ACPI_FUNCTION_NAME(ds_result_pop); |
154 | 78 | ||
155 | state = walk_state->results; | 79 | state = walk_state->results; |
156 | if (!state) { | ||
157 | return (AE_OK); | ||
158 | } | ||
159 | |||
160 | if (!state->results.num_results) { | ||
161 | ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p", | ||
162 | walk_state)); | ||
163 | return (AE_AML_NO_RETURN_VALUE); | ||
164 | } | ||
165 | 80 | ||
166 | /* Remove top element */ | 81 | /* Incorrect state of result stack */ |
167 | 82 | ||
168 | state->results.num_results--; | 83 | if (state && !walk_state->result_count) { |
169 | 84 | ACPI_ERROR((AE_INFO, "No results on result stack")); | |
170 | for (index = ACPI_OBJ_NUM_OPERANDS; index; index--) { | 85 | return (AE_AML_INTERNAL); |
171 | |||
172 | /* Check for a valid result object */ | ||
173 | |||
174 | if (state->results.obj_desc[index - 1]) { | ||
175 | *object = state->results.obj_desc[index - 1]; | ||
176 | state->results.obj_desc[index - 1] = NULL; | ||
177 | |||
178 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
179 | "Obj=%p [%s] Index=%X State=%p Num=%X\n", | ||
180 | *object, | ||
181 | (*object) ? | ||
182 | acpi_ut_get_object_type_name(*object) | ||
183 | : "NULL", (u32) index - 1, walk_state, | ||
184 | state->results.num_results)); | ||
185 | |||
186 | return (AE_OK); | ||
187 | } | ||
188 | } | 86 | } |
189 | 87 | ||
190 | ACPI_ERROR((AE_INFO, "No result objects! State=%p", walk_state)); | 88 | if (!state && walk_state->result_count) { |
191 | return (AE_AML_NO_RETURN_VALUE); | 89 | ACPI_ERROR((AE_INFO, "No result state for result stack")); |
192 | } | 90 | return (AE_AML_INTERNAL); |
193 | 91 | } | |
194 | /******************************************************************************* | ||
195 | * | ||
196 | * FUNCTION: acpi_ds_result_pop_from_bottom | ||
197 | * | ||
198 | * PARAMETERS: Object - Where to return the popped object | ||
199 | * walk_state - Current Walk state | ||
200 | * | ||
201 | * RETURN: Status | ||
202 | * | ||
203 | * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In | ||
204 | * other words, this is a FIFO. | ||
205 | * | ||
206 | ******************************************************************************/ | ||
207 | |||
208 | acpi_status | ||
209 | acpi_ds_result_pop_from_bottom(union acpi_operand_object ** object, | ||
210 | struct acpi_walk_state * walk_state) | ||
211 | { | ||
212 | acpi_native_uint index; | ||
213 | union acpi_generic_state *state; | ||
214 | 92 | ||
215 | ACPI_FUNCTION_NAME(ds_result_pop_from_bottom); | 93 | /* Empty result stack */ |
216 | 94 | ||
217 | state = walk_state->results; | ||
218 | if (!state) { | 95 | if (!state) { |
219 | ACPI_ERROR((AE_INFO, | 96 | ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p", |
220 | "No result object pushed! State=%p", walk_state)); | ||
221 | return (AE_NOT_EXIST); | ||
222 | } | ||
223 | |||
224 | if (!state->results.num_results) { | ||
225 | ACPI_ERROR((AE_INFO, "No result objects! State=%p", | ||
226 | walk_state)); | 97 | walk_state)); |
227 | return (AE_AML_NO_RETURN_VALUE); | 98 | return (AE_AML_NO_RETURN_VALUE); |
228 | } | 99 | } |
229 | 100 | ||
230 | /* Remove Bottom element */ | 101 | /* Return object of the top element and clean that top element result stack */ |
231 | |||
232 | *object = state->results.obj_desc[0]; | ||
233 | |||
234 | /* Push entire stack down one element */ | ||
235 | |||
236 | for (index = 0; index < state->results.num_results; index++) { | ||
237 | state->results.obj_desc[index] = | ||
238 | state->results.obj_desc[index + 1]; | ||
239 | } | ||
240 | 102 | ||
241 | state->results.num_results--; | 103 | walk_state->result_count--; |
242 | 104 | index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; | |
243 | /* Check for a valid result object */ | ||
244 | 105 | ||
106 | *object = state->results.obj_desc[index]; | ||
245 | if (!*object) { | 107 | if (!*object) { |
246 | ACPI_ERROR((AE_INFO, | 108 | ACPI_ERROR((AE_INFO, |
247 | "Null operand! State=%p #Ops=%X Index=%X", | 109 | "No result objects on result stack, State=%p", |
248 | walk_state, state->results.num_results, | 110 | walk_state)); |
249 | (u32) index)); | ||
250 | return (AE_AML_NO_RETURN_VALUE); | 111 | return (AE_AML_NO_RETURN_VALUE); |
251 | } | 112 | } |
252 | 113 | ||
253 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] Results=%p State=%p\n", | 114 | state->results.obj_desc[index] = NULL; |
254 | *object, | 115 | if (index == 0) { |
255 | (*object) ? acpi_ut_get_object_type_name(*object) : | 116 | status = acpi_ds_result_stack_pop(walk_state); |
256 | "NULL", state, walk_state)); | 117 | if (ACPI_FAILURE(status)) { |
118 | return (status); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
123 | "Obj=%p [%s] Index=%X State=%p Num=%X\n", *object, | ||
124 | acpi_ut_get_object_type_name(*object), | ||
125 | (u32) index, walk_state, walk_state->result_count)); | ||
257 | 126 | ||
258 | return (AE_OK); | 127 | return (AE_OK); |
259 | } | 128 | } |
@@ -276,39 +145,56 @@ acpi_ds_result_push(union acpi_operand_object * object, | |||
276 | struct acpi_walk_state * walk_state) | 145 | struct acpi_walk_state * walk_state) |
277 | { | 146 | { |
278 | union acpi_generic_state *state; | 147 | union acpi_generic_state *state; |
148 | acpi_status status; | ||
149 | acpi_native_uint index; | ||
279 | 150 | ||
280 | ACPI_FUNCTION_NAME(ds_result_push); | 151 | ACPI_FUNCTION_NAME(ds_result_push); |
281 | 152 | ||
153 | if (walk_state->result_count > walk_state->result_size) { | ||
154 | ACPI_ERROR((AE_INFO, "Result stack is full")); | ||
155 | return (AE_AML_INTERNAL); | ||
156 | } else if (walk_state->result_count == walk_state->result_size) { | ||
157 | |||
158 | /* Extend the result stack */ | ||
159 | |||
160 | status = acpi_ds_result_stack_push(walk_state); | ||
161 | if (ACPI_FAILURE(status)) { | ||
162 | ACPI_ERROR((AE_INFO, | ||
163 | "Failed to extend the result stack")); | ||
164 | return (status); | ||
165 | } | ||
166 | } | ||
167 | |||
168 | if (!(walk_state->result_count < walk_state->result_size)) { | ||
169 | ACPI_ERROR((AE_INFO, "No free elements in result stack")); | ||
170 | return (AE_AML_INTERNAL); | ||
171 | } | ||
172 | |||
282 | state = walk_state->results; | 173 | state = walk_state->results; |
283 | if (!state) { | 174 | if (!state) { |
284 | ACPI_ERROR((AE_INFO, "No result stack frame during push")); | 175 | ACPI_ERROR((AE_INFO, "No result stack frame during push")); |
285 | return (AE_AML_INTERNAL); | 176 | return (AE_AML_INTERNAL); |
286 | } | 177 | } |
287 | 178 | ||
288 | if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) { | ||
289 | ACPI_ERROR((AE_INFO, | ||
290 | "Result stack overflow: Obj=%p State=%p Num=%X", | ||
291 | object, walk_state, state->results.num_results)); | ||
292 | return (AE_STACK_OVERFLOW); | ||
293 | } | ||
294 | |||
295 | if (!object) { | 179 | if (!object) { |
296 | ACPI_ERROR((AE_INFO, | 180 | ACPI_ERROR((AE_INFO, |
297 | "Null Object! Obj=%p State=%p Num=%X", | 181 | "Null Object! Obj=%p State=%p Num=%X", |
298 | object, walk_state, state->results.num_results)); | 182 | object, walk_state, walk_state->result_count)); |
299 | return (AE_BAD_PARAMETER); | 183 | return (AE_BAD_PARAMETER); |
300 | } | 184 | } |
301 | 185 | ||
302 | state->results.obj_desc[state->results.num_results] = object; | 186 | /* Assign the address of object to the top free element of result stack */ |
303 | state->results.num_results++; | 187 | |
188 | index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; | ||
189 | state->results.obj_desc[index] = object; | ||
190 | walk_state->result_count++; | ||
304 | 191 | ||
305 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n", | 192 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n", |
306 | object, | 193 | object, |
307 | object ? | ||
308 | acpi_ut_get_object_type_name((union | 194 | acpi_ut_get_object_type_name((union |
309 | acpi_operand_object *) | 195 | acpi_operand_object *) |
310 | object) : "NULL", | 196 | object), walk_state, |
311 | walk_state, state->results.num_results, | 197 | walk_state->result_count, |
312 | walk_state->current_result)); | 198 | walk_state->current_result)); |
313 | 199 | ||
314 | return (AE_OK); | 200 | return (AE_OK); |
@@ -322,16 +208,25 @@ acpi_ds_result_push(union acpi_operand_object * object, | |||
322 | * | 208 | * |
323 | * RETURN: Status | 209 | * RETURN: Status |
324 | * | 210 | * |
325 | * DESCRIPTION: Push an object onto the walk_state result stack. | 211 | * DESCRIPTION: Push an object onto the walk_state result stack |
326 | * | 212 | * |
327 | ******************************************************************************/ | 213 | ******************************************************************************/ |
328 | 214 | ||
329 | acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state) | 215 | static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *walk_state) |
330 | { | 216 | { |
331 | union acpi_generic_state *state; | 217 | union acpi_generic_state *state; |
332 | 218 | ||
333 | ACPI_FUNCTION_NAME(ds_result_stack_push); | 219 | ACPI_FUNCTION_NAME(ds_result_stack_push); |
334 | 220 | ||
221 | /* Check for stack overflow */ | ||
222 | |||
223 | if (((u32) walk_state->result_size + ACPI_RESULTS_FRAME_OBJ_NUM) > | ||
224 | ACPI_RESULTS_OBJ_NUM_MAX) { | ||
225 | ACPI_ERROR((AE_INFO, "Result stack overflow: State=%p Num=%X", | ||
226 | walk_state, walk_state->result_size)); | ||
227 | return (AE_STACK_OVERFLOW); | ||
228 | } | ||
229 | |||
335 | state = acpi_ut_create_generic_state(); | 230 | state = acpi_ut_create_generic_state(); |
336 | if (!state) { | 231 | if (!state) { |
337 | return (AE_NO_MEMORY); | 232 | return (AE_NO_MEMORY); |
@@ -340,6 +235,10 @@ acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state) | |||
340 | state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT; | 235 | state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT; |
341 | acpi_ut_push_generic_state(&walk_state->results, state); | 236 | acpi_ut_push_generic_state(&walk_state->results, state); |
342 | 237 | ||
238 | /* Increase the length of the result stack by the length of frame */ | ||
239 | |||
240 | walk_state->result_size += ACPI_RESULTS_FRAME_OBJ_NUM; | ||
241 | |||
343 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n", | 242 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n", |
344 | state, walk_state)); | 243 | state, walk_state)); |
345 | 244 | ||
@@ -354,11 +253,11 @@ acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state) | |||
354 | * | 253 | * |
355 | * RETURN: Status | 254 | * RETURN: Status |
356 | * | 255 | * |
357 | * DESCRIPTION: Pop an object off of the walk_state result stack. | 256 | * DESCRIPTION: Pop an object off of the walk_state result stack |
358 | * | 257 | * |
359 | ******************************************************************************/ | 258 | ******************************************************************************/ |
360 | 259 | ||
361 | acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state * walk_state) | 260 | static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state) |
362 | { | 261 | { |
363 | union acpi_generic_state *state; | 262 | union acpi_generic_state *state; |
364 | 263 | ||
@@ -367,18 +266,27 @@ acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state * walk_state) | |||
367 | /* Check for stack underflow */ | 266 | /* Check for stack underflow */ |
368 | 267 | ||
369 | if (walk_state->results == NULL) { | 268 | if (walk_state->results == NULL) { |
370 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Underflow - State=%p\n", | 269 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
270 | "Result stack underflow - State=%p\n", | ||
371 | walk_state)); | 271 | walk_state)); |
372 | return (AE_AML_NO_OPERAND); | 272 | return (AE_AML_NO_OPERAND); |
373 | } | 273 | } |
374 | 274 | ||
275 | if (walk_state->result_size < ACPI_RESULTS_FRAME_OBJ_NUM) { | ||
276 | ACPI_ERROR((AE_INFO, "Insufficient result stack size")); | ||
277 | return (AE_AML_INTERNAL); | ||
278 | } | ||
279 | |||
375 | state = acpi_ut_pop_generic_state(&walk_state->results); | 280 | state = acpi_ut_pop_generic_state(&walk_state->results); |
281 | acpi_ut_delete_generic_state(state); | ||
282 | |||
283 | /* Decrease the length of result stack by the length of frame */ | ||
284 | |||
285 | walk_state->result_size -= ACPI_RESULTS_FRAME_OBJ_NUM; | ||
376 | 286 | ||
377 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 287 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
378 | "Result=%p RemainingResults=%X State=%p\n", | 288 | "Result=%p RemainingResults=%X State=%p\n", |
379 | state, state->results.num_results, walk_state)); | 289 | state, walk_state->result_count, walk_state)); |
380 | |||
381 | acpi_ut_delete_generic_state(state); | ||
382 | 290 | ||
383 | return (AE_OK); | 291 | return (AE_OK); |
384 | } | 292 | } |
@@ -412,9 +320,13 @@ acpi_ds_obj_stack_push(void *object, struct acpi_walk_state * walk_state) | |||
412 | 320 | ||
413 | /* Put the object onto the stack */ | 321 | /* Put the object onto the stack */ |
414 | 322 | ||
415 | walk_state->operands[walk_state->num_operands] = object; | 323 | walk_state->operands[walk_state->operand_index] = object; |
416 | walk_state->num_operands++; | 324 | walk_state->num_operands++; |
417 | 325 | ||
326 | /* For the usual order of filling the operand stack */ | ||
327 | |||
328 | walk_state->operand_index++; | ||
329 | |||
418 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", | 330 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", |
419 | object, | 331 | object, |
420 | acpi_ut_get_object_type_name((union | 332 | acpi_ut_get_object_type_name((union |
@@ -484,43 +396,36 @@ acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state * walk_state) | |||
484 | * | 396 | * |
485 | ******************************************************************************/ | 397 | ******************************************************************************/ |
486 | 398 | ||
487 | acpi_status | 399 | void |
488 | acpi_ds_obj_stack_pop_and_delete(u32 pop_count, | 400 | acpi_ds_obj_stack_pop_and_delete(u32 pop_count, |
489 | struct acpi_walk_state * walk_state) | 401 | struct acpi_walk_state *walk_state) |
490 | { | 402 | { |
491 | u32 i; | 403 | acpi_native_int i; |
492 | union acpi_operand_object *obj_desc; | 404 | union acpi_operand_object *obj_desc; |
493 | 405 | ||
494 | ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete); | 406 | ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete); |
495 | 407 | ||
496 | for (i = 0; i < pop_count; i++) { | 408 | if (pop_count == 0) { |
497 | 409 | return; | |
498 | /* Check for stack underflow */ | 410 | } |
499 | 411 | ||
412 | for (i = (acpi_native_int) (pop_count - 1); i >= 0; i--) { | ||
500 | if (walk_state->num_operands == 0) { | 413 | if (walk_state->num_operands == 0) { |
501 | ACPI_ERROR((AE_INFO, | 414 | return; |
502 | "Object stack underflow! Count=%X State=%p #Ops=%X", | ||
503 | pop_count, walk_state, | ||
504 | walk_state->num_operands)); | ||
505 | return (AE_STACK_UNDERFLOW); | ||
506 | } | 415 | } |
507 | 416 | ||
508 | /* Pop the stack and delete an object if present in this stack entry */ | 417 | /* Pop the stack and delete an object if present in this stack entry */ |
509 | 418 | ||
510 | walk_state->num_operands--; | 419 | walk_state->num_operands--; |
511 | obj_desc = walk_state->operands[walk_state->num_operands]; | 420 | obj_desc = walk_state->operands[i]; |
512 | if (obj_desc) { | 421 | if (obj_desc) { |
513 | acpi_ut_remove_reference(walk_state-> | 422 | acpi_ut_remove_reference(walk_state->operands[i]); |
514 | operands[walk_state-> | 423 | walk_state->operands[i] = NULL; |
515 | num_operands]); | ||
516 | walk_state->operands[walk_state->num_operands] = NULL; | ||
517 | } | 424 | } |
518 | } | 425 | } |
519 | 426 | ||
520 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n", | 427 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n", |
521 | pop_count, walk_state, walk_state->num_operands)); | 428 | pop_count, walk_state, walk_state->num_operands)); |
522 | |||
523 | return (AE_OK); | ||
524 | } | 429 | } |
525 | 430 | ||
526 | /******************************************************************************* | 431 | /******************************************************************************* |
@@ -560,7 +465,7 @@ struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state | |||
560 | * | 465 | * |
561 | * RETURN: None | 466 | * RETURN: None |
562 | * | 467 | * |
563 | * DESCRIPTION: Place the Thread state at the head of the state list. | 468 | * DESCRIPTION: Place the Thread state at the head of the state list |
564 | * | 469 | * |
565 | ******************************************************************************/ | 470 | ******************************************************************************/ |
566 | 471 | ||
@@ -636,7 +541,6 @@ struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union | |||
636 | *thread) | 541 | *thread) |
637 | { | 542 | { |
638 | struct acpi_walk_state *walk_state; | 543 | struct acpi_walk_state *walk_state; |
639 | acpi_status status; | ||
640 | 544 | ||
641 | ACPI_FUNCTION_TRACE(ds_create_walk_state); | 545 | ACPI_FUNCTION_TRACE(ds_create_walk_state); |
642 | 546 | ||
@@ -659,14 +563,6 @@ struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union | |||
659 | acpi_ds_method_data_init(walk_state); | 563 | acpi_ds_method_data_init(walk_state); |
660 | #endif | 564 | #endif |
661 | 565 | ||
662 | /* Create an initial result stack entry */ | ||
663 | |||
664 | status = acpi_ds_result_stack_push(walk_state); | ||
665 | if (ACPI_FAILURE(status)) { | ||
666 | ACPI_FREE(walk_state); | ||
667 | return_PTR(NULL); | ||
668 | } | ||
669 | |||
670 | /* Put the new state at the head of the walk list */ | 566 | /* Put the new state at the head of the walk list */ |
671 | 567 | ||
672 | if (thread) { | 568 | if (thread) { |
@@ -860,190 +756,3 @@ void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state) | |||
860 | ACPI_FREE(walk_state); | 756 | ACPI_FREE(walk_state); |
861 | return_VOID; | 757 | return_VOID; |
862 | } | 758 | } |
863 | |||
864 | #ifdef ACPI_OBSOLETE_FUNCTIONS | ||
865 | /******************************************************************************* | ||
866 | * | ||
867 | * FUNCTION: acpi_ds_result_insert | ||
868 | * | ||
869 | * PARAMETERS: Object - Object to push | ||
870 | * Index - Where to insert the object | ||
871 | * walk_state - Current Walk state | ||
872 | * | ||
873 | * RETURN: Status | ||
874 | * | ||
875 | * DESCRIPTION: Insert an object onto this walk's result stack | ||
876 | * | ||
877 | ******************************************************************************/ | ||
878 | |||
879 | acpi_status | ||
880 | acpi_ds_result_insert(void *object, | ||
881 | u32 index, struct acpi_walk_state *walk_state) | ||
882 | { | ||
883 | union acpi_generic_state *state; | ||
884 | |||
885 | ACPI_FUNCTION_NAME(ds_result_insert); | ||
886 | |||
887 | state = walk_state->results; | ||
888 | if (!state) { | ||
889 | ACPI_ERROR((AE_INFO, "No result object pushed! State=%p", | ||
890 | walk_state)); | ||
891 | return (AE_NOT_EXIST); | ||
892 | } | ||
893 | |||
894 | if (index >= ACPI_OBJ_NUM_OPERANDS) { | ||
895 | ACPI_ERROR((AE_INFO, | ||
896 | "Index out of range: %X Obj=%p State=%p Num=%X", | ||
897 | index, object, walk_state, | ||
898 | state->results.num_results)); | ||
899 | return (AE_BAD_PARAMETER); | ||
900 | } | ||
901 | |||
902 | if (!object) { | ||
903 | ACPI_ERROR((AE_INFO, | ||
904 | "Null Object! Index=%X Obj=%p State=%p Num=%X", | ||
905 | index, object, walk_state, | ||
906 | state->results.num_results)); | ||
907 | return (AE_BAD_PARAMETER); | ||
908 | } | ||
909 | |||
910 | state->results.obj_desc[index] = object; | ||
911 | state->results.num_results++; | ||
912 | |||
913 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
914 | "Obj=%p [%s] State=%p Num=%X Cur=%X\n", | ||
915 | object, | ||
916 | object ? | ||
917 | acpi_ut_get_object_type_name((union | ||
918 | acpi_operand_object *) | ||
919 | object) : "NULL", | ||
920 | walk_state, state->results.num_results, | ||
921 | walk_state->current_result)); | ||
922 | |||
923 | return (AE_OK); | ||
924 | } | ||
925 | |||
926 | /******************************************************************************* | ||
927 | * | ||
928 | * FUNCTION: acpi_ds_obj_stack_delete_all | ||
929 | * | ||
930 | * PARAMETERS: walk_state - Current Walk state | ||
931 | * | ||
932 | * RETURN: Status | ||
933 | * | ||
934 | * DESCRIPTION: Clear the object stack by deleting all objects that are on it. | ||
935 | * Should be used with great care, if at all! | ||
936 | * | ||
937 | ******************************************************************************/ | ||
938 | |||
939 | acpi_status acpi_ds_obj_stack_delete_all(struct acpi_walk_state * walk_state) | ||
940 | { | ||
941 | u32 i; | ||
942 | |||
943 | ACPI_FUNCTION_TRACE_PTR(ds_obj_stack_delete_all, walk_state); | ||
944 | |||
945 | /* The stack size is configurable, but fixed */ | ||
946 | |||
947 | for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) { | ||
948 | if (walk_state->operands[i]) { | ||
949 | acpi_ut_remove_reference(walk_state->operands[i]); | ||
950 | walk_state->operands[i] = NULL; | ||
951 | } | ||
952 | } | ||
953 | |||
954 | return_ACPI_STATUS(AE_OK); | ||
955 | } | ||
956 | |||
957 | /******************************************************************************* | ||
958 | * | ||
959 | * FUNCTION: acpi_ds_obj_stack_pop_object | ||
960 | * | ||
961 | * PARAMETERS: Object - Where to return the popped object | ||
962 | * walk_state - Current Walk state | ||
963 | * | ||
964 | * RETURN: Status | ||
965 | * | ||
966 | * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT | ||
967 | * deleted by this routine. | ||
968 | * | ||
969 | ******************************************************************************/ | ||
970 | |||
971 | acpi_status | ||
972 | acpi_ds_obj_stack_pop_object(union acpi_operand_object **object, | ||
973 | struct acpi_walk_state *walk_state) | ||
974 | { | ||
975 | ACPI_FUNCTION_NAME(ds_obj_stack_pop_object); | ||
976 | |||
977 | /* Check for stack underflow */ | ||
978 | |||
979 | if (walk_state->num_operands == 0) { | ||
980 | ACPI_ERROR((AE_INFO, | ||
981 | "Missing operand/stack empty! State=%p #Ops=%X", | ||
982 | walk_state, walk_state->num_operands)); | ||
983 | *object = NULL; | ||
984 | return (AE_AML_NO_OPERAND); | ||
985 | } | ||
986 | |||
987 | /* Pop the stack */ | ||
988 | |||
989 | walk_state->num_operands--; | ||
990 | |||
991 | /* Check for a valid operand */ | ||
992 | |||
993 | if (!walk_state->operands[walk_state->num_operands]) { | ||
994 | ACPI_ERROR((AE_INFO, | ||
995 | "Null operand! State=%p #Ops=%X", | ||
996 | walk_state, walk_state->num_operands)); | ||
997 | *object = NULL; | ||
998 | return (AE_AML_NO_OPERAND); | ||
999 | } | ||
1000 | |||
1001 | /* Get operand and set stack entry to null */ | ||
1002 | |||
1003 | *object = walk_state->operands[walk_state->num_operands]; | ||
1004 | walk_state->operands[walk_state->num_operands] = NULL; | ||
1005 | |||
1006 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", | ||
1007 | *object, acpi_ut_get_object_type_name(*object), | ||
1008 | walk_state, walk_state->num_operands)); | ||
1009 | |||
1010 | return (AE_OK); | ||
1011 | } | ||
1012 | |||
1013 | /******************************************************************************* | ||
1014 | * | ||
1015 | * FUNCTION: acpi_ds_obj_stack_get_value | ||
1016 | * | ||
1017 | * PARAMETERS: Index - Stack index whose value is desired. Based | ||
1018 | * on the top of the stack (index=0 == top) | ||
1019 | * walk_state - Current Walk state | ||
1020 | * | ||
1021 | * RETURN: Pointer to the requested operand | ||
1022 | * | ||
1023 | * DESCRIPTION: Retrieve an object from this walk's operand stack. Index must | ||
1024 | * be within the range of the current stack pointer. | ||
1025 | * | ||
1026 | ******************************************************************************/ | ||
1027 | |||
1028 | void *acpi_ds_obj_stack_get_value(u32 index, struct acpi_walk_state *walk_state) | ||
1029 | { | ||
1030 | |||
1031 | ACPI_FUNCTION_TRACE_PTR(ds_obj_stack_get_value, walk_state); | ||
1032 | |||
1033 | /* Can't do it if the stack is empty */ | ||
1034 | |||
1035 | if (walk_state->num_operands == 0) { | ||
1036 | return_PTR(NULL); | ||
1037 | } | ||
1038 | |||
1039 | /* or if the index is past the top of the stack */ | ||
1040 | |||
1041 | if (index > (walk_state->num_operands - (u32) 1)) { | ||
1042 | return_PTR(NULL); | ||
1043 | } | ||
1044 | |||
1045 | return_PTR(walk_state-> | ||
1046 | operands[(acpi_native_uint) (walk_state->num_operands - 1) - | ||
1047 | index]); | ||
1048 | } | ||
1049 | #endif | ||