aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c8
-rw-r--r--drivers/acpi/dispatcher/dsopcode.c15
-rw-r--r--drivers/acpi/dispatcher/dswload.c56
-rw-r--r--drivers/acpi/dispatcher/dswstate.c1
-rw-r--r--drivers/acpi/executer/exconfig.c27
-rw-r--r--drivers/acpi/executer/exfield.c5
-rw-r--r--drivers/acpi/executer/exnames.c7
-rw-r--r--drivers/acpi/executer/exoparg1.c11
-rw-r--r--drivers/acpi/namespace/nsparse.c2
-rw-r--r--drivers/acpi/parser/psparse.c109
-rw-r--r--drivers/acpi/tables/tbxfroot.c6
-rw-r--r--drivers/acpi/utilities/utmisc.c38
-rw-r--r--include/acpi/acconfig.h2
-rw-r--r--include/acpi/acstruct.h2
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
172cleanup:
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
181cleanup:
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
429cleanup: 438cleanup:
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
128cleanup: 128cleanup:
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
69static void 69static acpi_status
70acpi_ps_complete_this_op ( 70acpi_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
161static void 161static acpi_status
162acpi_ps_complete_this_op ( 162acpi_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
310allocate_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
333cleanup: 333cleanup:
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;