aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/dev/acpica/excreate.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/excreate.c')
-rw-r--r--sys/contrib/dev/acpica/excreate.c67
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);
}