diff options
Diffstat (limited to 'sys/contrib/dev/acpica/excreate.c')
-rw-r--r-- | sys/contrib/dev/acpica/excreate.c | 67 |
1 files changed, 53 insertions, 14 deletions
diff --git a/sys/contrib/dev/acpica/excreate.c b/sys/contrib/dev/acpica/excreate.c index ce2f25e74b86..332f3b55dd60 100644 --- a/sys/contrib/dev/acpica/excreate.c +++ b/sys/contrib/dev/acpica/excreate.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: excreate - Named object creation - * $Revision: 93 $ + * $Revision: 94 $ * *****************************************************************************/ @@ -146,7 +146,8 @@ ACPI_STATUS AcpiExCreateAlias ( ACPI_WALK_STATE *WalkState) { - ACPI_NAMESPACE_NODE *SourceNode; + ACPI_NAMESPACE_NODE *TargetNode; + ACPI_NAMESPACE_NODE *AliasNode; ACPI_STATUS Status; @@ -155,25 +156,63 @@ AcpiExCreateAlias ( /* Get the source/alias operands (both namespace nodes) */ - SourceNode = (ACPI_NAMESPACE_NODE *) WalkState->Operands[1]; + AliasNode = (ACPI_NAMESPACE_NODE *) WalkState->Operands[0]; + TargetNode = (ACPI_NAMESPACE_NODE *) WalkState->Operands[1]; - - /* Attach the original source object to the new Alias Node */ - - Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) WalkState->Operands[0], - AcpiNsGetAttachedObject (SourceNode), - SourceNode->Type); + if (TargetNode->Type == INTERNAL_TYPE_ALIAS) + { + /* + * Dereference an existing alias so that we don't create a chain + * of aliases. With this code, we guarantee that an alias is + * always exactly one level of indirection away from the + * actual aliased name. + */ + TargetNode = (ACPI_NAMESPACE_NODE *) TargetNode->Object; + } /* - * The new alias assumes the type of the source, but it points - * to the same object. The reference count of the object has an - * additional reference to prevent deletion out from under either the - * source or the alias Node + * For objects that can never change (i.e., the NS node will + * permanently point to the same object), we can simply attach + * the object to the new NS node. For other objects (such as + * Integers, buffers, etc.), we have to point the Alias node + * to the original Node. */ + switch (TargetNode->Type) + { + case ACPI_TYPE_INTEGER: + case ACPI_TYPE_STRING: + case ACPI_TYPE_BUFFER: + case ACPI_TYPE_PACKAGE: + case ACPI_TYPE_BUFFER_FIELD: + + /* + * The new alias has the type ALIAS and points to the original + * NS node, not the object itself. This is because for these + * types, the object can change dynamically via a Store. + */ + AliasNode->Type = INTERNAL_TYPE_ALIAS; + AliasNode->Object = (ACPI_OPERAND_OBJECT *) TargetNode; + break; + + default: + + /* Attach the original source object to the new Alias Node */ + + /* + * The new alias assumes the type of the target, and it points + * to the same object. The reference count of the object has an + * additional reference to prevent deletion out from under either the + * target node or the alias Node + */ + Status = AcpiNsAttachObject (AliasNode, + AcpiNsGetAttachedObject (TargetNode), + TargetNode->Type); + break; + } /* Since both operands are Nodes, we don't need to delete them */ - return_ACPI_STATUS (Status); + return_ACPI_STATUS (AE_OK); } |