summaryrefslogtreecommitdiffstats
path: root/sys/contrib/dev/acpica/psparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/psparse.c')
-rw-r--r--sys/contrib/dev/acpica/psparse.c118
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;
OpenPOWER on IntegriCloud