summaryrefslogtreecommitdiffstats
path: root/sys/contrib/dev/acpica/namespace
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/namespace')
-rw-r--r--sys/contrib/dev/acpica/namespace/nsaccess.c2
-rw-r--r--sys/contrib/dev/acpica/namespace/nsdump.c2
-rw-r--r--sys/contrib/dev/acpica/namespace/nseval.c20
-rw-r--r--sys/contrib/dev/acpica/namespace/nsnames.c2
-rw-r--r--sys/contrib/dev/acpica/namespace/nspredef.c93
-rw-r--r--sys/contrib/dev/acpica/namespace/nsrepair.c478
-rw-r--r--sys/contrib/dev/acpica/namespace/nsrepair2.c209
-rw-r--r--sys/contrib/dev/acpica/namespace/nsutils.c63
-rw-r--r--sys/contrib/dev/acpica/namespace/nsxfeval.c10
-rw-r--r--sys/contrib/dev/acpica/namespace/nsxfname.c10
-rw-r--r--sys/contrib/dev/acpica/namespace/nsxfobj.c12
11 files changed, 659 insertions, 242 deletions
diff --git a/sys/contrib/dev/acpica/namespace/nsaccess.c b/sys/contrib/dev/acpica/namespace/nsaccess.c
index b7bc11c..fc78917 100644
--- a/sys/contrib/dev/acpica/namespace/nsaccess.c
+++ b/sys/contrib/dev/acpica/namespace/nsaccess.c
@@ -251,7 +251,7 @@ AcpiNsRootInitialize (
/* Mark this as a very SPECIAL method */
ObjDesc->Method.MethodFlags = AML_METHOD_INTERNAL_ONLY;
- ObjDesc->Method.Implementation = AcpiUtOsiImplementation;
+ ObjDesc->Method.Extra.Implementation = AcpiUtOsiImplementation;
#endif
break;
diff --git a/sys/contrib/dev/acpica/namespace/nsdump.c b/sys/contrib/dev/acpica/namespace/nsdump.c
index 212facc..b4badfe 100644
--- a/sys/contrib/dev/acpica/namespace/nsdump.c
+++ b/sys/contrib/dev/acpica/namespace/nsdump.c
@@ -286,7 +286,7 @@ AcpiNsDumpOneObject (
return (AE_OK);
}
- ThisNode = AcpiNsMapHandleToNode (ObjHandle);
+ ThisNode = AcpiNsValidateHandle (ObjHandle);
if (!ThisNode)
{
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Invalid object handle %p\n",
diff --git a/sys/contrib/dev/acpica/namespace/nseval.c b/sys/contrib/dev/acpica/namespace/nseval.c
index c9bd4ab..d6b9a91 100644
--- a/sys/contrib/dev/acpica/namespace/nseval.c
+++ b/sys/contrib/dev/acpica/namespace/nseval.c
@@ -477,6 +477,19 @@ AcpiNsExecModuleCode (
MethodObj->Method.NextObject);
Type = AcpiNsGetType (ParentNode);
+ /*
+ * 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)
+ {
+ MethodObj->Method.Extra.Handler =
+ ParentNode->Object->Device.Handler;
+ }
+
/* Must clear NextObject (AcpiNsAttachObject needs the field) */
MethodObj->Method.NextObject = NULL;
@@ -513,6 +526,13 @@ AcpiNsExecModuleCode (
ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Executed module-level code at %p\n",
MethodObj->Method.AmlStart));
+ /* Delete a possible implicit return value (in slack mode) */
+
+ if (Info->ReturnObject)
+ {
+ AcpiUtRemoveReference (Info->ReturnObject);
+ }
+
/* Detach the temporary method object */
AcpiNsDetachObject (ParentNode);
diff --git a/sys/contrib/dev/acpica/namespace/nsnames.c b/sys/contrib/dev/acpica/namespace/nsnames.c
index c299d7e..31a78f0 100644
--- a/sys/contrib/dev/acpica/namespace/nsnames.c
+++ b/sys/contrib/dev/acpica/namespace/nsnames.c
@@ -337,7 +337,7 @@ AcpiNsHandleToPathname (
ACPI_FUNCTION_TRACE_PTR (NsHandleToPathname, TargetHandle);
- Node = AcpiNsMapHandleToNode (TargetHandle);
+ Node = AcpiNsValidateHandle (TargetHandle);
if (!Node)
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
diff --git a/sys/contrib/dev/acpica/namespace/nspredef.c b/sys/contrib/dev/acpica/namespace/nspredef.c
index 4814dd5..37cbe4e 100644
--- a/sys/contrib/dev/acpica/namespace/nspredef.c
+++ b/sys/contrib/dev/acpica/namespace/nspredef.c
@@ -313,31 +313,40 @@ AcpiNsCheckPredefinedNames (
Data->Pathname = Pathname;
/*
- * Check that the type of the return object is what is expected for
- * this predefined name
+ * Check that the type of the main return object is what is expected
+ * for this predefined name
*/
Status = AcpiNsCheckObjectType (Data, ReturnObjectPtr,
Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT);
if (ACPI_FAILURE (Status))
{
- goto CheckValidationStatus;
+ goto Exit;
}
- /* For returned Package objects, check the type of all sub-objects */
-
- if (ReturnObject->Common.Type == ACPI_TYPE_PACKAGE)
+ /*
+ * For returned Package objects, check the type of all sub-objects.
+ * Note: Package may have been newly created by call above.
+ */
+ if ((*ReturnObjectPtr)->Common.Type == ACPI_TYPE_PACKAGE)
{
Status = AcpiNsCheckPackage (Data, ReturnObjectPtr);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Exit;
+ }
}
/*
- * Perform additional, more complicated repairs on a per-name
- * basis.
+ * The return object was OK, or it was successfully repaired above.
+ * Now make some additional checks such as verifying that package
+ * objects are sorted correctly (if required) or buffer objects have
+ * the correct data width (bytes vs. dwords). These repairs are
+ * performed on a per-name basis, i.e., the code is specific to
+ * particular predefined names.
*/
Status = AcpiNsComplexRepairs (Data, Node, Status, ReturnObjectPtr);
-
-CheckValidationStatus:
+Exit:
/*
* If the object validation failed or if we successfully repaired one
* or more objects, mark the parent node to suppress further warning
@@ -349,7 +358,6 @@ CheckValidationStatus:
}
ACPI_FREE (Data);
-
Cleanup:
ACPI_FREE (Pathname);
return (Status);
@@ -544,6 +552,12 @@ AcpiNsCheckPackage (
"%s Validating return Package of Type %X, Count %X\n",
Data->Pathname, Package->RetInfo.Type, ReturnObject->Package.Count));
+ /*
+ * For variable-length Packages, we can safely remove all embedded
+ * and trailing NULL package elements
+ */
+ AcpiNsRemoveNullElements (Data, Package->RetInfo.Type, ReturnObject);
+
/* Extract package count and elements array */
Elements = ReturnObject->Package.Elements;
@@ -582,9 +596,10 @@ AcpiNsCheckPackage (
}
else if (Count > ExpectedCount)
{
- ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
- "Return Package is larger than needed - "
- "found %u, expected %u", Count, ExpectedCount));
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s: Return Package is larger than needed - "
+ "found %u, expected %u\n",
+ Data->Pathname, Count, ExpectedCount));
}
/* Validate all elements of the returned package */
@@ -800,56 +815,20 @@ AcpiNsCheckPackageList (
ACPI_OPERAND_OBJECT *SubPackage;
ACPI_OPERAND_OBJECT **SubElements;
ACPI_STATUS Status;
- BOOLEAN NonTrailingNull = FALSE;
UINT32 ExpectedCount;
UINT32 i;
UINT32 j;
- /* Validate each sub-Package in the parent Package */
-
+ /*
+ * Validate each sub-Package in the parent Package
+ *
+ * NOTE: assumes list of sub-packages contains no NULL elements.
+ * Any NULL elements should have been removed by earlier call
+ * to AcpiNsRemoveNullElements.
+ */
for (i = 0; i < Count; i++)
{
- /*
- * Handling for NULL package elements. For now, we will simply allow
- * a parent package with trailing NULL elements. This can happen if
- * the package was defined to be longer than the initializer list.
- * This is legal as per the ACPI specification. It is often used
- * to allow for dynamic initialization of a Package.
- *
- * A future enhancement may be to simply truncate the package to
- * remove the trailing NULL elements.
- */
- if (!(*Elements))
- {
- if (!NonTrailingNull)
- {
- /* Ensure the remaining elements are all NULL */
-
- for (j = 1; j < (Count - i + 1); j++)
- {
- if (Elements[j])
- {
- NonTrailingNull = TRUE;
- }
- }
-
- if (!NonTrailingNull)
- {
- /* Ignore the trailing NULL elements */
-
- return (AE_OK);
- }
- }
-
- /* There are trailing non-null elements, issue warning */
-
- ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
- "Found NULL element at package index %u", i));
- Elements++;
- continue;
- }
-
SubPackage = *Elements;
SubElements = SubPackage->Package.Elements;
diff --git a/sys/contrib/dev/acpica/namespace/nsrepair.c b/sys/contrib/dev/acpica/namespace/nsrepair.c
index fe9c109..1725b58 100644
--- a/sys/contrib/dev/acpica/namespace/nsrepair.c
+++ b/sys/contrib/dev/acpica/namespace/nsrepair.c
@@ -119,7 +119,6 @@
#include <contrib/dev/acpica/include/accommon.h>
#include <contrib/dev/acpica/include/acnamesp.h>
#include <contrib/dev/acpica/include/acinterp.h>
-#include <contrib/dev/acpica/include/acpredef.h>
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nsrepair")
@@ -127,6 +126,54 @@
/*******************************************************************************
*
+ * This module attempts to repair or convert objects returned by the
+ * predefined methods to an object type that is expected, as per the ACPI
+ * specification. The need for this code is dictated by the many machines that
+ * return incorrect types for the standard predefined methods. Performing these
+ * conversions here, in one place, eliminates the need for individual ACPI
+ * device drivers to do the same. Note: Most of these conversions are different
+ * than the internal object conversion routines used for implicit object
+ * conversion.
+ *
+ * The following conversions can be performed as necessary:
+ *
+ * Integer -> String
+ * Integer -> Buffer
+ * String -> Integer
+ * String -> Buffer
+ * Buffer -> Integer
+ * Buffer -> String
+ * Buffer -> Package of Integers
+ * Package -> Package of one Package
+ *
+ ******************************************************************************/
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiNsConvertToInteger (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject);
+
+static ACPI_STATUS
+AcpiNsConvertToString (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject);
+
+static ACPI_STATUS
+AcpiNsConvertToBuffer (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject);
+
+static ACPI_STATUS
+AcpiNsConvertToPackage (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject);
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiNsRepairObject
*
* PARAMETERS: Data - Pointer to validation data structure
@@ -153,35 +200,230 @@ AcpiNsRepairObject (
{
ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
ACPI_OPERAND_OBJECT *NewObject;
- ACPI_SIZE Length;
ACPI_STATUS Status;
+ ACPI_FUNCTION_NAME (NsRepairObject);
+
+
/*
* At this point, we know that the type of the returned object was not
* one of the expected types for this predefined name. Attempt to
- * repair the object. Only a limited number of repairs are possible.
+ * repair the object by converting it to one of the expected object
+ * types for this predefined name.
+ */
+ if (ExpectedBtypes & ACPI_RTYPE_INTEGER)
+ {
+ Status = AcpiNsConvertToInteger (ReturnObject, &NewObject);
+ if (ACPI_SUCCESS (Status))
+ {
+ goto ObjectRepaired;
+ }
+ }
+ if (ExpectedBtypes & ACPI_RTYPE_STRING)
+ {
+ Status = AcpiNsConvertToString (ReturnObject, &NewObject);
+ if (ACPI_SUCCESS (Status))
+ {
+ goto ObjectRepaired;
+ }
+ }
+ if (ExpectedBtypes & ACPI_RTYPE_BUFFER)
+ {
+ Status = AcpiNsConvertToBuffer (ReturnObject, &NewObject);
+ if (ACPI_SUCCESS (Status))
+ {
+ goto ObjectRepaired;
+ }
+ }
+ if (ExpectedBtypes & ACPI_RTYPE_PACKAGE)
+ {
+ Status = AcpiNsConvertToPackage (ReturnObject, &NewObject);
+ if (ACPI_SUCCESS (Status))
+ {
+ goto ObjectRepaired;
+ }
+ }
+
+ /* We cannot repair this object */
+
+ return (AE_AML_OPERAND_TYPE);
+
+
+ObjectRepaired:
+
+ /* Object was successfully repaired */
+
+ /*
+ * 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.
*/
- switch (ReturnObject->Common.Type)
+ if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT)
+ {
+ NewObject->Common.ReferenceCount =
+ ReturnObject->Common.ReferenceCount;
+
+ if (ReturnObject->Common.ReferenceCount > 1)
+ {
+ ReturnObject->Common.ReferenceCount--;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s: Converted %s to expected %s at index %u\n",
+ Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject),
+ AcpiUtGetObjectTypeName (NewObject), PackageIndex));
+ }
+ else
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s: Converted %s to expected %s\n",
+ Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject),
+ AcpiUtGetObjectTypeName (NewObject)));
+ }
+
+ /* Delete old object, install the new return object */
+
+ AcpiUtRemoveReference (ReturnObject);
+ *ReturnObjectPtr = NewObject;
+ Data->Flags |= ACPI_OBJECT_REPAIRED;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsConvertToInteger
+ *
+ * PARAMETERS: OriginalObject - Object to be converted
+ * ReturnObject - Where the new converted object is returned
+ *
+ * RETURN: Status. AE_OK if conversion was successful.
+ *
+ * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsConvertToInteger (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject)
+{
+ ACPI_OPERAND_OBJECT *NewObject;
+ ACPI_STATUS Status;
+ UINT64 Value = 0;
+ UINT32 i;
+
+
+ switch (OriginalObject->Common.Type)
{
+ case ACPI_TYPE_STRING:
+
+ /* String-to-Integer conversion */
+
+ Status = AcpiUtStrtoul64 (OriginalObject->String.Pointer,
+ ACPI_ANY_BASE, &Value);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ break;
+
case ACPI_TYPE_BUFFER:
- /* Does the method/object legally return a string? */
+ /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */
- if (!(ExpectedBtypes & ACPI_RTYPE_STRING))
+ if (OriginalObject->Buffer.Length > 8)
{
return (AE_AML_OPERAND_TYPE);
}
+ /* Extract each buffer byte to create the integer */
+
+ for (i = 0; i < OriginalObject->Buffer.Length; i++)
+ {
+ Value |= ((UINT64) OriginalObject->Buffer.Pointer[i] << (i * 8));
+ }
+ break;
+
+ default:
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ NewObject = AcpiUtCreateIntegerObject (Value);
+ if (!NewObject)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ *ReturnObject = NewObject;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsConvertToString
+ *
+ * PARAMETERS: OriginalObject - Object to be converted
+ * ReturnObject - Where the new converted object is returned
+ *
+ * RETURN: Status. AE_OK if conversion was successful.
+ *
+ * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsConvertToString (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject)
+{
+ ACPI_OPERAND_OBJECT *NewObject;
+ ACPI_SIZE Length;
+ ACPI_STATUS Status;
+
+
+ switch (OriginalObject->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+ /*
+ * Integer-to-String conversion. Commonly, convert
+ * an integer of value 0 to a NULL string. The last element of
+ * _BIF and _BIX packages occasionally need this fix.
+ */
+ if (OriginalObject->Integer.Value == 0)
+ {
+ /* Allocate a new NULL string object */
+
+ NewObject = AcpiUtCreateStringObject (0);
+ if (!NewObject)
+ {
+ return (AE_NO_MEMORY);
+ }
+ }
+ else
+ {
+ Status = AcpiExConvertToString (OriginalObject, &NewObject,
+ ACPI_IMPLICIT_CONVERT_HEX);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ break;
+
+ case ACPI_TYPE_BUFFER:
/*
- * Have a Buffer, expected a String, convert. Use a ToString
+ * Buffer-to-String conversion. Use a ToString
* conversion, no transform performed on the buffer data. The best
* example of this is the _BIF method, where the string data from
* the battery is often (incorrectly) returned as buffer object(s).
*/
Length = 0;
- while ((Length < ReturnObject->Buffer.Length) &&
- (ReturnObject->Buffer.Pointer[Length]))
+ while ((Length < OriginalObject->Buffer.Length) &&
+ (OriginalObject->Buffer.Pointer[Length]))
{
Length++;
}
@@ -199,101 +441,188 @@ AcpiNsRepairObject (
* terminated at Length+1.
*/
ACPI_MEMCPY (NewObject->String.Pointer,
- ReturnObject->Buffer.Pointer, Length);
+ OriginalObject->Buffer.Pointer, Length);
break;
+ default:
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ *ReturnObject = NewObject;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsConvertToBuffer
+ *
+ * PARAMETERS: OriginalObject - Object to be converted
+ * ReturnObject - Where the new converted object is returned
+ *
+ * RETURN: Status. AE_OK if conversion was successful.
+ *
+ * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsConvertToBuffer (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject)
+{
+ ACPI_OPERAND_OBJECT *NewObject;
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT **Elements;
+ UINT32 *DwordBuffer;
+ UINT32 Count;
+ UINT32 i;
+
+ switch (OriginalObject->Common.Type)
+ {
case ACPI_TYPE_INTEGER:
+ /*
+ * Integer-to-Buffer conversion.
+ * Convert the Integer to a packed-byte buffer. _MAT and other
+ * objects need this sometimes, if a read has been performed on a
+ * Field object that is less than or equal to the global integer
+ * size (32 or 64 bits).
+ */
+ Status = AcpiExConvertToBuffer (OriginalObject, &NewObject);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ break;
+
+ case ACPI_TYPE_STRING:
- /* 1) Does the method/object legally return a buffer? */
+ /* String-to-Buffer conversion. Simple data copy */
- if (ExpectedBtypes & ACPI_RTYPE_BUFFER)
+ NewObject = AcpiUtCreateBufferObject (OriginalObject->String.Length);
+ if (!NewObject)
{
- /*
- * Convert the Integer to a packed-byte buffer. _MAT needs
- * this sometimes, if a read has been performed on a Field
- * object that is less than or equal to the global integer
- * size (32 or 64 bits).
- */
- Status = AcpiExConvertToBuffer (ReturnObject, &NewObject);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
+ return (AE_NO_MEMORY);
}
- /* 2) Does the method/object legally return a string? */
+ ACPI_MEMCPY (NewObject->Buffer.Pointer,
+ OriginalObject->String.Pointer, OriginalObject->String.Length);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+ /*
+ * This case is often seen for predefined names that must return a
+ * Buffer object with multiple DWORD integers within. For example,
+ * _FDE and _GTM. The Package can be converted to a Buffer.
+ */
+
+ /* All elements of the Package must be integers */
+
+ Elements = OriginalObject->Package.Elements;
+ Count = OriginalObject->Package.Count;
- else if (ExpectedBtypes & ACPI_RTYPE_STRING)
+ for (i = 0; i < Count; i++)
{
- /*
- * The only supported Integer-to-String conversion is to convert
- * an integer of value 0 to a NULL string. The last element of
- * _BIF and _BIX packages occasionally need this fix.
- */
- if (ReturnObject->Integer.Value != 0)
+ if ((!*Elements) ||
+ ((*Elements)->Common.Type != ACPI_TYPE_INTEGER))
{
return (AE_AML_OPERAND_TYPE);
}
+ Elements++;
+ }
- /* Allocate a new NULL string object */
+ /* Create the new buffer object to replace the Package */
- NewObject = AcpiUtCreateStringObject (0);
- if (!NewObject)
- {
- return (AE_NO_MEMORY);
- }
- }
- else
+ NewObject = AcpiUtCreateBufferObject (ACPI_MUL_4 (Count));
+ if (!NewObject)
{
- return (AE_AML_OPERAND_TYPE);
+ return (AE_NO_MEMORY);
}
- break;
+ /* Copy the package elements (integers) to the buffer as DWORDs */
- default:
+ Elements = OriginalObject->Package.Elements;
+ DwordBuffer = ACPI_CAST_PTR (UINT32, NewObject->Buffer.Pointer);
- /* We cannot repair this object */
+ for (i = 0; i < Count; i++)
+ {
+ *DwordBuffer = (UINT32) (*Elements)->Integer.Value;
+ DwordBuffer++;
+ Elements++;
+ }
+ break;
+ default:
return (AE_AML_OPERAND_TYPE);
}
- /* Object was successfully repaired */
+ *ReturnObject = NewObject;
+ return (AE_OK);
+}
- /*
- * 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_ELEMENT)
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiNsConvertToPackage
+ *
+ * PARAMETERS: OriginalObject - Object to be converted
+ * ReturnObject - Where the new converted object is returned
+ *
+ * RETURN: Status. AE_OK if conversion was successful.
+ *
+ * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of
+ * the buffer is converted to a single integer package element.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiNsConvertToPackage (
+ ACPI_OPERAND_OBJECT *OriginalObject,
+ ACPI_OPERAND_OBJECT **ReturnObject)
+{
+ ACPI_OPERAND_OBJECT *NewObject;
+ ACPI_OPERAND_OBJECT **Elements;
+ UINT32 Length;
+ UINT8 *Buffer;
+
+
+ switch (OriginalObject->Common.Type)
{
- NewObject->Common.ReferenceCount =
- ReturnObject->Common.ReferenceCount;
+ case ACPI_TYPE_BUFFER:
- if (ReturnObject->Common.ReferenceCount > 1)
+ /* Buffer-to-Package conversion */
+
+ Length = OriginalObject->Buffer.Length;
+ NewObject = AcpiUtCreatePackageObject (Length);
+ if (!NewObject)
{
- ReturnObject->Common.ReferenceCount--;
+ return (AE_NO_MEMORY);
}
- ACPI_INFO_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
- "Converted %s to expected %s at index %u",
- AcpiUtGetObjectTypeName (ReturnObject),
- AcpiUtGetObjectTypeName (NewObject), PackageIndex));
- }
- else
- {
- ACPI_INFO_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
- "Converted %s to expected %s",
- AcpiUtGetObjectTypeName (ReturnObject),
- AcpiUtGetObjectTypeName (NewObject)));
- }
+ /* Convert each buffer byte to an integer package element */
- /* Delete old object, install the new return object */
+ Elements = NewObject->Package.Elements;
+ Buffer = OriginalObject->Buffer.Pointer;
- AcpiUtRemoveReference (ReturnObject);
- *ReturnObjectPtr = NewObject;
- Data->Flags |= ACPI_OBJECT_REPAIRED;
+ while (Length--)
+ {
+ *Elements = AcpiUtCreateIntegerObject ((UINT64) *Buffer);
+ if (!*Elements)
+ {
+ AcpiUtRemoveReference (NewObject);
+ return (AE_NO_MEMORY);
+ }
+ Elements++;
+ Buffer++;
+ }
+ break;
+
+ default:
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ *ReturnObject = NewObject;
return (AE_OK);
}
@@ -330,6 +659,9 @@ AcpiNsRepairPackageList (
ACPI_OPERAND_OBJECT *PkgObjDesc;
+ ACPI_FUNCTION_NAME (NsRepairPackageList);
+
+
/*
* Create the new outer package and populate it. The new package will
* have a single element, the lone subpackage.
@@ -347,8 +679,8 @@ AcpiNsRepairPackageList (
*ObjDescPtr = PkgObjDesc;
Data->Flags |= ACPI_OBJECT_REPAIRED;
- ACPI_INFO_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
- "Repaired Incorrectly formed Package"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s: Repaired incorrectly formed Package\n", Data->Pathname));
return (AE_OK);
}
diff --git a/sys/contrib/dev/acpica/namespace/nsrepair2.c b/sys/contrib/dev/acpica/namespace/nsrepair2.c
index b467595..a28e9d7 100644
--- a/sys/contrib/dev/acpica/namespace/nsrepair2.c
+++ b/sys/contrib/dev/acpica/namespace/nsrepair2.c
@@ -119,6 +119,7 @@
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/accommon.h>
#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/acpredef.h>
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nsrepair2")
@@ -153,6 +154,11 @@ AcpiNsRepair_ALR (
ACPI_OPERAND_OBJECT **ReturnObjectPtr);
static ACPI_STATUS
+AcpiNsRepair_FDE (
+ ACPI_PREDEFINED_DATA *Data,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr);
+
+static ACPI_STATUS
AcpiNsRepair_PSS (
ACPI_PREDEFINED_DATA *Data,
ACPI_OPERAND_OBJECT **ReturnObjectPtr);
@@ -172,10 +178,6 @@ AcpiNsCheckSortedList (
char *SortKeyName);
static ACPI_STATUS
-AcpiNsRemoveNullElements (
- ACPI_OPERAND_OBJECT *Package);
-
-static ACPI_STATUS
AcpiNsSortList (
ACPI_OPERAND_OBJECT **Elements,
UINT32 Count,
@@ -192,19 +194,30 @@ AcpiNsSortList (
* This table contains the names of the predefined methods for which we can
* perform more complex repairs.
*
- * _ALR: Sort the list ascending by AmbientIlluminance if necessary
- * _PSS: Sort the list descending by Power if necessary
- * _TSS: Sort the list descending by Power if necessary
+ * As necessary:
+ *
+ * _ALR: Sort the list ascending by AmbientIlluminance
+ * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
+ * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
+ * _PSS: Sort the list descending by Power
+ * _TSS: Sort the list descending by Power
*/
static const ACPI_REPAIR_INFO AcpiNsRepairableNames[] =
{
{"_ALR", AcpiNsRepair_ALR},
+ {"_FDE", AcpiNsRepair_FDE},
+ {"_GTM", AcpiNsRepair_FDE}, /* _GTM has same repair as _FDE */
{"_PSS", AcpiNsRepair_PSS},
{"_TSS", AcpiNsRepair_TSS},
- {{0,0,0,0}, NULL} /* Table terminator */
+ {{0,0,0,0}, NULL} /* Table terminator */
};
+#define ACPI_FDE_FIELD_COUNT 5
+#define ACPI_FDE_BYTE_BUFFER_SIZE 5
+#define ACPI_FDE_DWORD_BUFFER_SIZE (ACPI_FDE_FIELD_COUNT * sizeof (UINT32))
+
+
/******************************************************************************
*
* FUNCTION: AcpiNsComplexRepairs
@@ -215,7 +228,7 @@ static const ACPI_REPAIR_INFO AcpiNsRepairableNames[] =
* ReturnObjectPtr - Pointer to the object returned from the
* evaluation of a method or object
*
- * RETURN: Status. AE_OK if repair was successful. If name is not
+ * RETURN: Status. AE_OK if repair was successful. If name is not
* matched, ValidateStatus is returned.
*
* DESCRIPTION: Attempt to repair/convert a return object of a type that was
@@ -315,6 +328,99 @@ AcpiNsRepair_ALR (
/******************************************************************************
*
+ * FUNCTION: AcpiNsRepair_FDE
+ *
+ * PARAMETERS: Data - Pointer to validation data structure
+ * ReturnObjectPtr - Pointer to the object returned from the
+ * evaluation of a method or object
+ *
+ * RETURN: Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return
+ * value is a Buffer of 5 DWORDs. This function repairs a common
+ * problem where the return value is a Buffer of BYTEs, not
+ * DWORDs.
+ *
+ *****************************************************************************/
+
+static ACPI_STATUS
+AcpiNsRepair_FDE (
+ ACPI_PREDEFINED_DATA *Data,
+ ACPI_OPERAND_OBJECT **ReturnObjectPtr)
+{
+ ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
+ ACPI_OPERAND_OBJECT *BufferObject;
+ UINT8 *ByteBuffer;
+ UINT32 *DwordBuffer;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_NAME (NsRepair_FDE);
+
+
+ switch (ReturnObject->Common.Type)
+ {
+ case ACPI_TYPE_BUFFER:
+
+ /* This is the expected type. Length should be (at least) 5 DWORDs */
+
+ if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE)
+ {
+ return (AE_OK);
+ }
+
+ /* We can only repair if we have exactly 5 BYTEs */
+
+ if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE)
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
+ "Incorrect return buffer length %u, expected %u",
+ ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE));
+
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ /* Create the new (larger) buffer object */
+
+ BufferObject = AcpiUtCreateBufferObject (ACPI_FDE_DWORD_BUFFER_SIZE);
+ if (!BufferObject)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Expand each byte to a DWORD */
+
+ ByteBuffer = ReturnObject->Buffer.Pointer;
+ DwordBuffer = ACPI_CAST_PTR (UINT32, BufferObject->Buffer.Pointer);
+
+ for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++)
+ {
+ *DwordBuffer = (UINT32) *ByteBuffer;
+ DwordBuffer++;
+ ByteBuffer++;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s Expanded Byte Buffer to expected DWord Buffer\n",
+ Data->Pathname));
+ break;
+
+ default:
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ /* Delete the original return object, return the new buffer object */
+
+ AcpiUtRemoveReference (ReturnObject);
+ *ReturnObjectPtr = BufferObject;
+
+ Data->Flags |= ACPI_OBJECT_REPAIRED;
+ return (AE_OK);
+}
+
+
+/******************************************************************************
+ *
* FUNCTION: AcpiNsRepair_TSS
*
* PARAMETERS: Data - Pointer to validation data structure
@@ -454,6 +560,9 @@ AcpiNsCheckSortedList (
ACPI_STATUS Status;
+ ACPI_FUNCTION_NAME (NsCheckSortedList);
+
+
/* The top-level object must be a package */
if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
@@ -462,26 +571,10 @@ AcpiNsCheckSortedList (
}
/*
- * Detect any NULL package elements and remove them from the
- * package.
- *
- * TBD: We may want to do this for all predefined names that
- * return a variable-length package of packages.
+ * NOTE: assumes list of sub-packages contains no NULL elements.
+ * Any NULL elements should have been removed by earlier call
+ * to AcpiNsRemoveNullElements.
*/
- Status = AcpiNsRemoveNullElements (ReturnObject);
- if (Status == AE_NULL_ENTRY)
- {
- ACPI_INFO_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
- "NULL elements removed from package"));
-
- /* Exit if package is now zero length */
-
- if (!ReturnObject->Package.Count)
- {
- return (AE_NULL_ENTRY);
- }
- }
-
OuterElements = ReturnObject->Package.Elements;
OuterElementCount = ReturnObject->Package.Count;
if (!OuterElementCount)
@@ -539,8 +632,9 @@ AcpiNsCheckSortedList (
Data->Flags |= ACPI_OBJECT_REPAIRED;
- ACPI_INFO_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
- "Repaired unsorted list - now sorted by %s", SortKeyName));
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s: Repaired unsorted list - now sorted by %s\n",
+ Data->Pathname, SortKeyName));
return (AE_OK);
}
@@ -556,40 +650,69 @@ AcpiNsCheckSortedList (
*
* FUNCTION: AcpiNsRemoveNullElements
*
- * PARAMETERS: ObjDesc - A Package object
+ * PARAMETERS: Data - Pointer to validation data structure
+ * PackageType - An AcpiReturnPackageTypes value
+ * ObjDesc - A Package object
*
- * RETURN: Status. AE_NULL_ENTRY means that one or more elements were
- * removed.
+ * RETURN: None.
*
- * DESCRIPTION: Remove all NULL package elements and update the package count.
+ * DESCRIPTION: Remove all NULL package elements from packages that contain
+ * a variable number of sub-packages.
*
*****************************************************************************/
-static ACPI_STATUS
+void
AcpiNsRemoveNullElements (
+ ACPI_PREDEFINED_DATA *Data,
+ UINT8 PackageType,
ACPI_OPERAND_OBJECT *ObjDesc)
{
ACPI_OPERAND_OBJECT **Source;
ACPI_OPERAND_OBJECT **Dest;
- ACPI_STATUS Status = AE_OK;
UINT32 Count;
UINT32 NewCount;
UINT32 i;
+ ACPI_FUNCTION_NAME (NsRemoveNullElements);
+
+
+ /*
+ * PTYPE1 packages contain no subpackages.
+ * PTYPE2 packages contain a variable number of sub-packages. We can
+ * safely remove all NULL elements from the PTYPE2 packages.
+ */
+ switch (PackageType)
+ {
+ case ACPI_PTYPE1_FIXED:
+ case ACPI_PTYPE1_VAR:
+ case ACPI_PTYPE1_OPTION:
+ return;
+
+ case ACPI_PTYPE2:
+ case ACPI_PTYPE2_COUNT:
+ case ACPI_PTYPE2_PKG_COUNT:
+ case ACPI_PTYPE2_FIXED:
+ case ACPI_PTYPE2_MIN:
+ case ACPI_PTYPE2_REV_FIXED:
+ break;
+
+ default:
+ return;
+ }
+
Count = ObjDesc->Package.Count;
NewCount = Count;
Source = ObjDesc->Package.Elements;
Dest = Source;
- /* Examine all elements of the package object */
+ /* Examine all elements of the package object, remove nulls */
for (i = 0; i < Count; i++)
{
if (!*Source)
{
- Status = AE_NULL_ENTRY;
NewCount--;
}
else
@@ -600,15 +723,19 @@ AcpiNsRemoveNullElements (
Source++;
}
- if (Status == AE_NULL_ENTRY)
+ /* Update parent package if any null elements were removed */
+
+ if (NewCount < Count)
{
+ ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
+ "%s: Found and removed %u NULL elements\n",
+ Data->Pathname, (Count - NewCount)));
+
/* NULL terminate list and update the package count */
*Dest = NULL;
ObjDesc->Package.Count = NewCount;
}
-
- return (Status);
}
diff --git a/sys/contrib/dev/acpica/namespace/nsutils.c b/sys/contrib/dev/acpica/namespace/nsutils.c
index 666c790..75a5faa 100644
--- a/sys/contrib/dev/acpica/namespace/nsutils.c
+++ b/sys/contrib/dev/acpica/namespace/nsutils.c
@@ -857,25 +857,26 @@ AcpiNsExternalizeName (
/*******************************************************************************
*
- * FUNCTION: AcpiNsMapHandleToNode
+ * FUNCTION: AcpiNsValidateHandle
*
- * PARAMETERS: Handle - Handle to be converted to an Node
+ * PARAMETERS: Handle - Handle to be validated and typecast to a
+ * namespace node.
*
- * RETURN: A Name table entry pointer
+ * RETURN: A pointer to a namespace node
*
- * DESCRIPTION: Convert a namespace handle to a real Node
+ * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special
+ * cases for the root node.
*
- * Note: Real integer handles would allow for more verification
+ * NOTE: Real integer handles would allow for more verification
* and keep all pointers within this subsystem - however this introduces
- * more (and perhaps unnecessary) overhead.
- *
- * The current implemenation is basically a placeholder until such time comes
- * that it is needed.
+ * more overhead and has not been necessary to this point. Drivers
+ * holding handles are typically notified before a node becomes invalid
+ * due to a table unload.
*
******************************************************************************/
ACPI_NAMESPACE_NODE *
-AcpiNsMapHandleToNode (
+AcpiNsValidateHandle (
ACPI_HANDLE Handle)
{
@@ -902,48 +903,6 @@ AcpiNsMapHandleToNode (
/*******************************************************************************
*
- * FUNCTION: AcpiNsConvertEntryToHandle
- *
- * PARAMETERS: Node - Node to be converted to a Handle
- *
- * RETURN: A user handle
- *
- * DESCRIPTION: Convert a real Node to a namespace handle
- *
- ******************************************************************************/
-
-ACPI_HANDLE
-AcpiNsConvertEntryToHandle (
- ACPI_NAMESPACE_NODE *Node)
-{
-
-
- /*
- * Simple implementation for now;
- */
- return ((ACPI_HANDLE) Node);
-
-
-/* Example future implementation ---------------------
-
- if (!Node)
- {
- return (NULL);
- }
-
- if (Node == AcpiGbl_RootNode)
- {
- return (ACPI_ROOT_OBJECT);
- }
-
-
- return ((ACPI_HANDLE) Node);
-------------------------------------------------------*/
-}
-
-
-/*******************************************************************************
- *
* FUNCTION: AcpiNsTerminate
*
* PARAMETERS: none
diff --git a/sys/contrib/dev/acpica/namespace/nsxfeval.c b/sys/contrib/dev/acpica/namespace/nsxfeval.c
index 81fba51..82f45b4 100644
--- a/sys/contrib/dev/acpica/namespace/nsxfeval.c
+++ b/sys/contrib/dev/acpica/namespace/nsxfeval.c
@@ -281,7 +281,7 @@ AcpiEvaluateObject (
/* Convert and validate the device handle */
- Info->PrefixNode = AcpiNsMapHandleToNode (Handle);
+ Info->PrefixNode = AcpiNsValidateHandle (Handle);
if (!Info->PrefixNode)
{
Status = AE_BAD_PARAMETER;
@@ -676,7 +676,7 @@ AcpiNsGetDeviceCallback (
return (Status);
}
- Node = AcpiNsMapHandleToNode (ObjHandle);
+ Node = AcpiNsValidateHandle (ObjHandle);
Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (Status))
{
@@ -888,7 +888,7 @@ AcpiAttachData (
/* Convert and validate the handle */
- Node = AcpiNsMapHandleToNode (ObjHandle);
+ Node = AcpiNsValidateHandle (ObjHandle);
if (!Node)
{
Status = AE_BAD_PARAMETER;
@@ -943,7 +943,7 @@ AcpiDetachData (
/* Convert and validate the handle */
- Node = AcpiNsMapHandleToNode (ObjHandle);
+ Node = AcpiNsValidateHandle (ObjHandle);
if (!Node)
{
Status = AE_BAD_PARAMETER;
@@ -1001,7 +1001,7 @@ AcpiGetData (
/* Convert and validate the handle */
- Node = AcpiNsMapHandleToNode (ObjHandle);
+ Node = AcpiNsValidateHandle (ObjHandle);
if (!Node)
{
Status = AE_BAD_PARAMETER;
diff --git a/sys/contrib/dev/acpica/namespace/nsxfname.c b/sys/contrib/dev/acpica/namespace/nsxfname.c
index 298aeb5..32ea0a9 100644
--- a/sys/contrib/dev/acpica/namespace/nsxfname.c
+++ b/sys/contrib/dev/acpica/namespace/nsxfname.c
@@ -178,7 +178,7 @@ AcpiGetHandle (
if (Parent)
{
- PrefixNode = AcpiNsMapHandleToNode (Parent);
+ PrefixNode = AcpiNsValidateHandle (Parent);
if (!PrefixNode)
{
return (AE_BAD_PARAMETER);
@@ -200,7 +200,7 @@ AcpiGetHandle (
if (!ACPI_STRCMP (Pathname, ACPI_NS_ROOT_PATH))
{
- *RetHandle = AcpiNsConvertEntryToHandle (AcpiGbl_RootNode);
+ *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, AcpiGbl_RootNode);
return (AE_OK);
}
}
@@ -216,7 +216,7 @@ AcpiGetHandle (
Status = AcpiNsGetNode (PrefixNode, Pathname, ACPI_NS_NO_UPSEARCH, &Node);
if (ACPI_SUCCESS (Status))
{
- *RetHandle = AcpiNsConvertEntryToHandle (Node);
+ *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
}
return (Status);
@@ -282,7 +282,7 @@ AcpiGetName (
return (Status);
}
- Node = AcpiNsMapHandleToNode (Handle);
+ Node = AcpiNsValidateHandle (Handle);
if (!Node)
{
Status = AE_BAD_PARAMETER;
@@ -399,7 +399,7 @@ AcpiGetObjectInfo (
goto Cleanup;
}
- Node = AcpiNsMapHandleToNode (Handle);
+ Node = AcpiNsValidateHandle (Handle);
if (!Node)
{
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
diff --git a/sys/contrib/dev/acpica/namespace/nsxfobj.c b/sys/contrib/dev/acpica/namespace/nsxfobj.c
index 26859ef..b6e3f0a 100644
--- a/sys/contrib/dev/acpica/namespace/nsxfobj.c
+++ b/sys/contrib/dev/acpica/namespace/nsxfobj.c
@@ -172,7 +172,7 @@ AcpiGetType (
/* Convert and validate the handle */
- Node = AcpiNsMapHandleToNode (Handle);
+ Node = AcpiNsValidateHandle (Handle);
if (!Node)
{
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
@@ -233,7 +233,7 @@ AcpiGetParent (
/* Convert and validate the handle */
- Node = AcpiNsMapHandleToNode (Handle);
+ Node = AcpiNsValidateHandle (Handle);
if (!Node)
{
Status = AE_BAD_PARAMETER;
@@ -243,7 +243,7 @@ AcpiGetParent (
/* Get the parent entry */
ParentNode = AcpiNsGetParentNode (Node);
- *RetHandle = AcpiNsConvertEntryToHandle (ParentNode);
+ *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, ParentNode);
/* Return exception if parent is null */
@@ -312,7 +312,7 @@ AcpiGetNextObject (
{
/* Start search at the beginning of the specified scope */
- ParentNode = AcpiNsMapHandleToNode (Parent);
+ ParentNode = AcpiNsValidateHandle (Parent);
if (!ParentNode)
{
Status = AE_BAD_PARAMETER;
@@ -324,7 +324,7 @@ AcpiGetNextObject (
/* Non-null handle, ignore the parent */
/* Convert and validate the handle */
- ChildNode = AcpiNsMapHandleToNode (Child);
+ ChildNode = AcpiNsValidateHandle (Child);
if (!ChildNode)
{
Status = AE_BAD_PARAMETER;
@@ -343,7 +343,7 @@ AcpiGetNextObject (
if (RetHandle)
{
- *RetHandle = AcpiNsConvertEntryToHandle (Node);
+ *RetHandle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
}
OpenPOWER on IntegriCloud