diff options
Diffstat (limited to 'usr/src/uts/intel/io/acpica/namespace/nsxfeval.c')
| -rw-r--r-- | usr/src/uts/intel/io/acpica/namespace/nsxfeval.c | 141 |
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. * ******************************************************************************/ |
