diff options
Diffstat (limited to 'sys/contrib/dev/acpica/psparse.c')
-rw-r--r-- | sys/contrib/dev/acpica/psparse.c | 118 |
1 files changed, 71 insertions, 47 deletions
diff --git a/sys/contrib/dev/acpica/psparse.c b/sys/contrib/dev/acpica/psparse.c index a5d24ca..63c7cf1 100644 --- a/sys/contrib/dev/acpica/psparse.c +++ b/sys/contrib/dev/acpica/psparse.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psparse - Parser top level AML parse routines - * $Revision: 135 $ + * $Revision: 133 $ * *****************************************************************************/ @@ -580,8 +580,7 @@ AcpiPsParseLoop ( Status = AcpiPsNextParseState (WalkState, Op, Status); } - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); + AcpiPsPopScope (ParserState, &Op, &WalkState->ArgTypes, &WalkState->ArgCount); ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op)); } else if (WalkState->PrevOp) @@ -604,8 +603,7 @@ AcpiPsParseLoop ( { /* Get the next opcode from the AML stream */ - WalkState->AmlOffset = ACPI_PTR_DIFF (ParserState->Aml, - ParserState->AmlStart); + WalkState->AmlOffset = ACPI_PTR_DIFF (ParserState->Aml, ParserState->AmlStart); WalkState->Opcode = AcpiPsPeekOpcode (ParserState); /* @@ -665,8 +663,9 @@ AcpiPsParseLoop ( while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME)) { - Status = AcpiPsGetNextArg (WalkState, ParserState, - GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg); + Status = AcpiPsGetNextArg (ParserState, + GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), + &WalkState->ArgCount, &Arg); if (ACPI_FAILURE (Status)) { goto CloseThisOp; @@ -727,7 +726,7 @@ AcpiPsParseLoop ( * Defer final parsing of an OperationRegion body, * because we don't have enough info in the first pass * to parse it correctly (i.e., there may be method - * calls within the TermArg elements of the body.) + * calls within the TermArg elements of the body. * * However, we must continue parsing because * the opregion is not a standalone package -- @@ -816,15 +815,22 @@ AcpiPsParseLoop ( /* Fill in constant or string argument directly */ AcpiPsGetNextSimpleArg (ParserState, - GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), Op); + GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), Op); break; case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */ - Status = AcpiPsGetNextNamepath (WalkState, ParserState, Op, 1); + Status = AcpiPsGetNextNamepath (ParserState, Op, &WalkState->ArgCount, 1); if (ACPI_FAILURE (Status)) { - goto CloseThisOp; + /* NOT_FOUND is an error only if we are actually executing a method */ + + if ((((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) && + (Status == AE_NOT_FOUND)) || + (Status != AE_NOT_FOUND)) + { + goto CloseThisOp; + } } WalkState->ArgTypes = 0; @@ -835,16 +841,24 @@ AcpiPsParseLoop ( /* Op is not a constant or string, append each argument */ - while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && - !WalkState->ArgCount) + while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && !WalkState->ArgCount) { WalkState->AmlOffset = ACPI_PTR_DIFF (ParserState->Aml, ParserState->AmlStart); - Status = AcpiPsGetNextArg (WalkState, ParserState, - GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg); + Status = AcpiPsGetNextArg (ParserState, + GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), + &WalkState->ArgCount, &Arg); if (ACPI_FAILURE (Status)) { - goto CloseThisOp; + /* NOT_FOUND is an error only if we are actually executing a method */ + + if ((((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) && + (Status == AE_NOT_FOUND) && + (Op->Common.AmlOpcode != AML_COND_REF_OF_OP)) || + (Status != AE_NOT_FOUND)) + { + goto CloseThisOp; + } } if (Arg) @@ -922,8 +936,7 @@ AcpiPsParseLoop ( { /* There are arguments (complex ones), push Op and prepare for argument */ - Status = AcpiPsPushScope (ParserState, Op, - WalkState->ArgTypes, WalkState->ArgCount); + Status = AcpiPsPushScope (ParserState, Op, WalkState->ArgTypes, WalkState->ArgCount); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); @@ -1013,8 +1026,7 @@ CloseThisOp: case AE_CTRL_END: - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); + AcpiPsPopScope (ParserState, &Op, &WalkState->ArgTypes, &WalkState->ArgCount); if (Op) { @@ -1039,8 +1051,7 @@ CloseThisOp: while (!Op || (Op->Common.AmlOpcode != AML_WHILE_OP)) { - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); + AcpiPsPopScope (ParserState, &Op, &WalkState->ArgTypes, &WalkState->ArgCount); } /* Close this iteration of the While loop */ @@ -1070,8 +1081,7 @@ CloseThisOp: { AcpiPsCompleteThisOp (WalkState, Op); } - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); + AcpiPsPopScope (ParserState, &Op, &WalkState->ArgTypes, &WalkState->ArgCount); } while (Op); @@ -1086,8 +1096,7 @@ CloseThisOp: { AcpiPsCompleteThisOp (WalkState, Op); } - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); + AcpiPsPopScope (ParserState, &Op, &WalkState->ArgTypes, &WalkState->ArgCount); } while (Op); @@ -1098,8 +1107,7 @@ CloseThisOp: #if 0 if (Op == NULL) { - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); + AcpiPsPopScope (ParserState, &Op, &WalkState->ArgTypes, &WalkState->ArgCount); } #endif WalkState->PrevOp = Op; @@ -1111,8 +1119,7 @@ CloseThisOp: if (AcpiPsHasCompletedScope (ParserState)) { - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); + AcpiPsPopScope (ParserState, &Op, &WalkState->ArgTypes, &WalkState->ArgCount); ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op)); } else @@ -1160,8 +1167,7 @@ CloseThisOp: AcpiPsCompleteThisOp (WalkState, Op); } - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); + AcpiPsPopScope (ParserState, &Op, &WalkState->ArgTypes, &WalkState->ArgCount); } while (Op); @@ -1178,8 +1184,7 @@ CloseThisOp: AcpiPsCompleteThisOp (WalkState, Op); } - AcpiPsPopScope (ParserState, &Op, &WalkState->ArgTypes, - &WalkState->ArgCount); + AcpiPsPopScope (ParserState, &Op, &WalkState->ArgTypes, &WalkState->ArgCount); } while (Op); @@ -1212,6 +1217,9 @@ AcpiPsParseAml ( ACPI_THREAD_STATE *Thread; ACPI_THREAD_STATE *PrevWalkList = AcpiGbl_CurrentWalkList; ACPI_WALK_STATE *PreviousWalkState; + ACPI_OPERAND_OBJECT **CallerReturnDesc = WalkState->CallerReturnDesc; + ACPI_OPERAND_OBJECT *EffectiveReturnDesc = NULL; + ACPI_FUNCTION_TRACE ("PsParseAml"); @@ -1256,8 +1264,7 @@ AcpiPsParseAml ( } ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, - "Completed one call to walk loop, %s State=%p\n", - AcpiFormatException (Status), WalkState)); + "Completed one call to walk loop, State=%p\n", WalkState)); if (Status == AE_CTRL_TRANSFER) { @@ -1274,21 +1281,23 @@ AcpiPsParseAml ( WalkState = AcpiDsGetCurrentWalkState (Thread); continue; } + else if (Status == AE_CTRL_TERMINATE) { Status = AE_OK; } - else if (Status != AE_OK) - { - ACPI_REPORT_ERROR (("Method execution failed, %s\n", - AcpiFormatException (Status))); - ACPI_DUMP_PATHNAME (WalkState->MethodNode, "Method pathname: ", - ACPI_LV_ERROR, _COMPONENT); - } /* We are done with this walk, move on to the parent if any */ WalkState = AcpiDsPopWalkState (Thread); + /* Save the last effective return value */ + + if (CallerReturnDesc && WalkState->ReturnDesc) + { + AcpiUtRemoveReference (EffectiveReturnDesc); + EffectiveReturnDesc = WalkState->ReturnDesc; + AcpiUtAddReference (EffectiveReturnDesc); + } /* Reset the current scope to the beginning of scope stack */ @@ -1303,8 +1312,7 @@ AcpiPsParseAml ( TerminateStatus = AcpiDsTerminateControlMethod (WalkState); if (ACPI_FAILURE (TerminateStatus)) { - ACPI_REPORT_ERROR (( - "Could not terminate control method properly\n")); + ACPI_REPORT_ERROR (("Could not terminate control method properly\n")); /* Ignore error and continue */ } @@ -1331,8 +1339,7 @@ AcpiPsParseAml ( * If the method return value is not used by the parent, * The object is deleted */ - Status = AcpiDsRestartControlMethod (WalkState, - PreviousWalkState->ReturnDesc); + Status = AcpiDsRestartControlMethod (WalkState, PreviousWalkState->ReturnDesc); if (ACPI_SUCCESS (Status)) { WalkState->WalkType |= ACPI_WALK_METHOD_RESTART; @@ -1343,6 +1350,10 @@ AcpiPsParseAml ( /* On error, delete any return object */ AcpiUtRemoveReference (PreviousWalkState->ReturnDesc); + + ACPI_REPORT_ERROR (("Method execution failed, %s\n", AcpiFormatException (Status))); + ACPI_DUMP_PATHNAME (WalkState->MethodNode, "Method pathname: ", + ACPI_LV_ERROR, _COMPONENT); } } @@ -1352,8 +1363,20 @@ AcpiPsParseAml ( */ else if (PreviousWalkState->CallerReturnDesc) { + /* + * Some AML code expects return value w/o ReturnOp. + * Return the saved effective return value instead. + */ + + if (PreviousWalkState->ReturnDesc == NULL && EffectiveReturnDesc != NULL) + { + PreviousWalkState->ReturnDesc = EffectiveReturnDesc; + AcpiUtAddReference (PreviousWalkState->ReturnDesc); + } + *(PreviousWalkState->CallerReturnDesc) = PreviousWalkState->ReturnDesc; /* NULL if no return value */ } + else if (PreviousWalkState->ReturnDesc) { /* Caller doesn't want it, must delete it */ @@ -1366,6 +1389,7 @@ AcpiPsParseAml ( /* Normal exit */ + AcpiUtRemoveReference (EffectiveReturnDesc); AcpiExReleaseAllMutexes (Thread); AcpiUtDeleteGenericState (ACPI_CAST_PTR (ACPI_GENERIC_STATE, Thread)); AcpiGbl_CurrentWalkList = PrevWalkList; |