summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/io/acpica/namespace/nsxfeval.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/intel/io/acpica/namespace/nsxfeval.c')
-rw-r--r--usr/src/uts/intel/io/acpica/namespace/nsxfeval.c141
1 files changed, 120 insertions, 21 deletions
diff --git a/usr/src/uts/intel/io/acpica/namespace/nsxfeval.c b/usr/src/uts/intel/io/acpica/namespace/nsxfeval.c
index 3b88369187..f1bc6b8d7a 100644
--- a/usr/src/uts/intel/io/acpica/namespace/nsxfeval.c
+++ b/usr/src/uts/intel/io/acpica/namespace/nsxfeval.c
@@ -2,7 +2,7 @@
*
* Module Name: nsxfeval - Public interfaces to the ACPI subsystem
* ACPI Object evaluation interfaces
- * $Revision: 1.28 $
+ * $Revision: 1.33 $
*
******************************************************************************/
@@ -10,7 +10,7 @@
*
* 1. Copyright Notice
*
- * Some or all of this work - Copyright (c) 1999 - 2006, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp.
* All rights reserved.
*
* 2. License
@@ -126,6 +126,12 @@
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME ("nsxfeval")
+/* Local prototypes */
+
+static void
+AcpiNsResolveReferences (
+ ACPI_EVALUATE_INFO *Info);
+
/*******************************************************************************
*
@@ -255,7 +261,6 @@ AcpiEvaluateObject (
ACPI_BUFFER *ReturnBuffer)
{
ACPI_STATUS Status;
- ACPI_STATUS Status2;
ACPI_EVALUATE_INFO *Info;
ACPI_SIZE BufferSpaceNeeded;
UINT32 i;
@@ -273,7 +278,6 @@ AcpiEvaluateObject (
}
Info->Pathname = Pathname;
- Info->ParameterType = ACPI_PARAM_ARGS;
/* Convert and validate the device handle */
@@ -387,6 +391,10 @@ AcpiEvaluateObject (
if (ACPI_SUCCESS (Status))
{
+ /* Dereference Index and RefOf references */
+
+ AcpiNsResolveReferences (Info);
+
/* Get the size of the returned object */
Status = AcpiUtGetObjectSize (Info->ReturnObject,
@@ -426,14 +434,12 @@ AcpiEvaluateObject (
* Delete the internal return object. NOTE: Interpreter must be
* locked to avoid race condition.
*/
- Status2 = AcpiExEnterInterpreter ();
- if (ACPI_SUCCESS (Status2))
- {
- /* Remove one reference on the return object (should delete it) */
+ AcpiExEnterInterpreter ();
- AcpiUtRemoveReference (Info->ReturnObject);
- AcpiExExitInterpreter ();
- }
+ /* Remove one reference on the return object (should delete it) */
+
+ AcpiUtRemoveReference (Info->ReturnObject);
+ AcpiExExitInterpreter ();
}
@@ -457,6 +463,82 @@ ACPI_EXPORT_SYMBOL (AcpiEvaluateObject)
/*******************************************************************************
*
+ * FUNCTION: AcpiNsResolveReferences
+ *
+ * PARAMETERS: Info - Evaluation info block
+ *
+ * RETURN: Info->ReturnObject is replaced with the dereferenced object
+ *
+ * DESCRIPTION: Dereference certain reference objects. Called before an
+ * internal return object is converted to an external ACPI_OBJECT.
+ *
+ * Performs an automatic dereference of Index and RefOf reference objects.
+ * These reference objects are not supported by the ACPI_OBJECT, so this is a
+ * last resort effort to return something useful. Also, provides compatibility
+ * with other ACPI implementations.
+ *
+ * NOTE: does not handle references within returned package objects or nested
+ * references, but this support could be added later if found to be necessary.
+ *
+ ******************************************************************************/
+
+static void
+AcpiNsResolveReferences (
+ ACPI_EVALUATE_INFO *Info)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc = NULL;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ /* We are interested in reference objects only */
+
+ if (ACPI_GET_OBJECT_TYPE (Info->ReturnObject) != ACPI_TYPE_LOCAL_REFERENCE)
+ {
+ return;
+ }
+
+ /*
+ * Two types of references are supported - those created by Index and
+ * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted
+ * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle
+ * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
+ * an ACPI_OBJECT.
+ */
+ switch (Info->ReturnObject->Reference.Class)
+ {
+ case ACPI_REFCLASS_INDEX:
+
+ ObjDesc = *(Info->ReturnObject->Reference.Where);
+ break;
+
+ case ACPI_REFCLASS_REFOF:
+
+ Node = Info->ReturnObject->Reference.Object;
+ if (Node)
+ {
+ ObjDesc = Node->Object;
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ /* Replace the existing reference object */
+
+ if (ObjDesc)
+ {
+ AcpiUtAddReference (ObjDesc);
+ AcpiUtRemoveReference (Info->ReturnObject);
+ Info->ReturnObject = ObjDesc;
+ }
+
+ return;
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiWalkNamespace
*
* PARAMETERS: Type - ACPI_OBJECT_TYPE to search for
@@ -559,7 +641,8 @@ AcpiNsGetDeviceCallback (
UINT32 Flags;
ACPI_DEVICE_ID Hid;
ACPI_COMPATIBLE_ID_LIST *Cid;
- ACPI_NATIVE_UINT i;
+ UINT32 i;
+ BOOLEAN Found;
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
@@ -588,10 +671,14 @@ AcpiNsGetDeviceCallback (
return (AE_CTRL_DEPTH);
}
- if (!(Flags & ACPI_STA_DEVICE_PRESENT))
+ if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
+ !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
{
- /* Don't examine children of the device if not present */
-
+ /*
+ * Don't examine the children of the device only when the
+ * device is neither present nor functional. See ACPI spec,
+ * description of _STA for more information.
+ */
return (AE_CTRL_DEPTH);
}
@@ -611,8 +698,10 @@ AcpiNsGetDeviceCallback (
if (ACPI_STRNCMP (Hid.Value, Info->Hid, sizeof (Hid.Value)) != 0)
{
- /* Get the list of Compatible IDs */
-
+ /*
+ * HID does not match, attempt match within the
+ * list of Compatible IDs (CIDs)
+ */
Status = AcpiUtExecute_CID (Node, &Cid);
if (Status == AE_NOT_FOUND)
{
@@ -625,19 +714,29 @@ AcpiNsGetDeviceCallback (
/* Walk the CID list */
+ Found = FALSE;
for (i = 0; i < Cid->Count; i++)
{
if (ACPI_STRNCMP (Cid->Id[i].Value, Info->Hid,
- sizeof (ACPI_COMPATIBLE_ID)) != 0)
+ sizeof (ACPI_COMPATIBLE_ID)) == 0)
{
- ACPI_FREE (Cid);
- return (AE_OK);
+ /* Found a matching CID */
+
+ Found = TRUE;
+ break;
}
}
+
ACPI_FREE (Cid);
+ if (!Found)
+ {
+ return (AE_OK);
+ }
}
}
+ /* We have a valid device, invoke the user function */
+
Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context,
ReturnValue);
return (Status);
@@ -665,7 +764,7 @@ AcpiNsGetDeviceCallback (
* value is returned to the caller.
*
* This is a wrapper for WalkNamespace, but the callback performs
- * additional filtering. Please see AcpiGetDeviceCallback.
+ * additional filtering. Please see AcpiNsGetDeviceCallback.
*
******************************************************************************/