diff options
Diffstat (limited to 'source/components/namespace/nseval.c')
-rw-r--r-- | source/components/namespace/nseval.c | 71 |
1 files changed, 52 insertions, 19 deletions
diff --git a/source/components/namespace/nseval.c b/source/components/namespace/nseval.c index a4819947dae40..33a45c03a7e1e 100644 --- a/source/components/namespace/nseval.c +++ b/source/components/namespace/nseval.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2015, Intel Corp. + * Copyright (C) 2000 - 2016, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -418,7 +418,7 @@ AcpiNsExecModuleCodeList ( * * DESCRIPTION: Execute a control method containing a block of module-level * executable AML code. The control method is temporarily - * installed to a local copy of the root node, then evaluated. + * installed to the root node, then evaluated. * ******************************************************************************/ @@ -427,9 +427,10 @@ AcpiNsExecModuleCode ( ACPI_OPERAND_OBJECT *MethodObj, ACPI_EVALUATE_INFO *Info) { - ACPI_STATUS Status; - ACPI_NAMESPACE_NODE *TempNode; + ACPI_OPERAND_OBJECT *ParentObj; ACPI_NAMESPACE_NODE *ParentNode; + ACPI_OBJECT_TYPE Type; + ACPI_STATUS Status; ACPI_FUNCTION_TRACE (NsExecModuleCode); @@ -439,20 +440,23 @@ AcpiNsExecModuleCode ( * Get the parent node. We cheat by using the NextObject field * of the method object descriptor. */ - ParentNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, - MethodObj->Method.NextObject); + ParentNode = ACPI_CAST_PTR ( + ACPI_NAMESPACE_NODE, MethodObj->Method.NextObject); + Type = AcpiNsGetType (ParentNode); - /* Take a copy of the parent node to act as parent of this method */ - - TempNode = ACPI_ALLOCATE (sizeof (ACPI_NAMESPACE_NODE)); - if (!TempNode) + /* + * Get the region handler and save it in the method object. We may need + * this if an operation region declaration causes a _REG method to be run. + * + * We can't do this in AcpiPsLinkModuleCode because + * AcpiGbl_RootNode->Object is NULL at PASS1. + */ + if ((Type == ACPI_TYPE_DEVICE) && ParentNode->Object) { - return_VOID; + MethodObj->Method.Dispatch.Handler = + ParentNode->Object->Device.Handler; } - memcpy (TempNode, ParentNode, sizeof (ACPI_NAMESPACE_NODE)); - TempNode->Object = NULL; /* Clear the subobject */ - /* Must clear NextObject (AcpiNsAttachObject needs the field) */ MethodObj->Method.NextObject = NULL; @@ -460,14 +464,25 @@ AcpiNsExecModuleCode ( /* Initialize the evaluation information block */ memset (Info, 0, sizeof (ACPI_EVALUATE_INFO)); - Info->PrefixNode = TempNode; + Info->PrefixNode = ParentNode; + + /* + * Get the currently attached parent object. Add a reference, + * because the ref count will be decreased when the method object + * is installed to the parent node. + */ + ParentObj = AcpiNsGetAttachedObject (ParentNode); + if (ParentObj) + { + AcpiUtAddReference (ParentObj); + } /* Install the method (module-level code) in the parent node */ - Status = AcpiNsAttachObject (TempNode, MethodObj, ACPI_TYPE_METHOD); + Status = AcpiNsAttachObject (ParentNode, MethodObj, ACPI_TYPE_METHOD); if (ACPI_FAILURE (Status)) { - goto Cleanup; + goto Exit; } /* Execute the parent node as a control method */ @@ -485,7 +500,25 @@ AcpiNsExecModuleCode ( AcpiUtRemoveReference (Info->ReturnObject); } -Cleanup: - ACPI_FREE (TempNode); + /* Detach the temporary method object */ + + AcpiNsDetachObject (ParentNode); + + /* Restore the original parent object */ + + if (ParentObj) + { + Status = AcpiNsAttachObject (ParentNode, ParentObj, Type); + } + else + { + ParentNode->Type = (UINT8) Type; + } + +Exit: + if (ParentObj) + { + AcpiUtRemoveReference (ParentObj); + } return_VOID; } |