aboutsummaryrefslogtreecommitdiff
path: root/namespace
diff options
context:
space:
mode:
Diffstat (limited to 'namespace')
-rw-r--r--namespace/nsalloc.c93
-rw-r--r--namespace/nsload.c3
-rw-r--r--namespace/nspredef.c377
-rw-r--r--namespace/nsxfeval.c13
-rw-r--r--namespace/nsxfname.c248
5 files changed, 484 insertions, 250 deletions
diff --git a/namespace/nsalloc.c b/namespace/nsalloc.c
index c3113b6cb3d4..9693cb7835a1 100644
--- a/namespace/nsalloc.c
+++ b/namespace/nsalloc.c
@@ -181,7 +181,10 @@ AcpiNsCreateNode (
*
* RETURN: None
*
- * DESCRIPTION: Delete a namespace node
+ * DESCRIPTION: Delete a namespace node. All node deletions must come through
+ * here. Detaches any attached objects, including any attached
+ * data. If a handler is associated with attached data, it is
+ * invoked before the node is deleted.
*
******************************************************************************/
@@ -189,12 +192,67 @@ void
AcpiNsDeleteNode (
ACPI_NAMESPACE_NODE *Node)
{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ ACPI_FUNCTION_NAME (NsDeleteNode);
+
+
+ /* Detach an object if there is one */
+
+ AcpiNsDetachObject (Node);
+
+ /*
+ * Delete an attached data object if present (an object that was created
+ * and attached via AcpiAttachData). Note: After any normal object is
+ * detached above, the only possible remaining object is a data object.
+ */
+ ObjDesc = Node->Object;
+ if (ObjDesc &&
+ (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA))
+ {
+ /* Invoke the attached data deletion handler if present */
+
+ if (ObjDesc->Data.Handler)
+ {
+ ObjDesc->Data.Handler (Node, ObjDesc->Data.Pointer);
+ }
+
+ AcpiUtRemoveReference (ObjDesc);
+ }
+
+ /* Now we can delete the node */
+
+ (void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, Node);
+
+ ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++);
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Node %p, Remaining %X\n",
+ Node, AcpiGbl_CurrentNodeCount));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsRemoveNode
+ *
+ * PARAMETERS: Node - Node to be removed/deleted
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Remove (unlink) and delete a namespace node
+ *
+ ******************************************************************************/
+
+void
+AcpiNsRemoveNode (
+ ACPI_NAMESPACE_NODE *Node)
+{
ACPI_NAMESPACE_NODE *ParentNode;
ACPI_NAMESPACE_NODE *PrevNode;
ACPI_NAMESPACE_NODE *NextNode;
- ACPI_FUNCTION_TRACE_PTR (NsDeleteNode, Node);
+ ACPI_FUNCTION_TRACE_PTR (NsRemoveNode, Node);
ParentNode = AcpiNsGetParentNode (Node);
@@ -237,12 +295,9 @@ AcpiNsDeleteNode (
}
}
- ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++);
-
- /* Detach an object if there is one, then delete the node */
+ /* Delete the node and any attached objects */
- AcpiNsDetachObject (Node);
- (void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, Node);
+ AcpiNsDeleteNode (Node);
return_VOID;
}
@@ -385,23 +440,11 @@ AcpiNsDeleteChildren (
ParentNode, ChildNode));
}
- /* Now we can free this child object */
-
- ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++);
-
- ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n",
- ChildNode, AcpiGbl_CurrentNodeCount));
-
- /* Detach an object if there is one, then free the child node */
-
- AcpiNsDetachObject (ChildNode);
-
- /* Now we can delete the node */
-
- (void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, ChildNode);
-
- /* And move on to the next child in the list */
-
+ /*
+ * Delete this child node and move on to the next child in the list.
+ * No need to unlink the node since we are deleting the entire branch.
+ */
+ AcpiNsDeleteNode (ChildNode);
ChildNode = NextNode;
} while (!(Flags & ANOBJ_END_OF_PEER_LIST));
@@ -561,7 +604,7 @@ AcpiNsDeleteNamespaceByOwner (
if (DeletionNode)
{
AcpiNsDeleteChildren (DeletionNode);
- AcpiNsDeleteNode (DeletionNode);
+ AcpiNsRemoveNode (DeletionNode);
DeletionNode = NULL;
}
diff --git a/namespace/nsload.c b/namespace/nsload.c
index 10eff45cb36f..a9f3824718bc 100644
--- a/namespace/nsload.c
+++ b/namespace/nsload.c
@@ -376,8 +376,7 @@ AcpiNsDeleteSubtree (
/* Now delete the starting object, and we are done */
- AcpiNsDeleteNode (ChildHandle);
-
+ AcpiNsRemoveNode (ChildHandle);
return_ACPI_STATUS (AE_OK);
}
diff --git a/namespace/nspredef.c b/namespace/nspredef.c
index bfd6d7b4fc3b..0dc75247fbc8 100644
--- a/namespace/nspredef.c
+++ b/namespace/nspredef.c
@@ -146,17 +146,17 @@
*
******************************************************************************/
+
/* Local prototypes */
static ACPI_STATUS
AcpiNsCheckPackage (
- char *Pathname,
- ACPI_OPERAND_OBJECT **ReturnObjectPtr,
- const ACPI_PREDEFINED_INFO *Predefined);
+ ACPI_PREDEFINED_DATA *Data,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
static ACPI_STATUS
AcpiNsCheckPackageElements (
- char *Pathname,
+ ACPI_PREDEFINED_DATA *Data,
ACPI_OPERAND_OBJECT **Elements,
UINT8 Type1,
UINT32 Count1,
@@ -166,22 +166,28 @@ AcpiNsCheckPackageElements (
static ACPI_STATUS
AcpiNsCheckObjectType (
- char *Pathname,
+ ACPI_PREDEFINED_DATA *Data,
ACPI_OPERAND_OBJECT **ReturnObjectPtr,
UINT32 ExpectedBtypes,
UINT32 PackageIndex);
static ACPI_STATUS
AcpiNsCheckReference (
- char *Pathname,
+ ACPI_PREDEFINED_DATA *Data,
ACPI_OPERAND_OBJECT *ReturnObject);
static ACPI_STATUS
AcpiNsRepairObject (
+ ACPI_PREDEFINED_DATA *Data,
UINT32 ExpectedBtypes,
UINT32 PackageIndex,
ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+static void
+AcpiNsGetExpectedTypes (
+ char *Buffer,
+ UINT32 ExpectedBtypes);
+
/*
* Names for the types that can be returned by the predefined objects.
* Used for warning messages. Must be in the same order as the ACPI_RTYPEs
@@ -195,7 +201,13 @@ static const char *AcpiRtypeNames[] =
"/Reference",
};
-#define ACPI_NOT_PACKAGE ACPI_UINT32_MAX
+/* Object is not a package element */
+
+#define ACPI_NOT_PACKAGE_ELEMENT ACPI_UINT32_MAX
+
+/* Always emit warning message, not dependent on node flags */
+
+#define ACPI_WARN_ALWAYS 0
/*******************************************************************************
@@ -203,6 +215,8 @@ static const char *AcpiRtypeNames[] =
* FUNCTION: AcpiNsCheckPredefinedNames
*
* PARAMETERS: Node - Namespace node for the method/object
+ * UserParamCount - Number of parameters actually passed
+ * ReturnStatus - Status from the object evaluation
* ReturnObjectPtr - Pointer to the object returned from the
* evaluation of a method or object
*
@@ -223,13 +237,14 @@ AcpiNsCheckPredefinedNames (
ACPI_STATUS Status = AE_OK;
const ACPI_PREDEFINED_INFO *Predefined;
char *Pathname;
+ ACPI_PREDEFINED_DATA *Data;
/* Match the name for this method/object against the predefined list */
Predefined = AcpiNsCheckForPredefinedName (Node);
- /* Get the full pathname to the object, for use in error messages */
+ /* Get the full pathname to the object, for use in warning messages */
Pathname = AcpiNsGetExternalPathname (Node);
if (!Pathname)
@@ -248,30 +263,18 @@ AcpiNsCheckPredefinedNames (
if (!Predefined)
{
- goto Exit;
- }
-
- /* If the method failed, we cannot validate the return object */
-
- if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE))
- {
- goto Exit;
+ goto Cleanup;
}
/*
- * Only validate the return value on the first successful evaluation of
- * the method. This ensures that any warnings will only be emitted during
- * the very first evaluation of the method/object.
+ * If the method failed or did not actually return an object, we cannot
+ * validate the return object
*/
- if (Node->Flags & ANOBJ_EVALUATED)
+ if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE))
{
- goto Exit;
+ goto Cleanup;
}
- /* Mark the node as having been successfully evaluated */
-
- Node->Flags |= ANOBJ_EVALUATED;
-
/*
* If there is no return value, check if we require a return value for
* this predefined name. Either one return value is expected, or none,
@@ -284,45 +287,68 @@ AcpiNsCheckPredefinedNames (
if ((Predefined->Info.ExpectedBtypes) &&
(!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE)))
{
- ACPI_ERROR ((AE_INFO,
- "%s: Missing expected return value", Pathname));
+ ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
+ "Missing expected return value"));
Status = AE_AML_NO_RETURN_VALUE;
}
- goto Exit;
+ goto Cleanup;
}
/*
* We have a return value, but if one wasn't expected, just exit, this is
- * not a problem
- *
- * For example, if the "Implicit Return" feature is enabled, methods will
- * always return a value
+ * not a problem. For example, if the "Implicit Return" feature is
+ * enabled, methods will always return a value.
*/
if (!Predefined->Info.ExpectedBtypes)
{
- goto Exit;
+ goto Cleanup;
+ }
+
+ /* Create the parameter data block for object validation */
+
+ Data = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PREDEFINED_DATA));
+ if (!Data)
+ {
+ goto Cleanup;
}
+ Data->Predefined = Predefined;
+ Data->NodeFlags = Node->Flags;
+ Data->Pathname = Pathname;
/*
* Check that the type of the return object is what is expected for
* this predefined name
*/
- Status = AcpiNsCheckObjectType (Pathname, ReturnObjectPtr,
- Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE);
+ Status = AcpiNsCheckObjectType (Data, ReturnObjectPtr,
+ Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT);
if (ACPI_FAILURE (Status))
{
- goto Exit;
+ goto CheckValidationStatus;
}
/* For returned Package objects, check the type of all sub-objects */
if (ReturnObject->Common.Type == ACPI_TYPE_PACKAGE)
{
- Status = AcpiNsCheckPackage (Pathname, ReturnObjectPtr, Predefined);
+ Status = AcpiNsCheckPackage (Data, ReturnObjectPtr);
}
-Exit:
+
+CheckValidationStatus:
+ /*
+ * If the object validation failed or if we successfully repaired one
+ * or more objects, mark the parent node to suppress further warning
+ * messages during the next evaluation of the same method/object.
+ */
+ if (ACPI_FAILURE (Status) || (Data->Flags & ACPI_OBJECT_REPAIRED))
+ {
+ Node->Flags |= ANOBJ_EVALUATED;
+ }
+ ACPI_FREE (Data);
+
+
+Cleanup:
ACPI_FREE (Pathname);
return (Status);
}
@@ -365,11 +391,11 @@ AcpiNsCheckParameterCount (
ParamCount = Node->Object->Method.ParamCount;
}
- /* Argument count check for non-predefined methods/objects */
-
if (!Predefined)
{
/*
+ * Check the parameter count for non-predefined methods/objects.
+ *
* Warning if too few or too many arguments have been passed by the
* caller. An incorrect number of arguments may not cause the method
* to fail. However, the method will fail if there are too few
@@ -377,58 +403,49 @@ AcpiNsCheckParameterCount (
*/
if (UserParamCount < ParamCount)
{
- ACPI_WARNING ((AE_INFO,
- "%s: Insufficient arguments - needs %d, found %d",
- Pathname, ParamCount, UserParamCount));
+ ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
+ "Insufficient arguments - needs %u, found %u",
+ ParamCount, UserParamCount));
}
else if (UserParamCount > ParamCount)
{
- ACPI_WARNING ((AE_INFO,
- "%s: Excess arguments - needs %d, found %d",
- Pathname, ParamCount, UserParamCount));
+ ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
+ "Excess arguments - needs %u, found %u",
+ ParamCount, UserParamCount));
}
return;
}
- /* Allow two different legal argument counts (_SCP, etc.) */
-
+ /*
+ * Validate the user-supplied parameter count.
+ * Allow two different legal argument counts (_SCP, etc.)
+ */
RequiredParamsCurrent = Predefined->Info.ParamCount & 0x0F;
RequiredParamsOld = Predefined->Info.ParamCount >> 4;
if (UserParamCount != ACPI_UINT32_MAX)
{
- /* Validate the user-supplied parameter count */
-
if ((UserParamCount != RequiredParamsCurrent) &&
(UserParamCount != RequiredParamsOld))
{
- ACPI_WARNING ((AE_INFO,
- "%s: Parameter count mismatch - "
- "caller passed %d, ACPI requires %d",
- Pathname, UserParamCount, RequiredParamsCurrent));
+ ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
+ "Parameter count mismatch - "
+ "caller passed %u, ACPI requires %u",
+ UserParamCount, RequiredParamsCurrent));
}
}
/*
- * Only validate the argument count on the first successful evaluation of
- * the method. This ensures that any warnings will only be emitted during
- * the very first evaluation of the method/object.
- */
- if (Node->Flags & ANOBJ_EVALUATED)
- {
- return;
- }
-
- /*
* Check that the ASL-defined parameter count is what is expected for
- * this predefined name.
+ * this predefined name (parameter count as defined by the ACPI
+ * specification)
*/
if ((ParamCount != RequiredParamsCurrent) &&
(ParamCount != RequiredParamsOld))
{
- ACPI_WARNING ((AE_INFO,
- "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d",
- Pathname, ParamCount, RequiredParamsCurrent));
+ ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, Node->Flags,
+ "Parameter count mismatch - ASL declared %u, ACPI requires %u",
+ ParamCount, RequiredParamsCurrent));
}
}
@@ -466,8 +483,6 @@ AcpiNsCheckForPredefinedName (
{
if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Info.Name))
{
- /* Return pointer to this table entry */
-
return (ThisName);
}
@@ -483,7 +498,7 @@ AcpiNsCheckForPredefinedName (
ThisName++;
}
- return (NULL);
+ return (NULL); /* Not found */
}
@@ -491,10 +506,9 @@ AcpiNsCheckForPredefinedName (
*
* FUNCTION: AcpiNsCheckPackage
*
- * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
+ * PARAMETERS: Data - Pointer to validation data structure
* ReturnObjectPtr - Pointer to the object returned from the
* evaluation of a method or object
- * Predefined - Pointer to entry in predefined name table
*
* RETURN: Status
*
@@ -505,9 +519,8 @@ AcpiNsCheckForPredefinedName (
static ACPI_STATUS
AcpiNsCheckPackage (
- char *Pathname,
- ACPI_OPERAND_OBJECT **ReturnObjectPtr,
- const ACPI_PREDEFINED_INFO *Predefined)
+ ACPI_PREDEFINED_DATA *Data,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
{
ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
const ACPI_PREDEFINED_INFO *Package;
@@ -526,11 +539,11 @@ AcpiNsCheckPackage (
/* The package info for this name is in the next table entry */
- Package = Predefined + 1;
+ Package = Data->Predefined + 1;
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
"%s Validating return Package of Type %X, Count %X\n",
- Pathname, Package->RetInfo.Type, ReturnObject->Package.Count));
+ Data->Pathname, Package->RetInfo.Type, ReturnObject->Package.Count));
/* Extract package count and elements array */
@@ -541,8 +554,8 @@ AcpiNsCheckPackage (
if (!Count)
{
- ACPI_WARNING ((AE_INFO,
- "%s: Return Package has no elements (empty)", Pathname));
+ ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
+ "Return Package has no elements (empty)"));
return (AE_AML_OPERAND_VALUE);
}
@@ -570,14 +583,14 @@ AcpiNsCheckPackage (
}
else if (Count > ExpectedCount)
{
- ACPI_WARNING ((AE_INFO,
- "%s: Return Package is larger than needed - "
- "found %u, expected %u", Pathname, Count, ExpectedCount));
+ ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
+ "Return Package is larger than needed - "
+ "found %u, expected %u", Count, ExpectedCount));
}
/* Validate all elements of the returned package */
- Status = AcpiNsCheckPackageElements (Pathname, Elements,
+ Status = AcpiNsCheckPackageElements (Data, Elements,
Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0);
if (ACPI_FAILURE (Status))
@@ -595,7 +608,7 @@ AcpiNsCheckPackage (
*/
for (i = 0; i < Count; i++)
{
- Status = AcpiNsCheckObjectType (Pathname, Elements,
+ Status = AcpiNsCheckObjectType (Data, Elements,
Package->RetInfo.ObjectType1, i);
if (ACPI_FAILURE (Status))
{
@@ -629,7 +642,7 @@ AcpiNsCheckPackage (
{
/* These are the required package elements (0, 1, or 2) */
- Status = AcpiNsCheckObjectType (Pathname, Elements,
+ Status = AcpiNsCheckObjectType (Data, Elements,
Package->RetInfo3.ObjectType[i], i);
if (ACPI_FAILURE (Status))
{
@@ -640,7 +653,7 @@ AcpiNsCheckPackage (
{
/* These are the optional package elements */
- Status = AcpiNsCheckObjectType (Pathname, Elements,
+ Status = AcpiNsCheckObjectType (Data, Elements,
Package->RetInfo3.TailObjectType, i);
if (ACPI_FAILURE (Status))
{
@@ -656,7 +669,7 @@ AcpiNsCheckPackage (
/* First element is the (Integer) count of sub-packages to follow */
- Status = AcpiNsCheckObjectType (Pathname, Elements,
+ Status = AcpiNsCheckObjectType (Data, Elements,
ACPI_RTYPE_INTEGER, 0);
if (ACPI_FAILURE (Status))
{
@@ -697,7 +710,7 @@ AcpiNsCheckPackage (
/* Each sub-object must be of type Package */
- Status = AcpiNsCheckObjectType (Pathname, &SubPackage,
+ Status = AcpiNsCheckObjectType (Data, &SubPackage,
ACPI_RTYPE_PACKAGE, i);
if (ACPI_FAILURE (Status))
{
@@ -721,7 +734,7 @@ AcpiNsCheckPackage (
goto PackageTooSmall;
}
- Status = AcpiNsCheckPackageElements (Pathname, SubElements,
+ Status = AcpiNsCheckPackageElements (Data, SubElements,
Package->RetInfo.ObjectType1,
Package->RetInfo.Count1,
Package->RetInfo.ObjectType2,
@@ -747,7 +760,7 @@ AcpiNsCheckPackage (
for (j = 0; j < ExpectedCount; j++)
{
- Status = AcpiNsCheckObjectType (Pathname, &SubElements[j],
+ Status = AcpiNsCheckObjectType (Data, &SubElements[j],
Package->RetInfo2.ObjectType[j], j);
if (ACPI_FAILURE (Status))
{
@@ -769,7 +782,7 @@ AcpiNsCheckPackage (
/* Check the type of each sub-package element */
- Status = AcpiNsCheckPackageElements (Pathname, SubElements,
+ Status = AcpiNsCheckPackageElements (Data, SubElements,
Package->RetInfo.ObjectType1,
SubPackage->Package.Count, 0, 0, 0);
if (ACPI_FAILURE (Status))
@@ -782,7 +795,7 @@ AcpiNsCheckPackage (
/* First element is the (Integer) count of elements to follow */
- Status = AcpiNsCheckObjectType (Pathname, SubElements,
+ Status = AcpiNsCheckObjectType (Data, SubElements,
ACPI_RTYPE_INTEGER, 0);
if (ACPI_FAILURE (Status))
{
@@ -800,8 +813,7 @@ AcpiNsCheckPackage (
/* Check the type of each sub-package element */
- Status = AcpiNsCheckPackageElements (Pathname,
- (SubElements + 1),
+ Status = AcpiNsCheckPackageElements (Data, (SubElements + 1),
Package->RetInfo.ObjectType1,
(ExpectedCount - 1), 0, 0, 1);
if (ACPI_FAILURE (Status))
@@ -823,9 +835,9 @@ AcpiNsCheckPackage (
/* Should not get here if predefined info table is correct */
- ACPI_WARNING ((AE_INFO,
- "%s: Invalid internal return type in table entry: %X",
- Pathname, Package->RetInfo.Type));
+ ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
+ "Invalid internal return type in table entry: %X",
+ Package->RetInfo.Type));
return (AE_AML_INTERNAL);
}
@@ -837,8 +849,9 @@ PackageTooSmall:
/* Error exit for the case with an incorrect package count */
- ACPI_WARNING ((AE_INFO, "%s: Return Package is too small - "
- "found %u, expected %u", Pathname, Count, ExpectedCount));
+ ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
+ "Return Package is too small - found %u, expected %u",
+ Count, ExpectedCount));
return (AE_AML_OPERAND_VALUE);
}
@@ -848,7 +861,7 @@ PackageTooSmall:
*
* FUNCTION: AcpiNsCheckPackageElements
*
- * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
+ * PARAMETERS: Data - Pointer to validation data structure
* Elements - Pointer to the package elements array
* Type1 - Object type for first group
* Count1 - Count for first group
@@ -865,7 +878,7 @@ PackageTooSmall:
static ACPI_STATUS
AcpiNsCheckPackageElements (
- char *Pathname,
+ ACPI_PREDEFINED_DATA *Data,
ACPI_OPERAND_OBJECT **Elements,
UINT8 Type1,
UINT32 Count1,
@@ -885,7 +898,7 @@ AcpiNsCheckPackageElements (
*/
for (i = 0; i < Count1; i++)
{
- Status = AcpiNsCheckObjectType (Pathname, ThisElement,
+ Status = AcpiNsCheckObjectType (Data, ThisElement,
Type1, i + StartIndex);
if (ACPI_FAILURE (Status))
{
@@ -896,7 +909,7 @@ AcpiNsCheckPackageElements (
for (i = 0; i < Count2; i++)
{
- Status = AcpiNsCheckObjectType (Pathname, ThisElement,
+ Status = AcpiNsCheckObjectType (Data, ThisElement,
Type2, (i + Count1 + StartIndex));
if (ACPI_FAILURE (Status))
{
@@ -913,12 +926,13 @@ AcpiNsCheckPackageElements (
*
* FUNCTION: AcpiNsCheckObjectType
*
- * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
+ * PARAMETERS: Data - Pointer to validation data structure
* ReturnObjectPtr - Pointer to the object returned from the
* evaluation of a method or object
* ExpectedBtypes - Bitmap of expected return type(s)
* PackageIndex - Index of object within parent package (if
- * applicable - ACPI_NOT_PACKAGE otherwise)
+ * applicable - ACPI_NOT_PACKAGE_ELEMENT
+ * otherwise)
*
* RETURN: Status
*
@@ -929,7 +943,7 @@ AcpiNsCheckPackageElements (
static ACPI_STATUS
AcpiNsCheckObjectType (
- char *Pathname,
+ ACPI_PREDEFINED_DATA *Data,
ACPI_OPERAND_OBJECT **ReturnObjectPtr,
UINT32 ExpectedBtypes,
UINT32 PackageIndex)
@@ -938,9 +952,6 @@ AcpiNsCheckObjectType (
ACPI_STATUS Status = AE_OK;
UINT32 ReturnBtype;
char TypeBuffer[48]; /* Room for 5 types */
- UINT32 ThisRtype;
- UINT32 i;
- UINT32 j;
/*
@@ -956,9 +967,9 @@ AcpiNsCheckObjectType (
if (ACPI_GET_DESCRIPTOR_TYPE (ReturnObject) == ACPI_DESC_TYPE_NAMED)
{
- ACPI_WARNING ((AE_INFO,
- "%s: Invalid return type - Found a Namespace node [%4.4s] type %s",
- Pathname, ReturnObject->Node.Name.Ascii,
+ ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
+ "Invalid return type - Found a Namespace node [%4.4s] type %s",
+ ReturnObject->Node.Name.Ascii,
AcpiUtGetTypeName (ReturnObject->Node.Type)));
return (AE_AML_OPERAND_TYPE);
}
@@ -1005,11 +1016,11 @@ AcpiNsCheckObjectType (
{
/* Type mismatch -- attempt repair of the returned object */
- Status = AcpiNsRepairObject (ExpectedBtypes, PackageIndex,
- ReturnObjectPtr);
+ Status = AcpiNsRepairObject (Data, ExpectedBtypes,
+ PackageIndex, ReturnObjectPtr);
if (ACPI_SUCCESS (Status))
{
- return (Status);
+ return (AE_OK); /* Repair was successful */
}
goto TypeErrorExit;
}
@@ -1018,7 +1029,7 @@ AcpiNsCheckObjectType (
if (ReturnObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
{
- Status = AcpiNsCheckReference (Pathname, ReturnObject);
+ Status = AcpiNsCheckReference (Data, ReturnObject);
}
return (Status);
@@ -1028,33 +1039,19 @@ TypeErrorExit:
/* Create a string with all expected types for this predefined object */
- j = 1;
- TypeBuffer[0] = 0;
- ThisRtype = ACPI_RTYPE_INTEGER;
+ AcpiNsGetExpectedTypes (TypeBuffer, ExpectedBtypes);
- for (i = 0; i < ACPI_NUM_RTYPES; i++)
+ if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT)
{
- /* If one of the expected types, concatenate the name of this type */
-
- if (ExpectedBtypes & ThisRtype)
- {
- ACPI_STRCAT (TypeBuffer, &AcpiRtypeNames[i][j]);
- j = 0; /* Use name separator from now on */
- }
- ThisRtype <<= 1; /* Next Rtype */
- }
-
- if (PackageIndex == ACPI_NOT_PACKAGE)
- {
- ACPI_WARNING ((AE_INFO,
- "%s: Return type mismatch - found %s, expected %s",
- Pathname, AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
+ ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
+ "Return type mismatch - found %s, expected %s",
+ AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
}
else
{
- ACPI_WARNING ((AE_INFO,
- "%s: Return Package type mismatch at index %u - "
- "found %s, expected %s", Pathname, PackageIndex,
+ ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
+ "Return Package type mismatch at index %u - "
+ "found %s, expected %s", PackageIndex,
AcpiUtGetObjectTypeName (ReturnObject), TypeBuffer));
}
@@ -1066,7 +1063,7 @@ TypeErrorExit:
*
* FUNCTION: AcpiNsCheckReference
*
- * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
+ * PARAMETERS: Data - Pointer to validation data structure
* ReturnObject - Object returned from the evaluation of a
* method or object
*
@@ -1080,7 +1077,7 @@ TypeErrorExit:
static ACPI_STATUS
AcpiNsCheckReference (
- char *Pathname,
+ ACPI_PREDEFINED_DATA *Data,
ACPI_OPERAND_OBJECT *ReturnObject)
{
@@ -1094,10 +1091,9 @@ AcpiNsCheckReference (
return (AE_OK);
}
- ACPI_WARNING ((AE_INFO,
- "%s: Return type mismatch - "
- "unexpected reference object type [%s] %2.2X",
- Pathname, AcpiUtGetReferenceName (ReturnObject),
+ ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
+ "Return type mismatch - unexpected reference object type [%s] %2.2X",
+ AcpiUtGetReferenceName (ReturnObject),
ReturnObject->Reference.Class));
return (AE_AML_OPERAND_TYPE);
@@ -1108,8 +1104,11 @@ AcpiNsCheckReference (
*
* FUNCTION: AcpiNsRepairObject
*
- * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
- * PackageIndex - Used to determine if target is in a package
+ * PARAMETERS: Data - Pointer to validation data structure
+ * ExpectedBtypes - Object types expected
+ * PackageIndex - Index of object within parent package (if
+ * applicable - ACPI_NOT_PACKAGE_ELEMENT
+ * otherwise)
* ReturnObjectPtr - Pointer to the object returned from the
* evaluation of a method or object
*
@@ -1122,6 +1121,7 @@ AcpiNsCheckReference (
static ACPI_STATUS
AcpiNsRepairObject (
+ ACPI_PREDEFINED_DATA *Data,
UINT32 ExpectedBtypes,
UINT32 PackageIndex,
ACPI_OPERAND_OBJECT **ReturnObjectPtr)
@@ -1135,6 +1135,8 @@ AcpiNsRepairObject (
{
case ACPI_TYPE_BUFFER:
+ /* Does the method/object legally return a string? */
+
if (!(ExpectedBtypes & ACPI_RTYPE_STRING))
{
return (AE_AML_OPERAND_TYPE);
@@ -1168,23 +1170,37 @@ AcpiNsRepairObject (
ACPI_MEMCPY (NewObject->String.Pointer,
ReturnObject->Buffer.Pointer, Length);
- /* Install the new return object */
-
- AcpiUtRemoveReference (ReturnObject);
- *ReturnObjectPtr = NewObject;
-
/*
- * If the object is a package element, we need to:
- * 1. Decrement the reference count of the orignal object, it was
- * incremented when building the package
- * 2. Increment the reference count of the new object, it will be
- * decremented when releasing the package
+ * If the original object is a package element, we need to:
+ * 1. Set the reference count of the new object to match the
+ * reference count of the old object.
+ * 2. Decrement the reference count of the original object.
*/
- if (PackageIndex != ACPI_NOT_PACKAGE)
+ if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT)
{
- AcpiUtRemoveReference (ReturnObject);
- AcpiUtAddReference (NewObject);
+ NewObject->Common.ReferenceCount =
+ ReturnObject->Common.ReferenceCount;
+
+ if (ReturnObject->Common.ReferenceCount > 1)
+ {
+ ReturnObject->Common.ReferenceCount--;
+ }
+
+ ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
+ "Converted Buffer to expected String at index %u",
+ PackageIndex));
+ }
+ else
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
+ "Converted Buffer to expected String"));
}
+
+ /* Delete old object, install the new return object */
+
+ AcpiUtRemoveReference (ReturnObject);
+ *ReturnObjectPtr = NewObject;
+ Data->Flags |= ACPI_OBJECT_REPAIRED;
return (AE_OK);
default:
@@ -1194,3 +1210,44 @@ AcpiNsRepairObject (
return (AE_AML_OPERAND_TYPE);
}
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsGetExpectedTypes
+ *
+ * PARAMETERS: Buffer - Pointer to where the string is returned
+ * ExpectedBtypes - Bitmap of expected return type(s)
+ *
+ * RETURN: Buffer is populated with type names.
+ *
+ * DESCRIPTION: Translate the expected types bitmap into a string of ascii
+ * names of expected types, for use in warning messages.
+ *
+ ******************************************************************************/
+
+static void
+AcpiNsGetExpectedTypes (
+ char *Buffer,
+ UINT32 ExpectedBtypes)
+{
+ UINT32 ThisRtype;
+ UINT32 i;
+ UINT32 j;
+
+
+ j = 1;
+ Buffer[0] = 0;
+ ThisRtype = ACPI_RTYPE_INTEGER;
+
+ for (i = 0; i < ACPI_NUM_RTYPES; i++)
+ {
+ /* If one of the expected types, concatenate the name of this type */
+
+ if (ExpectedBtypes & ThisRtype)
+ {
+ ACPI_STRCAT (Buffer, &AcpiRtypeNames[i][j]);
+ j = 0; /* Use name separator from now on */
+ }
+ ThisRtype <<= 1; /* Next Rtype */
+ }
+}
diff --git a/namespace/nsxfeval.c b/namespace/nsxfeval.c
index c0d877839c3e..c2a5dbb6f175 100644
--- a/namespace/nsxfeval.c
+++ b/namespace/nsxfeval.c
@@ -658,10 +658,11 @@ AcpiNsGetDeviceCallback (
ACPI_STATUS Status;
ACPI_NAMESPACE_NODE *Node;
UINT32 Flags;
- ACPI_DEVICE_ID Hid;
- ACPI_COMPATIBLE_ID_LIST *Cid;
+ ACPI_DEVICE_ID *Hid;
+ ACPI_DEVICE_ID_LIST *Cid;
UINT32 i;
BOOLEAN Found;
+ int Match;
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
@@ -715,7 +716,10 @@ AcpiNsGetDeviceCallback (
return (AE_CTRL_DEPTH);
}
- if (ACPI_STRNCMP (Hid.Value, Info->Hid, sizeof (Hid.Value)) != 0)
+ Match = ACPI_STRCMP (Hid->String, Info->Hid);
+ ACPI_FREE (Hid);
+
+ if (!Match)
{
/*
* HID does not match, attempt match within the
@@ -736,8 +740,7 @@ AcpiNsGetDeviceCallback (
Found = FALSE;
for (i = 0; i < Cid->Count; i++)
{
- if (ACPI_STRNCMP (Cid->Id[i].Value, Info->Hid,
- sizeof (ACPI_COMPATIBLE_ID)) == 0)
+ if (ACPI_STRCMP (Cid->Ids[i].String, Info->Hid) == 0)
{
/* Found a matching CID */
diff --git a/namespace/nsxfname.c b/namespace/nsxfname.c
index 49ccb58092fa..166862bc2a9c 100644
--- a/namespace/nsxfname.c
+++ b/namespace/nsxfname.c
@@ -126,6 +126,14 @@
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nsxfname")
+/* Local prototypes */
+
+static char *
+AcpiNsCopyDeviceId (
+ ACPI_DEVICE_ID *Dest,
+ ACPI_DEVICE_ID *Source,
+ char *StringArea);
+
/******************************************************************************
*
@@ -308,10 +316,42 @@ ACPI_EXPORT_SYMBOL (AcpiGetName)
/******************************************************************************
*
+ * FUNCTION: AcpiNsCopyDeviceId
+ *
+ * PARAMETERS: Dest - Pointer to the destination DEVICE_ID
+ * Source - Pointer to the source DEVICE_ID
+ * StringArea - Pointer to where to copy the dest string
+ *
+ * RETURN: Pointer to the next string area
+ *
+ * DESCRIPTION: Copy a single DEVICE_ID, including the string data.
+ *
+ ******************************************************************************/
+
+static char *
+AcpiNsCopyDeviceId (
+ ACPI_DEVICE_ID *Dest,
+ ACPI_DEVICE_ID *Source,
+ char *StringArea)
+{
+ /* Create the destination DEVICE_ID */
+
+ Dest->String = StringArea;
+ Dest->Length = Source->Length;
+
+ /* Copy actual string and return a pointer to the next string area */
+
+ ACPI_MEMCPY (StringArea, Source->String, Source->Length);
+ return (StringArea + Source->Length);
+}
+
+
+/******************************************************************************
+ *
* FUNCTION: AcpiGetObjectInfo
*
- * PARAMETERS: Handle - Object Handle
- * Buffer - Where the info is returned
+ * PARAMETERS: Handle - Object Handle
+ * ReturnBuffer - Where the info is returned
*
* RETURN: Status
*
@@ -319,40 +359,40 @@ ACPI_EXPORT_SYMBOL (AcpiGetName)
* namespace node and possibly by running several standard
* control methods (Such as in the case of a device.)
*
+ * For Device and Processor objects, run the Device _HID, _UID, _CID, _STA,
+ * _ADR, _SxW, and _SxD methods.
+ *
+ * Note: Allocates the return buffer, must be freed by the caller.
+ *
******************************************************************************/
ACPI_STATUS
AcpiGetObjectInfo (
ACPI_HANDLE Handle,
- ACPI_BUFFER *Buffer)
+ ACPI_DEVICE_INFO **ReturnBuffer)
{
- ACPI_STATUS Status;
ACPI_NAMESPACE_NODE *Node;
ACPI_DEVICE_INFO *Info;
- ACPI_DEVICE_INFO *ReturnInfo;
- ACPI_COMPATIBLE_ID_LIST *CidList = NULL;
- ACPI_SIZE Size;
+ ACPI_DEVICE_ID_LIST *CidList = NULL;
+ ACPI_DEVICE_ID *Hid = NULL;
+ ACPI_DEVICE_ID *Uid = NULL;
+ char *NextIdString;
+ ACPI_OBJECT_TYPE Type;
+ ACPI_NAME Name;
+ UINT8 ParamCount= 0;
+ UINT8 Valid = 0;
+ UINT32 InfoSize;
+ UINT32 i;
+ ACPI_STATUS Status;
/* Parameter validation */
- if (!Handle || !Buffer)
+ if (!Handle || !ReturnBuffer)
{
return (AE_BAD_PARAMETER);
}
- Status = AcpiUtValidateBuffer (Buffer);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
-
- Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_DEVICE_INFO));
- if (!Info)
- {
- return (AE_NO_MEMORY);
- }
-
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (Status))
{
@@ -363,56 +403,54 @@ AcpiGetObjectInfo (
if (!Node)
{
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
- Status = AE_BAD_PARAMETER;
- goto Cleanup;
+ return (AE_BAD_PARAMETER);
}
- /* Init return structure */
-
- Size = sizeof (ACPI_DEVICE_INFO);
+ /* Get the namespace node data while the namespace is locked */
- Info->Type = Node->Type;
- Info->Name = Node->Name.Integer;
- Info->Valid = 0;
+ InfoSize = sizeof (ACPI_DEVICE_INFO);
+ Type = Node->Type;
+ Name = Node->Name.Integer;
if (Node->Type == ACPI_TYPE_METHOD)
{
- Info->ParamCount = Node->Object->Method.ParamCount;
+ ParamCount = Node->Object->Method.ParamCount;
}
Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (Status))
{
- goto Cleanup;
+ return (Status);
}
- /* If not a device, we are all done */
-
- if (Info->Type == ACPI_TYPE_DEVICE)
+ if ((Type == ACPI_TYPE_DEVICE) ||
+ (Type == ACPI_TYPE_PROCESSOR))
{
/*
- * Get extra info for ACPI Devices objects only:
- * Run the Device _HID, _UID, _CID, _STA, _ADR and _SxD methods.
+ * Get extra info for ACPI Device/Processor objects only:
+ * Run the Device _HID, _UID, and _CID methods.
*
* Note: none of these methods are required, so they may or may
- * not be present for this device. The Info->Valid bitfield is used
- * to indicate which methods were found and ran successfully.
+ * not be present for this device. The Info->Valid bitfield is used
+ * to indicate which methods were found and run successfully.
*/
/* Execute the Device._HID method */
- Status = AcpiUtExecute_HID (Node, &Info->HardwareId);
+ Status = AcpiUtExecute_HID (Node, &Hid);
if (ACPI_SUCCESS (Status))
{
- Info->Valid |= ACPI_VALID_HID;
+ InfoSize += Hid->Length;
+ Valid |= ACPI_VALID_HID;
}
/* Execute the Device._UID method */
- Status = AcpiUtExecute_UID (Node, &Info->UniqueId);
+ Status = AcpiUtExecute_UID (Node, &Uid);
if (ACPI_SUCCESS (Status))
{
- Info->Valid |= ACPI_VALID_UID;
+ InfoSize += Uid->Length;
+ Valid |= ACPI_VALID_UID;
}
/* Execute the Device._CID method */
@@ -420,57 +458,151 @@ AcpiGetObjectInfo (
Status = AcpiUtExecute_CID (Node, &CidList);
if (ACPI_SUCCESS (Status))
{
- Size += CidList->Size;
- Info->Valid |= ACPI_VALID_CID;
+ /* Add size of CID strings and CID pointer array */
+
+ InfoSize += (CidList->ListSize - sizeof (ACPI_DEVICE_ID_LIST));
+ Valid |= ACPI_VALID_CID;
}
+ }
+
+ /*
+ * Now that we have the variable-length data, we can allocate the
+ * return buffer
+ */
+ Info = ACPI_ALLOCATE_ZEROED (InfoSize);
+ if (!Info)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Get the fixed-length data */
+
+ if ((Type == ACPI_TYPE_DEVICE) ||
+ (Type == ACPI_TYPE_PROCESSOR))
+ {
+ /*
+ * Get extra info for ACPI Device/Processor objects only:
+ * Run the _STA, _ADR and, SxW, and _SxD methods.
+ *
+ * Note: none of these methods are required, so they may or may
+ * not be present for this device. The Info->Valid bitfield is used
+ * to indicate which methods were found and run successfully.
+ */
/* Execute the Device._STA method */
Status = AcpiUtExecute_STA (Node, &Info->CurrentStatus);
if (ACPI_SUCCESS (Status))
{
- Info->Valid |= ACPI_VALID_STA;
+ Valid |= ACPI_VALID_STA;
}
/* Execute the Device._ADR method */
Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node,
- &Info->Address);
+ &Info->Address);
if (ACPI_SUCCESS (Status))
{
- Info->Valid |= ACPI_VALID_ADR;
+ Valid |= ACPI_VALID_ADR;
+ }
+
+ /* Execute the Device._SxW methods */
+
+ Status = AcpiUtExecutePowerMethods (Node,
+ AcpiGbl_LowestDstateNames, ACPI_NUM_SxW_METHODS,
+ Info->LowestDstates);
+ if (ACPI_SUCCESS (Status))
+ {
+ Valid |= ACPI_VALID_SXWS;
}
/* Execute the Device._SxD methods */
- Status = AcpiUtExecute_Sxds (Node, Info->HighestDstates);
+ Status = AcpiUtExecutePowerMethods (Node,
+ AcpiGbl_HighestDstateNames, ACPI_NUM_SxD_METHODS,
+ Info->HighestDstates);
if (ACPI_SUCCESS (Status))
{
- Info->Valid |= ACPI_VALID_SXDS;
+ Valid |= ACPI_VALID_SXDS;
}
}
- /* Validate/Allocate/Clear caller buffer */
-
- Status = AcpiUtInitializeBuffer (Buffer, Size);
- if (ACPI_FAILURE (Status))
+ /*
+ * Create a pointer to the string area of the return buffer.
+ * Point to the end of the base ACPI_DEVICE_INFO structure.
+ */
+ NextIdString = ACPI_CAST_PTR (char, Info->CompatibleIdList.Ids);
+ if (CidList)
{
- goto Cleanup;
+ /* Point past the CID DEVICE_ID array */
+
+ NextIdString += ((ACPI_SIZE) CidList->Count * sizeof (ACPI_DEVICE_ID));
}
- /* Populate the return buffer */
+ /*
+ * Copy the HID, UID, and CIDs to the return buffer. The variable-length
+ * strings are copied to the reserved area at the end of the buffer.
+ *
+ * For HID and CID, check if the ID is a PCI Root Bridge.
+ */
+ if (Hid)
+ {
+ NextIdString = AcpiNsCopyDeviceId (&Info->HardwareId,
+ Hid, NextIdString);
+
+ if (AcpiUtIsPciRootBridge (Hid->String))
+ {
+ Info->Flags |= ACPI_PCI_ROOT_BRIDGE;
+ }
+ }
- ReturnInfo = Buffer->Pointer;
- ACPI_MEMCPY (ReturnInfo, Info, sizeof (ACPI_DEVICE_INFO));
+ if (Uid)
+ {
+ NextIdString = AcpiNsCopyDeviceId (&Info->UniqueId,
+ Uid, NextIdString);
+ }
if (CidList)
{
- ACPI_MEMCPY (&ReturnInfo->CompatibilityId, CidList, CidList->Size);
+ Info->CompatibleIdList.Count = CidList->Count;
+ Info->CompatibleIdList.ListSize = CidList->ListSize;
+
+ /* Copy each CID */
+
+ for (i = 0; i < CidList->Count; i++)
+ {
+ NextIdString = AcpiNsCopyDeviceId (&Info->CompatibleIdList.Ids[i],
+ &CidList->Ids[i], NextIdString);
+
+ if (AcpiUtIsPciRootBridge (CidList->Ids[i].String))
+ {
+ Info->Flags |= ACPI_PCI_ROOT_BRIDGE;
+ }
+ }
}
+ /* Copy the fixed-length data */
+
+ Info->InfoSize = InfoSize;
+ Info->Type = Type;
+ Info->Name = Name;
+ Info->ParamCount = ParamCount;
+ Info->Valid = Valid;
+
+ *ReturnBuffer = Info;
+ Status = AE_OK;
+
Cleanup:
- ACPI_FREE (Info);
+ if (Hid)
+ {
+ ACPI_FREE (Hid);
+ }
+ if (Uid)
+ {
+ ACPI_FREE (Uid);
+ }
if (CidList)
{
ACPI_FREE (CidList);