summaryrefslogtreecommitdiffstats
path: root/sys/contrib/dev/acpica/namespace/nsrepair.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/namespace/nsrepair.c')
-rw-r--r--sys/contrib/dev/acpica/namespace/nsrepair.c111
1 files changed, 87 insertions, 24 deletions
diff --git a/sys/contrib/dev/acpica/namespace/nsrepair.c b/sys/contrib/dev/acpica/namespace/nsrepair.c
index 82c1bb8..714ccc8 100644
--- a/sys/contrib/dev/acpica/namespace/nsrepair.c
+++ b/sys/contrib/dev/acpica/namespace/nsrepair.c
@@ -118,6 +118,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/acinterp.h>
#include <contrib/dev/acpica/include/acpredef.h>
#define _COMPONENT ACPI_NAMESPACE
@@ -153,8 +154,14 @@ AcpiNsRepairObject (
ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
ACPI_OPERAND_OBJECT *NewObject;
ACPI_SIZE Length;
+ ACPI_STATUS Status;
+ /*
+ * 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.
+ */
switch (ReturnObject->Common.Type)
{
case ACPI_TYPE_BUFFER:
@@ -193,45 +200,101 @@ AcpiNsRepairObject (
*/
ACPI_MEMCPY (NewObject->String.Pointer,
ReturnObject->Buffer.Pointer, Length);
+ break;
- /*
- * 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)
+
+ case ACPI_TYPE_INTEGER:
+
+ /* 1) Does the method/object legally return a buffer? */
+
+ if (ExpectedBtypes & ACPI_RTYPE_BUFFER)
{
- NewObject->Common.ReferenceCount =
- ReturnObject->Common.ReferenceCount;
+ /*
+ * 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);
+ }
+ }
+
+ /* 2) Does the method/object legally return a string? */
- if (ReturnObject->Common.ReferenceCount > 1)
+ else if (ExpectedBtypes & ACPI_RTYPE_STRING)
+ {
+ /*
+ * 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)
{
- ReturnObject->Common.ReferenceCount--;
+ return (AE_AML_OPERAND_TYPE);
}
- ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
- "Converted Buffer to expected String at index %u",
- PackageIndex));
+ /* Allocate a new NULL string object */
+
+ NewObject = AcpiUtCreateStringObject (0);
+ if (!NewObject)
+ {
+ return (AE_NO_MEMORY);
+ }
}
else
{
- ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
- "Converted Buffer to expected String"));
+ return (AE_AML_OPERAND_TYPE);
}
+ break;
- /* Delete old object, install the new return object */
-
- AcpiUtRemoveReference (ReturnObject);
- *ReturnObjectPtr = NewObject;
- Data->Flags |= ACPI_OBJECT_REPAIRED;
- return (AE_OK);
default:
- break;
+
+ /* We cannot repair this object */
+
+ return (AE_AML_OPERAND_TYPE);
+ }
+
+ /* 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.
+ */
+ if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT)
+ {
+ NewObject->Common.ReferenceCount =
+ ReturnObject->Common.ReferenceCount;
+
+ if (ReturnObject->Common.ReferenceCount > 1)
+ {
+ ReturnObject->Common.ReferenceCount--;
+ }
+
+ ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
+ "Converted %s to expected %s at index %u",
+ AcpiUtGetObjectTypeName (ReturnObject),
+ AcpiUtGetObjectTypeName (NewObject), PackageIndex));
}
+ else
+ {
+ ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
+ "Converted %s to expected %s",
+ AcpiUtGetObjectTypeName (ReturnObject),
+ AcpiUtGetObjectTypeName (NewObject)));
+ }
+
+ /* Delete old object, install the new return object */
- return (AE_AML_OPERAND_TYPE);
+ AcpiUtRemoveReference (ReturnObject);
+ *ReturnObjectPtr = NewObject;
+ Data->Flags |= ACPI_OBJECT_REPAIRED;
+ return (AE_OK);
}
OpenPOWER on IntegriCloud