summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNate Lawson <njl@FreeBSD.org>2003-11-21 21:24:31 +0000
committerNate Lawson <njl@FreeBSD.org>2003-11-21 21:24:31 +0000
commitbeb443da7a6b182a08e3c3ae3954b48feec005d6 (patch)
treefc0a1b6055549cd259c3bfae5b2021f648326ebc
parent847c562d46cc7fb651d10fd9f93d6520535ab583 (diff)
downloadsrc-test2-beb443da7a6b182a08e3c3ae3954b48feec005d6.tar.gz
src-test2-beb443da7a6b182a08e3c3ae3954b48feec005d6.zip
Update code for checking the reference count and performing the final
delete of objects. Also revert our temporary workaround in dsmthdat.c that always copied objects. This is the correct fix for errors evaluating _BST (and GBST) on IBM Thinkpads where an argument (Arg3) was returned to the caller and the object was freed while still in use. This will be in a future ACPI-CA dist. Thanks to: kochi@netbsd.org, shaohua.li@intel.com
Notes
Notes: svn path=/vendor-sys/acpica/dist/; revision=122945
-rw-r--r--sys/contrib/dev/acpica/dsmthdat.c30
-rw-r--r--sys/contrib/dev/acpica/utdelete.c40
2 files changed, 45 insertions, 25 deletions
diff --git a/sys/contrib/dev/acpica/dsmthdat.c b/sys/contrib/dev/acpica/dsmthdat.c
index ed3d14ef5118..3515957d2329 100644
--- a/sys/contrib/dev/acpica/dsmthdat.c
+++ b/sys/contrib/dev/acpica/dsmthdat.c
@@ -392,7 +392,6 @@ AcpiDsMethodDataSetValue (
{
ACPI_STATUS Status;
ACPI_NAMESPACE_NODE *Node;
- ACPI_OPERAND_OBJECT *NewDesc = Object;
ACPI_FUNCTION_TRACE ("DsMethodDataSetValue");
@@ -411,32 +410,17 @@ AcpiDsMethodDataSetValue (
return_ACPI_STATUS (Status);
}
- /*
- * If the object has just been created and is not attached to anything,
- * (the reference count is 1), then we can just store it directly into
- * the arg/local. Otherwise, we must copy it.
+ /*
+ * Increment ref count so object can't be deleted while installed.
+ * NOTE: We do not copy the object in order to preserve the call by
+ * reference semantics of ACPI Control Method invocation.
+ * (See ACPI Specification 2.0C)
*/
- if (Object->Common.ReferenceCount > 1)
- {
- Status = AcpiUtCopyIobjectToIobject (Object, &NewDesc, WalkState);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
-
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object Copied %p, new %p\n",
- Object, NewDesc));
- }
- else
- {
- /* Increment ref count so object can't be deleted while installed */
-
- AcpiUtAddReference (NewDesc);
- }
+ AcpiUtAddReference (Object);
/* Install the object */
- Node->Object = NewDesc;
+ Node->Object = Object;
return_ACPI_STATUS (Status);
}
diff --git a/sys/contrib/dev/acpica/utdelete.c b/sys/contrib/dev/acpica/utdelete.c
index 56f546b554df..36da0ff484e8 100644
--- a/sys/contrib/dev/acpica/utdelete.c
+++ b/sys/contrib/dev/acpica/utdelete.c
@@ -510,6 +510,7 @@ AcpiUtUpdateObjectReference (
UINT32 i;
ACPI_GENERIC_STATE *StateList = NULL;
ACPI_GENERIC_STATE *State;
+ ACPI_OPERAND_OBJECT *tmp;
ACPI_FUNCTION_TRACE_PTR ("UtUpdateObjectReference", Object);
@@ -546,8 +547,15 @@ AcpiUtUpdateObjectReference (
{
case ACPI_TYPE_DEVICE:
- AcpiUtUpdateRefCount (Object->Device.SystemNotify, Action);
- AcpiUtUpdateRefCount (Object->Device.DeviceNotify, Action);
+ tmp = Object->Device.SystemNotify;
+ if (tmp && (tmp->Common.ReferenceCount <= 1) && Action == REF_DECREMENT)
+ Object->Device.SystemNotify = NULL;
+ AcpiUtUpdateRefCount (tmp, Action);
+
+ tmp = Object->Device.DeviceNotify;
+ if (tmp && (tmp->Common.ReferenceCount <= 1) && Action == REF_DECREMENT)
+ Object->Device.DeviceNotify = NULL;
+ AcpiUtUpdateRefCount (tmp, Action);
break;
@@ -570,6 +578,10 @@ AcpiUtUpdateObjectReference (
{
goto ErrorExit;
}
+
+ tmp = Object->Package.Elements[i];
+ if (tmp && (tmp->Common.ReferenceCount <= 1) && Action == REF_DECREMENT)
+ Object->Package.Elements[i] = NULL;
}
break;
@@ -582,6 +594,10 @@ AcpiUtUpdateObjectReference (
{
goto ErrorExit;
}
+
+ tmp = Object->BufferField.BufferObj;
+ if (tmp && (tmp->Common.ReferenceCount <= 1) && Action == REF_DECREMENT)
+ Object->BufferField.BufferObj = NULL;
break;
@@ -593,6 +609,10 @@ AcpiUtUpdateObjectReference (
{
goto ErrorExit;
}
+
+ tmp = Object->Field.RegionObj;
+ if (tmp && (tmp->Common.ReferenceCount <= 1) && Action == REF_DECREMENT)
+ Object->Field.RegionObj = NULL;
break;
@@ -605,12 +625,20 @@ AcpiUtUpdateObjectReference (
goto ErrorExit;
}
+ tmp = Object->BankField.BankObj;
+ if (tmp && (tmp->Common.ReferenceCount <= 1) && Action == REF_DECREMENT)
+ Object->BankField.BankObj = NULL;
+
Status = AcpiUtCreateUpdateStateAndPush (
Object->BankField.RegionObj, Action, &StateList);
if (ACPI_FAILURE (Status))
{
goto ErrorExit;
}
+
+ tmp = Object->BankField.RegionObj;
+ if (tmp && (tmp->Common.ReferenceCount <= 1) && Action == REF_DECREMENT)
+ Object->BankField.RegionObj = NULL;
break;
@@ -623,12 +651,20 @@ AcpiUtUpdateObjectReference (
goto ErrorExit;
}
+ tmp = Object->IndexField.IndexObj;
+ if (tmp && (tmp->Common.ReferenceCount <= 1) && Action == REF_DECREMENT)
+ Object->IndexField.IndexObj = NULL;
+
Status = AcpiUtCreateUpdateStateAndPush (
Object->IndexField.DataObj, Action, &StateList);
if (ACPI_FAILURE (Status))
{
goto ErrorExit;
}
+
+ tmp = Object->IndexField.DataObj;
+ if (tmp && (tmp->Common.ReferenceCount <= 1) && Action == REF_DECREMENT)
+ Object->IndexField.DataObj = NULL;
break;