diff options
Diffstat (limited to 'drivers/acpi/parser/psparse.c')
-rw-r--r-- | drivers/acpi/parser/psparse.c | 144 |
1 files changed, 91 insertions, 53 deletions
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index e79edb53cb3b..bbfdc1a58c27 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c | |||
@@ -64,6 +64,23 @@ | |||
64 | 64 | ||
65 | static u32 acpi_gbl_depth = 0; | 65 | static u32 acpi_gbl_depth = 0; |
66 | 66 | ||
67 | /* Local prototypes */ | ||
68 | |||
69 | static void | ||
70 | acpi_ps_complete_this_op ( | ||
71 | struct acpi_walk_state *walk_state, | ||
72 | union acpi_parse_object *op); | ||
73 | |||
74 | static acpi_status | ||
75 | acpi_ps_next_parse_state ( | ||
76 | struct acpi_walk_state *walk_state, | ||
77 | union acpi_parse_object *op, | ||
78 | acpi_status callback_status); | ||
79 | |||
80 | static acpi_status | ||
81 | acpi_ps_parse_loop ( | ||
82 | struct acpi_walk_state *walk_state); | ||
83 | |||
67 | 84 | ||
68 | /******************************************************************************* | 85 | /******************************************************************************* |
69 | * | 86 | * |
@@ -100,7 +117,7 @@ acpi_ps_get_opcode_size ( | |||
100 | * | 117 | * |
101 | * PARAMETERS: parser_state - A parser state object | 118 | * PARAMETERS: parser_state - A parser state object |
102 | * | 119 | * |
103 | * RETURN: Status | 120 | * RETURN: Next AML opcode |
104 | * | 121 | * |
105 | * DESCRIPTION: Get next AML opcode (without incrementing AML pointer) | 122 | * DESCRIPTION: Get next AML opcode (without incrementing AML pointer) |
106 | * | 123 | * |
@@ -117,7 +134,6 @@ acpi_ps_peek_opcode ( | |||
117 | aml = parser_state->aml; | 134 | aml = parser_state->aml; |
118 | opcode = (u16) ACPI_GET8 (aml); | 135 | opcode = (u16) ACPI_GET8 (aml); |
119 | 136 | ||
120 | |||
121 | if (opcode == AML_EXTOP) { | 137 | if (opcode == AML_EXTOP) { |
122 | /* Extended opcode */ | 138 | /* Extended opcode */ |
123 | 139 | ||
@@ -142,7 +158,7 @@ acpi_ps_peek_opcode ( | |||
142 | * | 158 | * |
143 | ******************************************************************************/ | 159 | ******************************************************************************/ |
144 | 160 | ||
145 | void | 161 | static void |
146 | acpi_ps_complete_this_op ( | 162 | acpi_ps_complete_this_op ( |
147 | struct acpi_walk_state *walk_state, | 163 | struct acpi_walk_state *walk_state, |
148 | union acpi_parse_object *op) | 164 | union acpi_parse_object *op) |
@@ -272,7 +288,6 @@ acpi_ps_complete_this_op ( | |||
272 | next = NULL; | 288 | next = NULL; |
273 | } | 289 | } |
274 | } | 290 | } |
275 | |||
276 | prev = next; | 291 | prev = next; |
277 | } | 292 | } |
278 | } | 293 | } |
@@ -280,7 +295,7 @@ acpi_ps_complete_this_op ( | |||
280 | 295 | ||
281 | cleanup: | 296 | cleanup: |
282 | 297 | ||
283 | /* Now we can actually delete the subtree rooted at op */ | 298 | /* Now we can actually delete the subtree rooted at Op */ |
284 | 299 | ||
285 | acpi_ps_delete_parse_tree (op); | 300 | acpi_ps_delete_parse_tree (op); |
286 | return_VOID; | 301 | return_VOID; |
@@ -291,7 +306,9 @@ cleanup: | |||
291 | * | 306 | * |
292 | * FUNCTION: acpi_ps_next_parse_state | 307 | * FUNCTION: acpi_ps_next_parse_state |
293 | * | 308 | * |
294 | * PARAMETERS: parser_state - Current parser state object | 309 | * PARAMETERS: walk_state - Current state |
310 | * Op - Current parse op | ||
311 | * callback_status - Status from previous operation | ||
295 | * | 312 | * |
296 | * RETURN: Status | 313 | * RETURN: Status |
297 | * | 314 | * |
@@ -300,7 +317,7 @@ cleanup: | |||
300 | * | 317 | * |
301 | ******************************************************************************/ | 318 | ******************************************************************************/ |
302 | 319 | ||
303 | acpi_status | 320 | static acpi_status |
304 | acpi_ps_next_parse_state ( | 321 | acpi_ps_next_parse_state ( |
305 | struct acpi_walk_state *walk_state, | 322 | struct acpi_walk_state *walk_state, |
306 | union acpi_parse_object *op, | 323 | union acpi_parse_object *op, |
@@ -382,9 +399,8 @@ acpi_ps_next_parse_state ( | |||
382 | 399 | ||
383 | case AE_CTRL_TRANSFER: | 400 | case AE_CTRL_TRANSFER: |
384 | 401 | ||
385 | /* | 402 | /* A method call (invocation) -- transfer control */ |
386 | * A method call (invocation) -- transfer control | 403 | |
387 | */ | ||
388 | status = AE_CTRL_TRANSFER; | 404 | status = AE_CTRL_TRANSFER; |
389 | walk_state->prev_op = op; | 405 | walk_state->prev_op = op; |
390 | walk_state->method_call_op = op; | 406 | walk_state->method_call_op = op; |
@@ -397,6 +413,7 @@ acpi_ps_next_parse_state ( | |||
397 | 413 | ||
398 | 414 | ||
399 | default: | 415 | default: |
416 | |||
400 | status = callback_status; | 417 | status = callback_status; |
401 | if ((callback_status & AE_CODE_MASK) == AE_CODE_CONTROL) { | 418 | if ((callback_status & AE_CODE_MASK) == AE_CODE_CONTROL) { |
402 | status = AE_OK; | 419 | status = AE_OK; |
@@ -412,7 +429,7 @@ acpi_ps_next_parse_state ( | |||
412 | * | 429 | * |
413 | * FUNCTION: acpi_ps_parse_loop | 430 | * FUNCTION: acpi_ps_parse_loop |
414 | * | 431 | * |
415 | * PARAMETERS: parser_state - Current parser state object | 432 | * PARAMETERS: walk_state - Current state |
416 | * | 433 | * |
417 | * RETURN: Status | 434 | * RETURN: Status |
418 | * | 435 | * |
@@ -421,7 +438,7 @@ acpi_ps_next_parse_state ( | |||
421 | * | 438 | * |
422 | ******************************************************************************/ | 439 | ******************************************************************************/ |
423 | 440 | ||
424 | acpi_status | 441 | static acpi_status |
425 | acpi_ps_parse_loop ( | 442 | acpi_ps_parse_loop ( |
426 | struct acpi_walk_state *walk_state) | 443 | struct acpi_walk_state *walk_state) |
427 | { | 444 | { |
@@ -443,6 +460,7 @@ acpi_ps_parse_loop ( | |||
443 | walk_state->arg_types = 0; | 460 | walk_state->arg_types = 0; |
444 | 461 | ||
445 | #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) | 462 | #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) |
463 | |||
446 | if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) { | 464 | if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) { |
447 | /* We are restarting a preempted control method */ | 465 | /* We are restarting a preempted control method */ |
448 | 466 | ||
@@ -471,7 +489,8 @@ acpi_ps_parse_loop ( | |||
471 | acpi_format_exception (status))); | 489 | acpi_format_exception (status))); |
472 | 490 | ||
473 | } | 491 | } |
474 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "get_predicate Failed, %s\n", | 492 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, |
493 | "get_predicate Failed, %s\n", | ||
475 | acpi_format_exception (status))); | 494 | acpi_format_exception (status))); |
476 | return_ACPI_STATUS (status); | 495 | return_ACPI_STATUS (status); |
477 | } | 496 | } |
@@ -492,16 +511,15 @@ acpi_ps_parse_loop ( | |||
492 | } | 511 | } |
493 | #endif | 512 | #endif |
494 | 513 | ||
495 | /* | 514 | /* Iterative parsing loop, while there is more AML to process: */ |
496 | * Iterative parsing loop, while there is more aml to process: | 515 | |
497 | */ | ||
498 | while ((parser_state->aml < parser_state->aml_end) || (op)) { | 516 | while ((parser_state->aml < parser_state->aml_end) || (op)) { |
499 | aml_op_start = parser_state->aml; | 517 | aml_op_start = parser_state->aml; |
500 | if (!op) { | 518 | if (!op) { |
501 | /* Get the next opcode from the AML stream */ | 519 | /* Get the next opcode from the AML stream */ |
502 | 520 | ||
503 | walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml, | 521 | walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml, |
504 | parser_state->aml_start); | 522 | parser_state->aml_start); |
505 | walk_state->opcode = acpi_ps_peek_opcode (parser_state); | 523 | walk_state->opcode = acpi_ps_peek_opcode (parser_state); |
506 | 524 | ||
507 | /* | 525 | /* |
@@ -578,8 +596,10 @@ acpi_ps_parse_loop ( | |||
578 | INCREMENT_ARG_LIST (walk_state->arg_types); | 596 | INCREMENT_ARG_LIST (walk_state->arg_types); |
579 | } | 597 | } |
580 | 598 | ||
581 | /* Make sure that we found a NAME and didn't run out of arguments */ | 599 | /* |
582 | 600 | * Make sure that we found a NAME and didn't run out of | |
601 | * arguments | ||
602 | */ | ||
583 | if (!GET_CURRENT_ARG_TYPE (walk_state->arg_types)) { | 603 | if (!GET_CURRENT_ARG_TYPE (walk_state->arg_types)) { |
584 | status = AE_AML_NO_OPERAND; | 604 | status = AE_AML_NO_OPERAND; |
585 | goto close_this_op; | 605 | goto close_this_op; |
@@ -597,12 +617,13 @@ acpi_ps_parse_loop ( | |||
597 | 617 | ||
598 | status = walk_state->descending_callback (walk_state, &op); | 618 | status = walk_state->descending_callback (walk_state, &op); |
599 | if (ACPI_FAILURE (status)) { | 619 | if (ACPI_FAILURE (status)) { |
600 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "During name lookup/catalog, %s\n", | 620 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, |
601 | acpi_format_exception (status))); | 621 | "During name lookup/catalog, %s\n", |
622 | acpi_format_exception (status))); | ||
602 | goto close_this_op; | 623 | goto close_this_op; |
603 | } | 624 | } |
604 | 625 | ||
605 | if (op == NULL) { | 626 | if (!op) { |
606 | continue; | 627 | continue; |
607 | } | 628 | } |
608 | 629 | ||
@@ -659,7 +680,7 @@ acpi_ps_parse_loop ( | |||
659 | 680 | ||
660 | if ((walk_state->descending_callback != NULL)) { | 681 | if ((walk_state->descending_callback != NULL)) { |
661 | /* | 682 | /* |
662 | * Find the object. This will either insert the object into | 683 | * Find the object. This will either insert the object into |
663 | * the namespace or simply look it up | 684 | * the namespace or simply look it up |
664 | */ | 685 | */ |
665 | walk_state->op = op; | 686 | walk_state->op = op; |
@@ -688,11 +709,15 @@ acpi_ps_parse_loop ( | |||
688 | } | 709 | } |
689 | 710 | ||
690 | 711 | ||
691 | /* Start arg_count at zero because we don't know if there are any args yet */ | 712 | /* |
692 | 713 | * Start arg_count at zero because we don't know if there are | |
714 | * any args yet | ||
715 | */ | ||
693 | walk_state->arg_count = 0; | 716 | walk_state->arg_count = 0; |
694 | 717 | ||
695 | if (walk_state->arg_types) /* Are there any arguments that must be processed? */ { | 718 | /* Are there any arguments that must be processed? */ |
719 | |||
720 | if (walk_state->arg_types) { | ||
696 | /* Get arguments */ | 721 | /* Get arguments */ |
697 | 722 | ||
698 | switch (op->common.aml_opcode) { | 723 | switch (op->common.aml_opcode) { |
@@ -720,14 +745,18 @@ acpi_ps_parse_loop ( | |||
720 | 745 | ||
721 | default: | 746 | default: |
722 | 747 | ||
723 | /* Op is not a constant or string, append each argument to the Op */ | 748 | /* |
724 | 749 | * Op is not a constant or string, append each argument | |
750 | * to the Op | ||
751 | */ | ||
725 | while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) && | 752 | while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) && |
726 | !walk_state->arg_count) { | 753 | !walk_state->arg_count) { |
727 | walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml, | 754 | walk_state->aml_offset = (u32) |
728 | parser_state->aml_start); | 755 | ACPI_PTR_DIFF (parser_state->aml, parser_state->aml_start); |
756 | |||
729 | status = acpi_ps_get_next_arg (walk_state, parser_state, | 757 | status = acpi_ps_get_next_arg (walk_state, parser_state, |
730 | GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg); | 758 | GET_CURRENT_ARG_TYPE (walk_state->arg_types), |
759 | &arg); | ||
731 | if (ACPI_FAILURE (status)) { | 760 | if (ACPI_FAILURE (status)) { |
732 | goto close_this_op; | 761 | goto close_this_op; |
733 | } | 762 | } |
@@ -752,7 +781,8 @@ acpi_ps_parse_loop ( | |||
752 | * Save the length and address of the body | 781 | * Save the length and address of the body |
753 | */ | 782 | */ |
754 | op->named.data = parser_state->aml; | 783 | op->named.data = parser_state->aml; |
755 | op->named.length = (u32) (parser_state->pkg_end - parser_state->aml); | 784 | op->named.length = (u32) (parser_state->pkg_end - |
785 | parser_state->aml); | ||
756 | 786 | ||
757 | /* Skip body of method */ | 787 | /* Skip body of method */ |
758 | 788 | ||
@@ -773,7 +803,8 @@ acpi_ps_parse_loop ( | |||
773 | * to parse them correctly. | 803 | * to parse them correctly. |
774 | */ | 804 | */ |
775 | op->named.data = aml_op_start; | 805 | op->named.data = aml_op_start; |
776 | op->named.length = (u32) (parser_state->pkg_end - aml_op_start); | 806 | op->named.length = (u32) (parser_state->pkg_end - |
807 | aml_op_start); | ||
777 | 808 | ||
778 | /* Skip body */ | 809 | /* Skip body */ |
779 | 810 | ||
@@ -785,7 +816,8 @@ acpi_ps_parse_loop ( | |||
785 | case AML_WHILE_OP: | 816 | case AML_WHILE_OP: |
786 | 817 | ||
787 | if (walk_state->control_state) { | 818 | if (walk_state->control_state) { |
788 | walk_state->control_state->control.package_end = parser_state->pkg_end; | 819 | walk_state->control_state->control.package_end = |
820 | parser_state->pkg_end; | ||
789 | } | 821 | } |
790 | break; | 822 | break; |
791 | 823 | ||
@@ -801,8 +833,10 @@ acpi_ps_parse_loop ( | |||
801 | /* Check for arguments that need to be processed */ | 833 | /* Check for arguments that need to be processed */ |
802 | 834 | ||
803 | if (walk_state->arg_count) { | 835 | if (walk_state->arg_count) { |
804 | /* There are arguments (complex ones), push Op and prepare for argument */ | 836 | /* |
805 | 837 | * There are arguments (complex ones), push Op and | |
838 | * prepare for argument | ||
839 | */ | ||
806 | status = acpi_ps_push_scope (parser_state, op, | 840 | status = acpi_ps_push_scope (parser_state, op, |
807 | walk_state->arg_types, walk_state->arg_count); | 841 | walk_state->arg_types, walk_state->arg_count); |
808 | if (ACPI_FAILURE (status)) { | 842 | if (ACPI_FAILURE (status)) { |
@@ -812,8 +846,10 @@ acpi_ps_parse_loop ( | |||
812 | continue; | 846 | continue; |
813 | } | 847 | } |
814 | 848 | ||
815 | /* All arguments have been processed -- Op is complete, prepare for next */ | 849 | /* |
816 | 850 | * All arguments have been processed -- Op is complete, | |
851 | * prepare for next | ||
852 | */ | ||
817 | walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); | 853 | walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); |
818 | if (walk_state->op_info->flags & AML_NAMED) { | 854 | if (walk_state->op_info->flags & AML_NAMED) { |
819 | if (acpi_gbl_depth) { | 855 | if (acpi_gbl_depth) { |
@@ -880,9 +916,8 @@ close_this_op: | |||
880 | 916 | ||
881 | case AE_CTRL_TRANSFER: | 917 | case AE_CTRL_TRANSFER: |
882 | 918 | ||
883 | /* | 919 | /* We are about to transfer to a called method. */ |
884 | * We are about to transfer to a called method. | 920 | |
885 | */ | ||
886 | walk_state->prev_op = op; | 921 | walk_state->prev_op = op; |
887 | walk_state->prev_arg_types = walk_state->arg_types; | 922 | walk_state->prev_arg_types = walk_state->arg_types; |
888 | return_ACPI_STATUS (status); | 923 | return_ACPI_STATUS (status); |
@@ -1051,10 +1086,7 @@ close_this_op: | |||
1051 | * | 1086 | * |
1052 | * FUNCTION: acpi_ps_parse_aml | 1087 | * FUNCTION: acpi_ps_parse_aml |
1053 | * | 1088 | * |
1054 | * PARAMETERS: start_scope - The starting point of the parse. Becomes the | 1089 | * PARAMETERS: walk_state - Current state |
1055 | * root of the parsed op tree. | ||
1056 | * Aml - Pointer to the raw AML code to parse | ||
1057 | * aml_size - Length of the AML to parse | ||
1058 | * | 1090 | * |
1059 | * | 1091 | * |
1060 | * RETURN: Status | 1092 | * RETURN: Status |
@@ -1076,8 +1108,10 @@ acpi_ps_parse_aml ( | |||
1076 | 1108 | ||
1077 | ACPI_FUNCTION_TRACE ("ps_parse_aml"); | 1109 | ACPI_FUNCTION_TRACE ("ps_parse_aml"); |
1078 | 1110 | ||
1079 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Entered with walk_state=%p Aml=%p size=%X\n", | 1111 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, |
1080 | walk_state, walk_state->parser_state.aml, walk_state->parser_state.aml_size)); | 1112 | "Entered with walk_state=%p Aml=%p size=%X\n", |
1113 | walk_state, walk_state->parser_state.aml, | ||
1114 | walk_state->parser_state.aml_size)); | ||
1081 | 1115 | ||
1082 | 1116 | ||
1083 | /* Create and initialize a new thread state */ | 1117 | /* Create and initialize a new thread state */ |
@@ -1142,9 +1176,10 @@ acpi_ps_parse_aml ( | |||
1142 | if ((status == AE_ALREADY_EXISTS) && | 1176 | if ((status == AE_ALREADY_EXISTS) && |
1143 | (!walk_state->method_desc->method.semaphore)) { | 1177 | (!walk_state->method_desc->method.semaphore)) { |
1144 | /* | 1178 | /* |
1145 | * This method is marked not_serialized, but it tried to create a named | 1179 | * This method is marked not_serialized, but it tried to create |
1146 | * object, causing the second thread entrance to fail. We will workaround | 1180 | * a named object, causing the second thread entrance to fail. |
1147 | * this by marking the method permanently as Serialized. | 1181 | * We will workaround this by marking the method permanently |
1182 | * as Serialized. | ||
1148 | */ | 1183 | */ |
1149 | walk_state->method_desc->method.method_flags |= AML_METHOD_SERIALIZED; | 1184 | walk_state->method_desc->method.method_flags |= AML_METHOD_SERIALIZED; |
1150 | walk_state->method_desc->method.concurrency = 1; | 1185 | walk_state->method_desc->method.concurrency = 1; |
@@ -1187,7 +1222,8 @@ acpi_ps_parse_aml ( | |||
1187 | 1222 | ||
1188 | previous_walk_state = walk_state; | 1223 | previous_walk_state = walk_state; |
1189 | 1224 | ||
1190 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "return_value=%p, implicit_value=%p State=%p\n", | 1225 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, |
1226 | "return_value=%p, implicit_value=%p State=%p\n", | ||
1191 | walk_state->return_desc, walk_state->implicit_return_obj, walk_state)); | 1227 | walk_state->return_desc, walk_state->implicit_return_obj, walk_state)); |
1192 | 1228 | ||
1193 | /* Check if we have restarted a preempted walk */ | 1229 | /* Check if we have restarted a preempted walk */ |
@@ -1231,12 +1267,14 @@ acpi_ps_parse_aml ( | |||
1231 | */ | 1267 | */ |
1232 | else if (previous_walk_state->caller_return_desc) { | 1268 | else if (previous_walk_state->caller_return_desc) { |
1233 | if (previous_walk_state->implicit_return_obj) { | 1269 | if (previous_walk_state->implicit_return_obj) { |
1234 | *(previous_walk_state->caller_return_desc) = previous_walk_state->implicit_return_obj; | 1270 | *(previous_walk_state->caller_return_desc) = |
1271 | previous_walk_state->implicit_return_obj; | ||
1235 | } | 1272 | } |
1236 | else { | 1273 | else { |
1237 | /* NULL if no return value */ | 1274 | /* NULL if no return value */ |
1238 | 1275 | ||
1239 | *(previous_walk_state->caller_return_desc) = previous_walk_state->return_desc; | 1276 | *(previous_walk_state->caller_return_desc) = |
1277 | previous_walk_state->return_desc; | ||
1240 | } | 1278 | } |
1241 | } | 1279 | } |
1242 | else { | 1280 | else { |