The upstream maintainer just e-mailed me a possible fix for the
problem and it looks very promising. Please try the attached patch.
Note the patch reverts r233555 and applies the fix. This patch is
also available from here:
http://people.freebsd.org/~jkim/acpi_refcnt.diff
Thanks!
Jung-uk Kim
Index: sys/contrib/dev/acpica/include/aclocal.h
===
--- sys/contrib/dev/acpica/include/aclocal.h(revision 233578)
+++ sys/contrib/dev/acpica/include/aclocal.h(working copy)
@@ -424,6 +424,7 @@ typedef struct acpi_predefined_data
/* Defines for Flags field above */
#define ACPI_OBJECT_REPAIRED1
+#define ACPI_OBJECT_WRAPPED 2
/*
Index: sys/contrib/dev/acpica/include/acnamesp.h
===
--- sys/contrib/dev/acpica/include/acnamesp.h (revision 233578)
+++ sys/contrib/dev/acpica/include/acnamesp.h (working copy)
@@ -368,8 +368,9 @@ AcpiNsRepairObject (
ACPI_OPERAND_OBJECT **ReturnObjectPtr);
ACPI_STATUS
-AcpiNsRepairPackageList (
+AcpiNsWrapWithPackage (
ACPI_PREDEFINED_DATA*Data,
+ACPI_OPERAND_OBJECT *OriginalObject,
ACPI_OPERAND_OBJECT **ObjDescPtr);
ACPI_STATUS
Index: sys/contrib/dev/acpica/components/namespace/nsrepair.c
===
--- sys/contrib/dev/acpica/components/namespace/nsrepair.c (revision
233578)
+++ sys/contrib/dev/acpica/components/namespace/nsrepair.c (working copy)
@@ -74,11 +74,10 @@
* Buffer -> String
* Buffer -> Package of Integers
* Package -> Package of one Package
+ * An incorrect standalone object is wrapped with required outer package
*
* Additional possible repairs:
- *
* Required package elements that are NULL replaced by Integer/String/Buffer
- * Incorrect standalone package wrapped with required outer package
*
**/
@@ -100,12 +99,7 @@ AcpiNsConvertToBuffer (
ACPI_OPERAND_OBJECT *OriginalObject,
ACPI_OPERAND_OBJECT **ReturnObject);
-static ACPI_STATUS
-AcpiNsConvertToPackage (
-ACPI_OPERAND_OBJECT *OriginalObject,
-ACPI_OPERAND_OBJECT **ReturnObject);
-
/***
*
* FUNCTION:AcpiNsRepairObject
@@ -172,10 +166,24 @@ AcpiNsRepairObject (
}
if (ExpectedBtypes & ACPI_RTYPE_PACKAGE)
{
-Status = AcpiNsConvertToPackage (ReturnObject, &NewObject);
+/*
+ * A package is expected. We will wrap the existing object with a
+ * new package object. It is often the case that if a variable-length
+ * package is required, but there is only a single object needed, the
+ * BIOS will return that object instead of wrapping it with a Package
+ * object. Note: after the wrapping, the package will be validated
+ * for correct contents (expected object type or types).
+ */
+Status = AcpiNsWrapWithPackage (Data, ReturnObject, &NewObject);
if (ACPI_SUCCESS (Status))
{
-goto ObjectRepaired;
+/*
+ * The original object just had its reference count
+ * incremented for being inserted into the new package.
+ */
+*ReturnObjectPtr = NewObject; /* New Package object */
+Data->Flags |= ACPI_OBJECT_REPAIRED;
+return (AE_OK);
}
}
@@ -188,24 +196,30 @@ 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.
- */
if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT)
{
-NewObject->Common.ReferenceCount =
-ReturnObject->Common.ReferenceCount;
+/*
+ * The original object is a package element. We need to
+ * decrement the reference count of the original object,
+ * for removing it from the package.
+ *
+ * However, if the original object was just wrapped with a
+ * package object as part of the repair, we don't need to
+ * change the reference count.
+ */
+if (!(Data->Flags & ACPI_OBJECT_WRAPPED))
+{
+NewObject->Common.ReferenceCount =
+ReturnObject->Common.ReferenceCount;
-if (ReturnObject->Common.ReferenceCount > 1)
-{
-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\