diff options
-rw-r--r-- | drivers/acpi/dispatcher/dsmethod.c | 8 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dsopcode.c | 15 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dswload.c | 56 | ||||
-rw-r--r-- | drivers/acpi/dispatcher/dswstate.c | 1 | ||||
-rw-r--r-- | drivers/acpi/executer/exconfig.c | 27 | ||||
-rw-r--r-- | drivers/acpi/executer/exfield.c | 5 | ||||
-rw-r--r-- | drivers/acpi/executer/exnames.c | 7 | ||||
-rw-r--r-- | drivers/acpi/executer/exoparg1.c | 11 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsparse.c | 2 | ||||
-rw-r--r-- | drivers/acpi/parser/psparse.c | 109 | ||||
-rw-r--r-- | drivers/acpi/tables/tbxfroot.c | 6 | ||||
-rw-r--r-- | drivers/acpi/utilities/utmisc.c | 38 | ||||
-rw-r--r-- | include/acpi/acconfig.h | 2 | ||||
-rw-r--r-- | include/acpi/acstruct.h | 2 |
14 files changed, 198 insertions, 91 deletions
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 9fc3f4c033e..c9d9a6c45ae 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c | |||
@@ -139,7 +139,8 @@ acpi_ds_parse_method ( | |||
139 | 139 | ||
140 | walk_state = acpi_ds_create_walk_state (owner_id, NULL, NULL, NULL); | 140 | walk_state = acpi_ds_create_walk_state (owner_id, NULL, NULL, NULL); |
141 | if (!walk_state) { | 141 | if (!walk_state) { |
142 | return_ACPI_STATUS (AE_NO_MEMORY); | 142 | status = AE_NO_MEMORY; |
143 | goto cleanup; | ||
143 | } | 144 | } |
144 | 145 | ||
145 | status = acpi_ds_init_aml_walk (walk_state, op, node, | 146 | status = acpi_ds_init_aml_walk (walk_state, op, node, |
@@ -147,7 +148,7 @@ acpi_ds_parse_method ( | |||
147 | obj_desc->method.aml_length, NULL, 1); | 148 | obj_desc->method.aml_length, NULL, 1); |
148 | if (ACPI_FAILURE (status)) { | 149 | if (ACPI_FAILURE (status)) { |
149 | acpi_ds_delete_walk_state (walk_state); | 150 | acpi_ds_delete_walk_state (walk_state); |
150 | return_ACPI_STATUS (status); | 151 | goto cleanup; |
151 | } | 152 | } |
152 | 153 | ||
153 | /* | 154 | /* |
@@ -161,13 +162,14 @@ acpi_ds_parse_method ( | |||
161 | */ | 162 | */ |
162 | status = acpi_ps_parse_aml (walk_state); | 163 | status = acpi_ps_parse_aml (walk_state); |
163 | if (ACPI_FAILURE (status)) { | 164 | if (ACPI_FAILURE (status)) { |
164 | return_ACPI_STATUS (status); | 165 | goto cleanup; |
165 | } | 166 | } |
166 | 167 | ||
167 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, | 168 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, |
168 | "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n", | 169 | "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n", |
169 | acpi_ut_get_node_name (obj_handle), obj_handle, op)); | 170 | acpi_ut_get_node_name (obj_handle), obj_handle, op)); |
170 | 171 | ||
172 | cleanup: | ||
171 | acpi_ps_delete_parse_tree (op); | 173 | acpi_ps_delete_parse_tree (op); |
172 | return_ACPI_STATUS (status); | 174 | return_ACPI_STATUS (status); |
173 | } | 175 | } |
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index ba13bca28be..750bdb1ac34 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c | |||
@@ -119,14 +119,15 @@ acpi_ds_execute_arguments ( | |||
119 | 119 | ||
120 | walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); | 120 | walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); |
121 | if (!walk_state) { | 121 | if (!walk_state) { |
122 | return_ACPI_STATUS (AE_NO_MEMORY); | 122 | status = AE_NO_MEMORY; |
123 | goto cleanup; | ||
123 | } | 124 | } |
124 | 125 | ||
125 | status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start, | 126 | status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start, |
126 | aml_length, NULL, 1); | 127 | aml_length, NULL, 1); |
127 | if (ACPI_FAILURE (status)) { | 128 | if (ACPI_FAILURE (status)) { |
128 | acpi_ds_delete_walk_state (walk_state); | 129 | acpi_ds_delete_walk_state (walk_state); |
129 | return_ACPI_STATUS (status); | 130 | goto cleanup; |
130 | } | 131 | } |
131 | 132 | ||
132 | /* Mark this parse as a deferred opcode */ | 133 | /* Mark this parse as a deferred opcode */ |
@@ -138,8 +139,7 @@ acpi_ds_execute_arguments ( | |||
138 | 139 | ||
139 | status = acpi_ps_parse_aml (walk_state); | 140 | status = acpi_ps_parse_aml (walk_state); |
140 | if (ACPI_FAILURE (status)) { | 141 | if (ACPI_FAILURE (status)) { |
141 | acpi_ps_delete_parse_tree (op); | 142 | goto cleanup; |
142 | return_ACPI_STATUS (status); | ||
143 | } | 143 | } |
144 | 144 | ||
145 | /* Get and init the Op created above */ | 145 | /* Get and init the Op created above */ |
@@ -160,7 +160,8 @@ acpi_ds_execute_arguments ( | |||
160 | 160 | ||
161 | walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); | 161 | walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); |
162 | if (!walk_state) { | 162 | if (!walk_state) { |
163 | return_ACPI_STATUS (AE_NO_MEMORY); | 163 | status = AE_NO_MEMORY; |
164 | goto cleanup; | ||
164 | } | 165 | } |
165 | 166 | ||
166 | /* Execute the opcode and arguments */ | 167 | /* Execute the opcode and arguments */ |
@@ -169,13 +170,15 @@ acpi_ds_execute_arguments ( | |||
169 | aml_length, NULL, 3); | 170 | aml_length, NULL, 3); |
170 | if (ACPI_FAILURE (status)) { | 171 | if (ACPI_FAILURE (status)) { |
171 | acpi_ds_delete_walk_state (walk_state); | 172 | acpi_ds_delete_walk_state (walk_state); |
172 | return_ACPI_STATUS (status); | 173 | goto cleanup; |
173 | } | 174 | } |
174 | 175 | ||
175 | /* Mark this execution as a deferred opcode */ | 176 | /* Mark this execution as a deferred opcode */ |
176 | 177 | ||
177 | walk_state->deferred_node = node; | 178 | walk_state->deferred_node = node; |
178 | status = acpi_ps_parse_aml (walk_state); | 179 | status = acpi_ps_parse_aml (walk_state); |
180 | |||
181 | cleanup: | ||
179 | acpi_ps_delete_parse_tree (op); | 182 | acpi_ps_delete_parse_tree (op); |
180 | return_ACPI_STATUS (status); | 183 | return_ACPI_STATUS (status); |
181 | } | 184 | } |
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index 1ac197ccfc8..e2e0a855be2 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c | |||
@@ -145,15 +145,6 @@ acpi_ds_load1_begin_op ( | |||
145 | 145 | ||
146 | if (op) { | 146 | if (op) { |
147 | if (!(walk_state->op_info->flags & AML_NAMED)) { | 147 | if (!(walk_state->op_info->flags & AML_NAMED)) { |
148 | #if 0 | ||
149 | if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || | ||
150 | (walk_state->op_info->class == AML_CLASS_CONTROL)) { | ||
151 | acpi_os_printf ("\n\n***EXECUTABLE OPCODE %s***\n\n", | ||
152 | walk_state->op_info->name); | ||
153 | *out_op = op; | ||
154 | return (AE_CTRL_SKIP); | ||
155 | } | ||
156 | #endif | ||
157 | *out_op = op; | 148 | *out_op = op; |
158 | return (AE_OK); | 149 | return (AE_OK); |
159 | } | 150 | } |
@@ -486,6 +477,15 @@ acpi_ds_load2_begin_op ( | |||
486 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); | 477 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); |
487 | 478 | ||
488 | if (op) { | 479 | if (op) { |
480 | if ((walk_state->control_state) && | ||
481 | (walk_state->control_state->common.state == | ||
482 | ACPI_CONTROL_CONDITIONAL_EXECUTING)) { | ||
483 | /* We are executing a while loop outside of a method */ | ||
484 | |||
485 | status = acpi_ds_exec_begin_op (walk_state, out_op); | ||
486 | return_ACPI_STATUS (status); | ||
487 | } | ||
488 | |||
489 | /* We only care about Namespace opcodes here */ | 489 | /* We only care about Namespace opcodes here */ |
490 | 490 | ||
491 | if ((!(walk_state->op_info->flags & AML_NSOPCODE) && | 491 | if ((!(walk_state->op_info->flags & AML_NSOPCODE) && |
@@ -493,9 +493,14 @@ acpi_ds_load2_begin_op ( | |||
493 | (!(walk_state->op_info->flags & AML_NAMED))) { | 493 | (!(walk_state->op_info->flags & AML_NAMED))) { |
494 | if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || | 494 | if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || |
495 | (walk_state->op_info->class == AML_CLASS_CONTROL)) { | 495 | (walk_state->op_info->class == AML_CLASS_CONTROL)) { |
496 | ACPI_REPORT_WARNING (( | 496 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, |
497 | "Encountered executable code at module level, [%s]\n", | 497 | "Begin/EXEC: %s (fl %8.8X)\n", walk_state->op_info->name, |
498 | acpi_ps_get_opcode_name (walk_state->opcode))); | 498 | walk_state->op_info->flags)); |
499 | |||
500 | /* Executing a type1 or type2 opcode outside of a method */ | ||
501 | |||
502 | status = acpi_ds_exec_begin_op (walk_state, out_op); | ||
503 | return_ACPI_STATUS (status); | ||
499 | } | 504 | } |
500 | return_ACPI_STATUS (AE_OK); | 505 | return_ACPI_STATUS (AE_OK); |
501 | } | 506 | } |
@@ -657,8 +662,10 @@ acpi_ds_load2_begin_op ( | |||
657 | break; | 662 | break; |
658 | } | 663 | } |
659 | 664 | ||
665 | /* Add new entry into namespace */ | ||
666 | |||
660 | status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type, | 667 | status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type, |
661 | ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, | 668 | ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, |
662 | walk_state, &(node)); | 669 | walk_state, &(node)); |
663 | break; | 670 | break; |
664 | } | 671 | } |
@@ -668,7 +675,6 @@ acpi_ds_load2_begin_op ( | |||
668 | return_ACPI_STATUS (status); | 675 | return_ACPI_STATUS (status); |
669 | } | 676 | } |
670 | 677 | ||
671 | |||
672 | if (!op) { | 678 | if (!op) { |
673 | /* Create a new op */ | 679 | /* Create a new op */ |
674 | 680 | ||
@@ -682,9 +688,7 @@ acpi_ds_load2_begin_op ( | |||
682 | if (node) { | 688 | if (node) { |
683 | op->named.name = node->name.integer; | 689 | op->named.name = node->name.integer; |
684 | } | 690 | } |
685 | if (out_op) { | 691 | *out_op = op; |
686 | *out_op = op; | ||
687 | } | ||
688 | } | 692 | } |
689 | 693 | ||
690 | /* | 694 | /* |
@@ -731,9 +735,24 @@ acpi_ds_load2_end_op ( | |||
731 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n", | 735 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n", |
732 | walk_state->op_info->name, op, walk_state)); | 736 | walk_state->op_info->name, op, walk_state)); |
733 | 737 | ||
734 | /* Only interested in opcodes that have namespace objects */ | 738 | /* Check if opcode had an associated namespace object */ |
735 | 739 | ||
736 | if (!(walk_state->op_info->flags & AML_NSOBJECT)) { | 740 | if (!(walk_state->op_info->flags & AML_NSOBJECT)) { |
741 | #ifndef ACPI_NO_METHOD_EXECUTION | ||
742 | /* No namespace object. Executable opcode? */ | ||
743 | |||
744 | if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || | ||
745 | (walk_state->op_info->class == AML_CLASS_CONTROL)) { | ||
746 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, | ||
747 | "End/EXEC: %s (fl %8.8X)\n", walk_state->op_info->name, | ||
748 | walk_state->op_info->flags)); | ||
749 | |||
750 | /* Executing a type1 or type2 opcode outside of a method */ | ||
751 | |||
752 | status = acpi_ds_exec_end_op (walk_state); | ||
753 | return_ACPI_STATUS (status); | ||
754 | } | ||
755 | #endif | ||
737 | return_ACPI_STATUS (AE_OK); | 756 | return_ACPI_STATUS (AE_OK); |
738 | } | 757 | } |
739 | 758 | ||
@@ -742,7 +761,6 @@ acpi_ds_load2_end_op ( | |||
742 | "Ending scope Op=%p State=%p\n", op, walk_state)); | 761 | "Ending scope Op=%p State=%p\n", op, walk_state)); |
743 | } | 762 | } |
744 | 763 | ||
745 | |||
746 | object_type = walk_state->op_info->object_type; | 764 | object_type = walk_state->op_info->object_type; |
747 | 765 | ||
748 | /* | 766 | /* |
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c index 4ef0e85c677..cc45d52225d 100644 --- a/drivers/acpi/dispatcher/dswstate.c +++ b/drivers/acpi/dispatcher/dswstate.c | |||
@@ -762,6 +762,7 @@ acpi_ds_init_aml_walk ( | |||
762 | /* The next_op of the next_walk will be the beginning of the method */ | 762 | /* The next_op of the next_walk will be the beginning of the method */ |
763 | 763 | ||
764 | walk_state->next_op = NULL; | 764 | walk_state->next_op = NULL; |
765 | walk_state->pass_number = (u8) pass_number; | ||
765 | 766 | ||
766 | if (info) { | 767 | if (info) { |
767 | if (info->parameter_type == ACPI_PARAM_GPE) { | 768 | if (info->parameter_type == ACPI_PARAM_GPE) { |
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 734b2f24af4..8bfa6effaa0 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c | |||
@@ -376,16 +376,22 @@ acpi_ex_load_op ( | |||
376 | */ | 376 | */ |
377 | status = acpi_ex_read_data_from_field (walk_state, obj_desc, &buffer_desc); | 377 | status = acpi_ex_read_data_from_field (walk_state, obj_desc, &buffer_desc); |
378 | if (ACPI_FAILURE (status)) { | 378 | if (ACPI_FAILURE (status)) { |
379 | goto cleanup; | 379 | return_ACPI_STATUS (status); |
380 | } | 380 | } |
381 | 381 | ||
382 | table_ptr = ACPI_CAST_PTR (struct acpi_table_header, | 382 | table_ptr = ACPI_CAST_PTR (struct acpi_table_header, |
383 | buffer_desc->buffer.pointer); | 383 | buffer_desc->buffer.pointer); |
384 | 384 | ||
385 | /* Sanity check the table length */ | 385 | /* All done with the buffer_desc, delete it */ |
386 | |||
387 | buffer_desc->buffer.pointer = NULL; | ||
388 | acpi_ut_remove_reference (buffer_desc); | ||
389 | |||
390 | /* Sanity check the table length */ | ||
386 | 391 | ||
387 | if (table_ptr->length < sizeof (struct acpi_table_header)) { | 392 | if (table_ptr->length < sizeof (struct acpi_table_header)) { |
388 | return_ACPI_STATUS (AE_BAD_HEADER); | 393 | status = AE_BAD_HEADER; |
394 | goto cleanup; | ||
389 | } | 395 | } |
390 | break; | 396 | break; |
391 | 397 | ||
@@ -413,7 +419,9 @@ acpi_ex_load_op ( | |||
413 | 419 | ||
414 | status = acpi_ex_add_table (table_ptr, acpi_gbl_root_node, &ddb_handle); | 420 | status = acpi_ex_add_table (table_ptr, acpi_gbl_root_node, &ddb_handle); |
415 | if (ACPI_FAILURE (status)) { | 421 | if (ACPI_FAILURE (status)) { |
416 | goto cleanup; | 422 | /* On error, table_ptr was deallocated above */ |
423 | |||
424 | return_ACPI_STATUS (status); | ||
417 | } | 425 | } |
418 | 426 | ||
419 | /* Store the ddb_handle into the Target operand */ | 427 | /* Store the ddb_handle into the Target operand */ |
@@ -421,17 +429,14 @@ acpi_ex_load_op ( | |||
421 | status = acpi_ex_store (ddb_handle, target, walk_state); | 429 | status = acpi_ex_store (ddb_handle, target, walk_state); |
422 | if (ACPI_FAILURE (status)) { | 430 | if (ACPI_FAILURE (status)) { |
423 | (void) acpi_ex_unload_table (ddb_handle); | 431 | (void) acpi_ex_unload_table (ddb_handle); |
424 | } | ||
425 | 432 | ||
426 | return_ACPI_STATUS (status); | 433 | /* table_ptr was deallocated above */ |
427 | 434 | ||
435 | return_ACPI_STATUS (status); | ||
436 | } | ||
428 | 437 | ||
429 | cleanup: | 438 | cleanup: |
430 | 439 | if (ACPI_FAILURE (status)) { | |
431 | if (buffer_desc) { | ||
432 | acpi_ut_remove_reference (buffer_desc); | ||
433 | } | ||
434 | else { | ||
435 | ACPI_MEM_FREE (table_ptr); | 440 | ACPI_MEM_FREE (table_ptr); |
436 | } | 441 | } |
437 | return_ACPI_STATUS (status); | 442 | return_ACPI_STATUS (status); |
diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c index 22c8fa480f6..a690c925099 100644 --- a/drivers/acpi/executer/exfield.c +++ b/drivers/acpi/executer/exfield.c | |||
@@ -87,6 +87,9 @@ acpi_ex_read_data_from_field ( | |||
87 | if (!obj_desc) { | 87 | if (!obj_desc) { |
88 | return_ACPI_STATUS (AE_AML_NO_OPERAND); | 88 | return_ACPI_STATUS (AE_AML_NO_OPERAND); |
89 | } | 89 | } |
90 | if (!ret_buffer_desc) { | ||
91 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
92 | } | ||
90 | 93 | ||
91 | if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) { | 94 | if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) { |
92 | /* | 95 | /* |
@@ -182,7 +185,7 @@ exit: | |||
182 | if (ACPI_FAILURE (status)) { | 185 | if (ACPI_FAILURE (status)) { |
183 | acpi_ut_remove_reference (buffer_desc); | 186 | acpi_ut_remove_reference (buffer_desc); |
184 | } | 187 | } |
185 | else if (ret_buffer_desc) { | 188 | else { |
186 | *ret_buffer_desc = buffer_desc; | 189 | *ret_buffer_desc = buffer_desc; |
187 | } | 190 | } |
188 | 191 | ||
diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c index 639f0bd3f6d..b6ba1a7a677 100644 --- a/drivers/acpi/executer/exnames.c +++ b/drivers/acpi/executer/exnames.c | |||
@@ -438,6 +438,13 @@ acpi_ex_get_name_string ( | |||
438 | status = AE_AML_BAD_NAME; | 438 | status = AE_AML_BAD_NAME; |
439 | } | 439 | } |
440 | 440 | ||
441 | if (ACPI_FAILURE (status)) { | ||
442 | if (name_string) { | ||
443 | ACPI_MEM_FREE (name_string); | ||
444 | } | ||
445 | return_ACPI_STATUS (status); | ||
446 | } | ||
447 | |||
441 | *out_name_string = name_string; | 448 | *out_name_string = name_string; |
442 | *out_name_length = (u32) (aml_address - in_aml_address); | 449 | *out_name_length = (u32) (aml_address - in_aml_address); |
443 | 450 | ||
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c index dbdf8262ba0..ffc61ddeb65 100644 --- a/drivers/acpi/executer/exoparg1.c +++ b/drivers/acpi/executer/exoparg1.c | |||
@@ -127,15 +127,16 @@ acpi_ex_opcode_0A_0T_1R ( | |||
127 | 127 | ||
128 | cleanup: | 128 | cleanup: |
129 | 129 | ||
130 | if (!walk_state->result_obj) { | ||
131 | walk_state->result_obj = return_desc; | ||
132 | } | ||
133 | |||
134 | /* Delete return object on error */ | 130 | /* Delete return object on error */ |
135 | 131 | ||
136 | if (ACPI_FAILURE (status)) { | 132 | if ((ACPI_FAILURE (status)) || walk_state->result_obj) { |
137 | acpi_ut_remove_reference (return_desc); | 133 | acpi_ut_remove_reference (return_desc); |
138 | } | 134 | } |
135 | else { | ||
136 | /* Save the return value */ | ||
137 | |||
138 | walk_state->result_obj = return_desc; | ||
139 | } | ||
139 | 140 | ||
140 | return_ACPI_STATUS (status); | 141 | return_ACPI_STATUS (status); |
141 | } | 142 | } |
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c index a0e13e8d376..f81b836e77f 100644 --- a/drivers/acpi/namespace/nsparse.c +++ b/drivers/acpi/namespace/nsparse.c | |||
@@ -146,6 +146,7 @@ acpi_ns_parse_table ( | |||
146 | * to service the entire parse. The second pass of the parse then | 146 | * to service the entire parse. The second pass of the parse then |
147 | * performs another complete parse of the AML.. | 147 | * performs another complete parse of the AML.. |
148 | */ | 148 | */ |
149 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 1\n")); | ||
149 | status = acpi_ns_one_complete_parse (1, table_desc); | 150 | status = acpi_ns_one_complete_parse (1, table_desc); |
150 | if (ACPI_FAILURE (status)) { | 151 | if (ACPI_FAILURE (status)) { |
151 | return_ACPI_STATUS (status); | 152 | return_ACPI_STATUS (status); |
@@ -160,6 +161,7 @@ acpi_ns_parse_table ( | |||
160 | * overhead of this is compensated for by the fact that the | 161 | * overhead of this is compensated for by the fact that the |
161 | * parse objects are all cached. | 162 | * parse objects are all cached. |
162 | */ | 163 | */ |
164 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 2\n")); | ||
163 | status = acpi_ns_one_complete_parse (2, table_desc); | 165 | status = acpi_ns_one_complete_parse (2, table_desc); |
164 | if (ACPI_FAILURE (status)) { | 166 | if (ACPI_FAILURE (status)) { |
165 | return_ACPI_STATUS (status); | 167 | return_ACPI_STATUS (status); |
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index bbfdc1a58c2..bdbe0d99486 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c | |||
@@ -66,7 +66,7 @@ static u32 acpi_gbl_depth = 0; | |||
66 | 66 | ||
67 | /* Local prototypes */ | 67 | /* Local prototypes */ |
68 | 68 | ||
69 | static void | 69 | static acpi_status |
70 | acpi_ps_complete_this_op ( | 70 | acpi_ps_complete_this_op ( |
71 | struct acpi_walk_state *walk_state, | 71 | struct acpi_walk_state *walk_state, |
72 | union acpi_parse_object *op); | 72 | union acpi_parse_object *op); |
@@ -152,13 +152,13 @@ acpi_ps_peek_opcode ( | |||
152 | * PARAMETERS: walk_state - Current State | 152 | * PARAMETERS: walk_state - Current State |
153 | * Op - Op to complete | 153 | * Op - Op to complete |
154 | * | 154 | * |
155 | * RETURN: None. | 155 | * RETURN: Status |
156 | * | 156 | * |
157 | * DESCRIPTION: Perform any cleanup at the completion of an Op. | 157 | * DESCRIPTION: Perform any cleanup at the completion of an Op. |
158 | * | 158 | * |
159 | ******************************************************************************/ | 159 | ******************************************************************************/ |
160 | 160 | ||
161 | static void | 161 | static acpi_status |
162 | acpi_ps_complete_this_op ( | 162 | acpi_ps_complete_this_op ( |
163 | struct acpi_walk_state *walk_state, | 163 | struct acpi_walk_state *walk_state, |
164 | union acpi_parse_object *op) | 164 | union acpi_parse_object *op) |
@@ -175,19 +175,26 @@ acpi_ps_complete_this_op ( | |||
175 | /* Check for null Op, can happen if AML code is corrupt */ | 175 | /* Check for null Op, can happen if AML code is corrupt */ |
176 | 176 | ||
177 | if (!op) { | 177 | if (!op) { |
178 | return_VOID; | 178 | return_ACPI_STATUS (AE_OK); /* OK for now */ |
179 | } | 179 | } |
180 | 180 | ||
181 | /* Delete this op and the subtree below it if asked to */ | 181 | /* Delete this op and the subtree below it if asked to */ |
182 | 182 | ||
183 | if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) != ACPI_PARSE_DELETE_TREE) || | 183 | if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) != ACPI_PARSE_DELETE_TREE) || |
184 | (walk_state->op_info->class == AML_CLASS_ARGUMENT)) { | 184 | (walk_state->op_info->class == AML_CLASS_ARGUMENT)) { |
185 | return_VOID; | 185 | return_ACPI_STATUS (AE_OK); |
186 | } | 186 | } |
187 | 187 | ||
188 | /* Make sure that we only delete this subtree */ | 188 | /* Make sure that we only delete this subtree */ |
189 | 189 | ||
190 | if (op->common.parent) { | 190 | if (op->common.parent) { |
191 | prev = op->common.parent->common.value.arg; | ||
192 | if (!prev) { | ||
193 | /* Nothing more to do */ | ||
194 | |||
195 | goto cleanup; | ||
196 | } | ||
197 | |||
191 | /* | 198 | /* |
192 | * Check if we need to replace the operator and its subtree | 199 | * Check if we need to replace the operator and its subtree |
193 | * with a return value op (placeholder op) | 200 | * with a return value op (placeholder op) |
@@ -206,7 +213,7 @@ acpi_ps_complete_this_op ( | |||
206 | */ | 213 | */ |
207 | replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); | 214 | replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); |
208 | if (!replacement_op) { | 215 | if (!replacement_op) { |
209 | goto cleanup; | 216 | goto allocate_error; |
210 | } | 217 | } |
211 | break; | 218 | break; |
212 | 219 | ||
@@ -223,18 +230,17 @@ acpi_ps_complete_this_op ( | |||
223 | (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) { | 230 | (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) { |
224 | replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); | 231 | replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); |
225 | if (!replacement_op) { | 232 | if (!replacement_op) { |
226 | goto cleanup; | 233 | goto allocate_error; |
227 | } | 234 | } |
228 | } | 235 | } |
229 | 236 | else if ((op->common.parent->common.aml_opcode == AML_NAME_OP) && | |
230 | if ((op->common.parent->common.aml_opcode == AML_NAME_OP) && | 237 | (walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2)) { |
231 | (walk_state->descending_callback != acpi_ds_exec_begin_op)) { | ||
232 | if ((op->common.aml_opcode == AML_BUFFER_OP) || | 238 | if ((op->common.aml_opcode == AML_BUFFER_OP) || |
233 | (op->common.aml_opcode == AML_PACKAGE_OP) || | 239 | (op->common.aml_opcode == AML_PACKAGE_OP) || |
234 | (op->common.aml_opcode == AML_VAR_PACKAGE_OP)) { | 240 | (op->common.aml_opcode == AML_VAR_PACKAGE_OP)) { |
235 | replacement_op = acpi_ps_alloc_op (op->common.aml_opcode); | 241 | replacement_op = acpi_ps_alloc_op (op->common.aml_opcode); |
236 | if (!replacement_op) { | 242 | if (!replacement_op) { |
237 | goto cleanup; | 243 | goto allocate_error; |
238 | } | 244 | } |
239 | 245 | ||
240 | replacement_op->named.data = op->named.data; | 246 | replacement_op->named.data = op->named.data; |
@@ -244,15 +250,15 @@ acpi_ps_complete_this_op ( | |||
244 | break; | 250 | break; |
245 | 251 | ||
246 | default: | 252 | default: |
253 | |||
247 | replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); | 254 | replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); |
248 | if (!replacement_op) { | 255 | if (!replacement_op) { |
249 | goto cleanup; | 256 | goto allocate_error; |
250 | } | 257 | } |
251 | } | 258 | } |
252 | 259 | ||
253 | /* We must unlink this op from the parent tree */ | 260 | /* We must unlink this op from the parent tree */ |
254 | 261 | ||
255 | prev = op->common.parent->common.value.arg; | ||
256 | if (prev == op) { | 262 | if (prev == op) { |
257 | /* This op is the first in the list */ | 263 | /* This op is the first in the list */ |
258 | 264 | ||
@@ -298,7 +304,15 @@ cleanup: | |||
298 | /* Now we can actually delete the subtree rooted at Op */ | 304 | /* Now we can actually delete the subtree rooted at Op */ |
299 | 305 | ||
300 | acpi_ps_delete_parse_tree (op); | 306 | acpi_ps_delete_parse_tree (op); |
301 | return_VOID; | 307 | return_ACPI_STATUS (AE_OK); |
308 | |||
309 | |||
310 | allocate_error: | ||
311 | |||
312 | /* Always delete the subtree, even on error */ | ||
313 | |||
314 | acpi_ps_delete_parse_tree (op); | ||
315 | return_ACPI_STATUS (AE_NO_MEMORY); | ||
302 | } | 316 | } |
303 | 317 | ||
304 | 318 | ||
@@ -443,6 +457,7 @@ acpi_ps_parse_loop ( | |||
443 | struct acpi_walk_state *walk_state) | 457 | struct acpi_walk_state *walk_state) |
444 | { | 458 | { |
445 | acpi_status status = AE_OK; | 459 | acpi_status status = AE_OK; |
460 | acpi_status status2; | ||
446 | union acpi_parse_object *op = NULL; /* current op */ | 461 | union acpi_parse_object *op = NULL; /* current op */ |
447 | union acpi_parse_object *arg = NULL; | 462 | union acpi_parse_object *arg = NULL; |
448 | union acpi_parse_object *pre_op = NULL; | 463 | union acpi_parse_object *pre_op = NULL; |
@@ -744,7 +759,6 @@ acpi_ps_parse_loop ( | |||
744 | break; | 759 | break; |
745 | 760 | ||
746 | default: | 761 | default: |
747 | |||
748 | /* | 762 | /* |
749 | * Op is not a constant or string, append each argument | 763 | * Op is not a constant or string, append each argument |
750 | * to the Op | 764 | * to the Op |
@@ -770,6 +784,23 @@ acpi_ps_parse_loop ( | |||
770 | 784 | ||
771 | /* Special processing for certain opcodes */ | 785 | /* Special processing for certain opcodes */ |
772 | 786 | ||
787 | if (walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) { | ||
788 | switch (op->common.aml_opcode) { | ||
789 | case AML_IF_OP: | ||
790 | case AML_ELSE_OP: | ||
791 | case AML_WHILE_OP: | ||
792 | |||
793 | /* Skip body of if/else/while in pass 1 */ | ||
794 | |||
795 | parser_state->aml = parser_state->pkg_end; | ||
796 | walk_state->arg_count = 0; | ||
797 | break; | ||
798 | |||
799 | default: | ||
800 | break; | ||
801 | } | ||
802 | } | ||
803 | |||
773 | switch (op->common.aml_opcode) { | 804 | switch (op->common.aml_opcode) { |
774 | case AML_METHOD_OP: | 805 | case AML_METHOD_OP: |
775 | 806 | ||
@@ -796,7 +827,7 @@ acpi_ps_parse_loop ( | |||
796 | 827 | ||
797 | if ((op->common.parent) && | 828 | if ((op->common.parent) && |
798 | (op->common.parent->common.aml_opcode == AML_NAME_OP) && | 829 | (op->common.parent->common.aml_opcode == AML_NAME_OP) && |
799 | (walk_state->descending_callback != acpi_ds_exec_begin_op)) { | 830 | (walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2)) { |
800 | /* | 831 | /* |
801 | * Skip parsing of Buffers and Packages | 832 | * Skip parsing of Buffers and Packages |
802 | * because we don't have enough info in the first pass | 833 | * because we don't have enough info in the first pass |
@@ -900,15 +931,21 @@ close_this_op: | |||
900 | */ | 931 | */ |
901 | parser_state->scope->parse_scope.arg_count--; | 932 | parser_state->scope->parse_scope.arg_count--; |
902 | 933 | ||
903 | /* Close this Op (will result in parse subtree deletion) */ | 934 | /* Finished with pre_op */ |
904 | 935 | ||
905 | acpi_ps_complete_this_op (walk_state, op); | ||
906 | op = NULL; | ||
907 | if (pre_op) { | 936 | if (pre_op) { |
908 | acpi_ps_free_op (pre_op); | 937 | acpi_ps_free_op (pre_op); |
909 | pre_op = NULL; | 938 | pre_op = NULL; |
910 | } | 939 | } |
911 | 940 | ||
941 | /* Close this Op (will result in parse subtree deletion) */ | ||
942 | |||
943 | status2 = acpi_ps_complete_this_op (walk_state, op); | ||
944 | if (ACPI_FAILURE (status2)) { | ||
945 | return_ACPI_STATUS (status2); | ||
946 | } | ||
947 | op = NULL; | ||
948 | |||
912 | switch (status) { | 949 | switch (status) { |
913 | case AE_OK: | 950 | case AE_OK: |
914 | break; | 951 | break; |
@@ -936,7 +973,10 @@ close_this_op: | |||
936 | status = walk_state->ascending_callback (walk_state); | 973 | status = walk_state->ascending_callback (walk_state); |
937 | status = acpi_ps_next_parse_state (walk_state, op, status); | 974 | status = acpi_ps_next_parse_state (walk_state, op, status); |
938 | 975 | ||
939 | acpi_ps_complete_this_op (walk_state, op); | 976 | status2 = acpi_ps_complete_this_op (walk_state, op); |
977 | if (ACPI_FAILURE (status2)) { | ||
978 | return_ACPI_STATUS (status2); | ||
979 | } | ||
940 | op = NULL; | 980 | op = NULL; |
941 | } | 981 | } |
942 | status = AE_OK; | 982 | status = AE_OK; |
@@ -962,7 +1002,10 @@ close_this_op: | |||
962 | status = walk_state->ascending_callback (walk_state); | 1002 | status = walk_state->ascending_callback (walk_state); |
963 | status = acpi_ps_next_parse_state (walk_state, op, status); | 1003 | status = acpi_ps_next_parse_state (walk_state, op, status); |
964 | 1004 | ||
965 | acpi_ps_complete_this_op (walk_state, op); | 1005 | status2 = acpi_ps_complete_this_op (walk_state, op); |
1006 | if (ACPI_FAILURE (status2)) { | ||
1007 | return_ACPI_STATUS (status2); | ||
1008 | } | ||
966 | op = NULL; | 1009 | op = NULL; |
967 | 1010 | ||
968 | status = AE_OK; | 1011 | status = AE_OK; |
@@ -976,7 +1019,10 @@ close_this_op: | |||
976 | /* Clean up */ | 1019 | /* Clean up */ |
977 | do { | 1020 | do { |
978 | if (op) { | 1021 | if (op) { |
979 | acpi_ps_complete_this_op (walk_state, op); | 1022 | status2 = acpi_ps_complete_this_op (walk_state, op); |
1023 | if (ACPI_FAILURE (status2)) { | ||
1024 | return_ACPI_STATUS (status2); | ||
1025 | } | ||
980 | } | 1026 | } |
981 | acpi_ps_pop_scope (parser_state, &op, | 1027 | acpi_ps_pop_scope (parser_state, &op, |
982 | &walk_state->arg_types, &walk_state->arg_count); | 1028 | &walk_state->arg_types, &walk_state->arg_count); |
@@ -990,7 +1036,10 @@ close_this_op: | |||
990 | 1036 | ||
991 | do { | 1037 | do { |
992 | if (op) { | 1038 | if (op) { |
993 | acpi_ps_complete_this_op (walk_state, op); | 1039 | status2 = acpi_ps_complete_this_op (walk_state, op); |
1040 | if (ACPI_FAILURE (status2)) { | ||
1041 | return_ACPI_STATUS (status2); | ||
1042 | } | ||
994 | } | 1043 | } |
995 | acpi_ps_pop_scope (parser_state, &op, | 1044 | acpi_ps_pop_scope (parser_state, &op, |
996 | &walk_state->arg_types, &walk_state->arg_count); | 1045 | &walk_state->arg_types, &walk_state->arg_count); |
@@ -1053,7 +1102,10 @@ close_this_op: | |||
1053 | /* Clean up */ | 1102 | /* Clean up */ |
1054 | do { | 1103 | do { |
1055 | if (op) { | 1104 | if (op) { |
1056 | acpi_ps_complete_this_op (walk_state, op); | 1105 | status2 = acpi_ps_complete_this_op (walk_state, op); |
1106 | if (ACPI_FAILURE (status2)) { | ||
1107 | return_ACPI_STATUS (status2); | ||
1108 | } | ||
1057 | } | 1109 | } |
1058 | 1110 | ||
1059 | acpi_ps_pop_scope (parser_state, &op, | 1111 | acpi_ps_pop_scope (parser_state, &op, |
@@ -1065,12 +1117,17 @@ close_this_op: | |||
1065 | } | 1117 | } |
1066 | 1118 | ||
1067 | else if (ACPI_FAILURE (status)) { | 1119 | else if (ACPI_FAILURE (status)) { |
1068 | acpi_ps_complete_this_op (walk_state, op); | 1120 | /* First error is most important */ |
1121 | |||
1122 | (void) acpi_ps_complete_this_op (walk_state, op); | ||
1069 | return_ACPI_STATUS (status); | 1123 | return_ACPI_STATUS (status); |
1070 | } | 1124 | } |
1071 | } | 1125 | } |
1072 | 1126 | ||
1073 | acpi_ps_complete_this_op (walk_state, op); | 1127 | status2 = acpi_ps_complete_this_op (walk_state, op); |
1128 | if (ACPI_FAILURE (status2)) { | ||
1129 | return_ACPI_STATUS (status2); | ||
1130 | } | ||
1074 | } | 1131 | } |
1075 | 1132 | ||
1076 | acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, | 1133 | acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, |
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index dc3c3f6a9f6..198997aa7fb 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c | |||
@@ -331,8 +331,10 @@ acpi_get_firmware_table ( | |||
331 | 331 | ||
332 | 332 | ||
333 | cleanup: | 333 | cleanup: |
334 | acpi_os_unmap_memory (rsdt_info->pointer, | 334 | if (rsdt_info->pointer) { |
335 | (acpi_size) rsdt_info->pointer->length); | 335 | acpi_os_unmap_memory (rsdt_info->pointer, |
336 | (acpi_size) rsdt_info->pointer->length); | ||
337 | } | ||
336 | ACPI_MEM_FREE (rsdt_info); | 338 | ACPI_MEM_FREE (rsdt_info); |
337 | 339 | ||
338 | if (header) { | 340 | if (header) { |
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index f6de4ed3d52..bb658777fa8 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c | |||
@@ -787,7 +787,6 @@ acpi_ut_release_mutex ( | |||
787 | acpi_mutex_handle mutex_id) | 787 | acpi_mutex_handle mutex_id) |
788 | { | 788 | { |
789 | acpi_status status; | 789 | acpi_status status; |
790 | u32 i; | ||
791 | u32 this_thread_id; | 790 | u32 this_thread_id; |
792 | 791 | ||
793 | 792 | ||
@@ -814,25 +813,32 @@ acpi_ut_release_mutex ( | |||
814 | return (AE_NOT_ACQUIRED); | 813 | return (AE_NOT_ACQUIRED); |
815 | } | 814 | } |
816 | 815 | ||
817 | /* | 816 | #ifdef ACPI_MUTEX_DEBUG |
818 | * Deadlock prevention. Check if this thread owns any mutexes of value | 817 | { |
819 | * greater than this one. If so, the thread has violated the mutex | 818 | u32 i; |
820 | * ordering rule. This indicates a coding error somewhere in | 819 | /* |
821 | * the ACPI subsystem code. | 820 | * Mutex debug code, for internal debugging only. |
822 | */ | 821 | * |
823 | for (i = mutex_id; i < MAX_MUTEX; i++) { | 822 | * Deadlock prevention. Check if this thread owns any mutexes of value |
824 | if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { | 823 | * greater than this one. If so, the thread has violated the mutex |
825 | if (i == mutex_id) { | 824 | * ordering rule. This indicates a coding error somewhere in |
826 | continue; | 825 | * the ACPI subsystem code. |
827 | } | 826 | */ |
827 | for (i = mutex_id; i < MAX_MUTEX; i++) { | ||
828 | if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { | ||
829 | if (i == mutex_id) { | ||
830 | continue; | ||
831 | } | ||
828 | 832 | ||
829 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | 833 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, |
830 | "Invalid release order: owns [%s], releasing [%s]\n", | 834 | "Invalid release order: owns [%s], releasing [%s]\n", |
831 | acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id))); | 835 | acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id))); |
832 | 836 | ||
833 | return (AE_RELEASE_DEADLOCK); | 837 | return (AE_RELEASE_DEADLOCK); |
838 | } | ||
834 | } | 839 | } |
835 | } | 840 | } |
841 | #endif | ||
836 | 842 | ||
837 | /* Mark unlocked FIRST */ | 843 | /* Mark unlocked FIRST */ |
838 | 844 | ||
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index a268c4ae187..6babcb10493 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h | |||
@@ -64,7 +64,7 @@ | |||
64 | 64 | ||
65 | /* Version string */ | 65 | /* Version string */ |
66 | 66 | ||
67 | #define ACPI_CA_VERSION 0x20050513 | 67 | #define ACPI_CA_VERSION 0x20050526 |
68 | 68 | ||
69 | /* | 69 | /* |
70 | * OS name, used for the _OS object. The _OS object is essentially obsolete, | 70 | * OS name, used for the _OS object. The _OS object is essentially obsolete, |
diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h index e6b9e36a2ed..4e926457bd2 100644 --- a/include/acpi/acstruct.h +++ b/include/acpi/acstruct.h | |||
@@ -78,7 +78,7 @@ struct acpi_walk_state | |||
78 | u8 return_used; | 78 | u8 return_used; |
79 | u16 opcode; /* Current AML opcode */ | 79 | u16 opcode; /* Current AML opcode */ |
80 | u8 scope_depth; | 80 | u8 scope_depth; |
81 | u8 reserved1; | 81 | u8 pass_number; /* Parse pass during table load */ |
82 | u32 arg_count; /* push for fixed or var args */ | 82 | u32 arg_count; /* push for fixed or var args */ |
83 | u32 aml_offset; | 83 | u32 aml_offset; |
84 | u32 arg_types; | 84 | u32 arg_types; |