diff options
Diffstat (limited to 'sys/contrib/dev/acpica/nseval.c')
-rw-r--r-- | sys/contrib/dev/acpica/nseval.c | 518 |
1 files changed, 109 insertions, 409 deletions
diff --git a/sys/contrib/dev/acpica/nseval.c b/sys/contrib/dev/acpica/nseval.c index e2ca5594dc5c..c44af2d904e8 100644 --- a/sys/contrib/dev/acpica/nseval.c +++ b/sys/contrib/dev/acpica/nseval.c @@ -1,8 +1,7 @@ /******************************************************************************* * - * Module Name: nseval - Object evaluation interfaces -- includes control - * method lookup and execution. - * $Revision: 1.134 $ + * Module Name: nseval - Object evaluation, includes control method execution + * $Revision: 1.144 $ * ******************************************************************************/ @@ -10,7 +9,7 @@ * * 1. Copyright Notice * - * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp. + * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp. * All rights reserved. * * 2. License @@ -127,221 +126,15 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME ("nseval") -/* Local prototypes */ - -static ACPI_STATUS -AcpiNsExecuteControlMethod ( - ACPI_PARAMETER_INFO *Info); - -static ACPI_STATUS -AcpiNsGetObjectValue ( - ACPI_PARAMETER_INFO *Info); - - -/******************************************************************************* - * - * FUNCTION: AcpiNsEvaluateRelative - * - * PARAMETERS: Pathname - Name of method to execute, If NULL, the - * handle is the object to execute - * Info - Method info block, contains: - * ReturnObject - Where to put method's return value (if - * any). If NULL, no value is returned. - * Params - List of parameters to pass to the method, - * terminated by NULL. Params itself may be - * NULL if no parameters are being passed. - * - * RETURN: Status - * - * DESCRIPTION: Evaluate the object or find and execute the requested method - * - * MUTEX: Locks Namespace - * - ******************************************************************************/ - -ACPI_STATUS -AcpiNsEvaluateRelative ( - char *Pathname, - ACPI_PARAMETER_INFO *Info) -{ - ACPI_STATUS Status; - ACPI_NAMESPACE_NODE *Node = NULL; - ACPI_GENERIC_STATE *ScopeInfo; - char *InternalPath = NULL; - - - ACPI_FUNCTION_TRACE ("NsEvaluateRelative"); - - - /* - * Must have a valid object handle - */ - if (!Info || !Info->Node) - { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - - /* Build an internal name string for the method */ - - Status = AcpiNsInternalizeName (Pathname, &InternalPath); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - - ScopeInfo = AcpiUtCreateGenericState (); - if (!ScopeInfo) - { - goto Cleanup1; - } - - /* Get the prefix handle and Node */ - - Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (Status)) - { - goto Cleanup; - } - - Info->Node = AcpiNsMapHandleToNode (Info->Node); - if (!Info->Node) - { - (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); - Status = AE_BAD_PARAMETER; - goto Cleanup; - } - - /* Lookup the name in the namespace */ - - ScopeInfo->Scope.Node = Info->Node; - Status = AcpiNsLookup (ScopeInfo, InternalPath, ACPI_TYPE_ANY, - ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, - &Node); - - (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); - - if (ACPI_FAILURE (Status)) - { - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Object [%s] not found [%s]\n", - Pathname, AcpiFormatException (Status))); - goto Cleanup; - } - - /* - * Now that we have a handle to the object, we can attempt to evaluate it. - */ - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", - Pathname, Node, AcpiNsGetAttachedObject (Node))); - - Info->Node = Node; - Status = AcpiNsEvaluateByHandle (Info); - - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n", - Pathname)); - -Cleanup: - AcpiUtDeleteGenericState (ScopeInfo); - -Cleanup1: - ACPI_MEM_FREE (InternalPath); - return_ACPI_STATUS (Status); -} - /******************************************************************************* * - * FUNCTION: AcpiNsEvaluateByName + * FUNCTION: AcpiNsEvaluate * - * PARAMETERS: Pathname - Fully qualified pathname to the object - * Info - Method info block, contains: - * ReturnObject - Where to put method's return value (if - * any). If NULL, no value is returned. - * Params - List of parameters to pass to the method, - * terminated by NULL. Params itself may be - * NULL if no parameters are being passed. - * - * RETURN: Status - * - * DESCRIPTION: Evaluate the object or rind and execute the requested method - * passing the given parameters - * - * MUTEX: Locks Namespace - * - ******************************************************************************/ - -ACPI_STATUS -AcpiNsEvaluateByName ( - char *Pathname, - ACPI_PARAMETER_INFO *Info) -{ - ACPI_STATUS Status; - char *InternalPath = NULL; - - - ACPI_FUNCTION_TRACE ("NsEvaluateByName"); - - - /* Build an internal name string for the method */ - - Status = AcpiNsInternalizeName (Pathname, &InternalPath); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - - Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (Status)) - { - goto Cleanup; - } - - /* Lookup the name in the namespace */ - - Status = AcpiNsLookup (NULL, InternalPath, ACPI_TYPE_ANY, - ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, - &Info->Node); - - (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); - - if (ACPI_FAILURE (Status)) - { - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, - "Object at [%s] was not found, status=%.4X\n", - Pathname, Status)); - goto Cleanup; - } - - /* - * Now that we have a handle to the object, we can attempt to evaluate it. - */ - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", - Pathname, Info->Node, AcpiNsGetAttachedObject (Info->Node))); - - Status = AcpiNsEvaluateByHandle (Info); - - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n", - Pathname)); - - -Cleanup: - - /* Cleanup */ - - if (InternalPath) - { - ACPI_MEM_FREE (InternalPath); - } - - return_ACPI_STATUS (Status); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiNsEvaluateByHandle - * - * PARAMETERS: Info - Method info block, contains: - * Node - Method/Object Node to execute + * PARAMETERS: Info - Evaluation info block, contains: + * PrefixNode - Prefix or Method/Object Node to execute + * Pathname - Name of method to execute, If NULL, the + * Node is the object to execute * Parameters - List of parameters to pass to the method, * terminated by NULL. Params itself may be * NULL if no parameters are being passed. @@ -350,34 +143,26 @@ Cleanup: * ParameterType - Type of Parameter list * ReturnObject - Where to put method's return value (if * any). If NULL, no value is returned. + * Flags - ACPI_IGNORE_RETURN_VALUE to delete return * * RETURN: Status * - * DESCRIPTION: Evaluate object or execute the requested method passing the - * given parameters + * DESCRIPTION: Execute a control method or return the current value of an + * ACPI namespace object. * - * MUTEX: Locks Namespace + * MUTEX: Locks interpreter * ******************************************************************************/ ACPI_STATUS -AcpiNsEvaluateByHandle ( - ACPI_PARAMETER_INFO *Info) +AcpiNsEvaluate ( + ACPI_EVALUATE_INFO *Info) { ACPI_STATUS Status; - ACPI_FUNCTION_TRACE ("NsEvaluateByHandle"); - - - /* Check if namespace has been initialized */ - - if (!AcpiGbl_RootNode) - { - return_ACPI_STATUS (AE_NO_NAMESPACE); - } + ACPI_FUNCTION_TRACE (NsEvaluate); - /* Parameter Validation */ if (!Info) { @@ -388,229 +173,144 @@ AcpiNsEvaluateByHandle ( Info->ReturnObject = NULL; - /* Get the prefix handle and Node */ - - Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); + /* + * Get the actual namespace node for the target object. Handles these cases: + * + * 1) Null node, Pathname (absolute path) + * 2) Node, Pathname (path relative to Node) + * 3) Node, Null Pathname + */ + Status = AcpiNsGetNode (Info->PrefixNode, Info->Pathname, + ACPI_NS_NO_UPSEARCH, &Info->ResolvedNode); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } - Info->Node = AcpiNsMapHandleToNode (Info->Node); - if (!Info->Node) - { - (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - /* * For a method alias, we must grab the actual method node so that proper * scoping context will be established before execution. */ - if (AcpiNsGetType (Info->Node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) + if (AcpiNsGetType (Info->ResolvedNode) == ACPI_TYPE_LOCAL_METHOD_ALIAS) { - Info->Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Info->Node->Object); + Info->ResolvedNode = + ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Info->ResolvedNode->Object); } + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", Info->Pathname, + Info->ResolvedNode, AcpiNsGetAttachedObject (Info->ResolvedNode))); + /* * Two major cases here: - * 1) The object is an actual control method -- execute it. - * 2) The object is not a method -- just return it's current value * - * In both cases, the namespace is unlocked by the AcpiNs* procedure + * 1) The object is a control method -- execute it + * 2) The object is not a method -- just return it's current value */ - if (AcpiNsGetType (Info->Node) == ACPI_TYPE_METHOD) - { - /* - * Case 1) We have an actual control method to execute - */ - Status = AcpiNsExecuteControlMethod (Info); - } - else + if (AcpiNsGetType (Info->ResolvedNode) == ACPI_TYPE_METHOD) { /* - * Case 2) Object is NOT a method, just return its current value + * 1) Object is a control method - execute it */ - Status = AcpiNsGetObjectValue (Info); - } - - /* - * Check if there is a return value on the stack that must be dealt with - */ - if (Status == AE_CTRL_RETURN_VALUE) - { - /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ - - Status = AE_OK; - } - - /* - * Namespace was unlocked by the handling AcpiNs* function, so we - * just return - */ - return_ACPI_STATUS (Status); -} + /* Verify that there is a method object associated with this node */ -/******************************************************************************* - * - * FUNCTION: AcpiNsExecuteControlMethod - * - * PARAMETERS: Info - Method info block, contains: - * Node - Method Node to execute - * ObjDesc - Method object - * Parameters - List of parameters to pass to the method, - * terminated by NULL. Params itself may be - * NULL if no parameters are being passed. - * ReturnObject - Where to put method's return value (if - * any). If NULL, no value is returned. - * ParameterType - Type of Parameter list - * ReturnObject - Where to put method's return value (if - * any). If NULL, no value is returned. - * - * RETURN: Status - * - * DESCRIPTION: Execute the requested method passing the given parameters - * - * MUTEX: Assumes namespace is locked - * - ******************************************************************************/ - -static ACPI_STATUS -AcpiNsExecuteControlMethod ( - ACPI_PARAMETER_INFO *Info) -{ - ACPI_STATUS Status; - - - ACPI_FUNCTION_TRACE ("NsExecuteControlMethod"); - - - /* Verify that there is a method associated with this object */ - - Info->ObjDesc = AcpiNsGetAttachedObject (Info->Node); - if (!Info->ObjDesc) - { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No attached method object\n")); - - (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); - return_ACPI_STATUS (AE_NULL_OBJECT); - } + Info->ObjDesc = AcpiNsGetAttachedObject (Info->ResolvedNode); + if (!Info->ObjDesc) + { + ACPI_ERROR ((AE_INFO, "Control method has no attached sub-object")); + return_ACPI_STATUS (AE_NULL_OBJECT); + } - ACPI_DUMP_PATHNAME (Info->Node, "Execute Method:", - ACPI_LV_INFO, _COMPONENT); + ACPI_DUMP_PATHNAME (Info->ResolvedNode, "Execute Method:", + ACPI_LV_INFO, _COMPONENT); - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Method at AML address %p Length %X\n", - Info->ObjDesc->Method.AmlStart + 1, Info->ObjDesc->Method.AmlLength - 1)); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, + "Method at AML address %p Length %X\n", + Info->ObjDesc->Method.AmlStart + 1, + Info->ObjDesc->Method.AmlLength - 1)); - /* - * Unlock the namespace before execution. This allows namespace access - * via the external Acpi* interfaces while a method is being executed. - * However, any namespace deletion must acquire both the namespace and - * interpreter locks to ensure that no thread is using the portion of the - * namespace that is being deleted. - */ - Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); + /* + * Any namespace deletion must acquire both the namespace and + * interpreter locks to ensure that no thread is using the portion of + * the namespace that is being deleted. + * + * Execute the method via the interpreter. The interpreter is locked + * here before calling into the AML parser + */ + AcpiExEnterInterpreter (); + Status = AcpiPsExecuteMethod (Info); + AcpiExExitInterpreter (); } - - /* - * Execute the method via the interpreter. The interpreter is locked - * here before calling into the AML parser - */ - Status = AcpiExEnterInterpreter (); - if (ACPI_FAILURE (Status)) + else { - return_ACPI_STATUS (Status); - } - - Status = AcpiPsExecuteMethod (Info); - AcpiExExitInterpreter (); - - return_ACPI_STATUS (Status); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiNsGetObjectValue - * - * PARAMETERS: Info - Method info block, contains: - * Node - Object's NS node - * ReturnObject - Where to put object value (if - * any). If NULL, no value is returned. - * - * RETURN: Status - * - * DESCRIPTION: Return the current value of the object - * - * MUTEX: Assumes namespace is locked, leaves namespace unlocked - * - ******************************************************************************/ - -static ACPI_STATUS -AcpiNsGetObjectValue ( - ACPI_PARAMETER_INFO *Info) -{ - ACPI_STATUS Status = AE_OK; - ACPI_NAMESPACE_NODE *ResolvedNode = Info->Node; - - - ACPI_FUNCTION_TRACE ("NsGetObjectValue"); + /* + * 2) Object is not a method, return its current value + */ + /* + * Objects require additional resolution steps (e.g., the Node may be + * a field that must be read, etc.) -- we can't just grab the object + * out of the node. + * + * Use ResolveNodeToValue() to get the associated value. + * + * NOTE: we can get away with passing in NULL for a walk state because + * ResolvedNode is guaranteed to not be a reference to either a method + * local or a method argument (because this interface is never called + * from a running method.) + * + * Even though we do not directly invoke the interpreter for object + * resolution, we must lock it because we could access an opregion. + * The opregion access code assumes that the interpreter is locked. + */ + AcpiExEnterInterpreter (); - /* - * Objects require additional resolution steps (e.g., the Node may be a - * field that must be read, etc.) -- we can't just grab the object out of - * the node. - */ + /* Function has a strange interface */ - /* - * Use ResolveNodeToValue() to get the associated value. This call always - * deletes ObjDesc (allocated above). - * - * NOTE: we can get away with passing in NULL for a walk state because - * ObjDesc is guaranteed to not be a reference to either a method local or - * a method argument (because this interface can only be called from the - * AcpiEvaluate external interface, never called from a running method.) - * - * Even though we do not directly invoke the interpreter for this, we must - * enter it because we could access an opregion. The opregion access code - * assumes that the interpreter is locked. - * - * We must release the namespace lock before entering the intepreter. - */ - Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } + Status = AcpiExResolveNodeToValue (&Info->ResolvedNode, NULL); + AcpiExExitInterpreter (); - Status = AcpiExEnterInterpreter (); - if (ACPI_SUCCESS (Status)) - { - Status = AcpiExResolveNodeToValue (&ResolvedNode, NULL); /* * If AcpiExResolveNodeToValue() succeeded, the return value was placed * in ResolvedNode. */ - AcpiExExitInterpreter (); - if (ACPI_SUCCESS (Status)) { Status = AE_CTRL_RETURN_VALUE; - Info->ReturnObject = ACPI_CAST_PTR - (ACPI_OPERAND_OBJECT, ResolvedNode); + Info->ReturnObject = + ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Info->ResolvedNode); + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n", Info->ReturnObject, AcpiUtGetObjectTypeName (Info->ReturnObject))); } } - /* Namespace is unlocked */ + /* + * Check if there is a return value that must be dealt with + */ + if (Status == AE_CTRL_RETURN_VALUE) + { + /* If caller does not want the return value, delete it */ + + if (Info->Flags & ACPI_IGNORE_RETURN_VALUE) + { + AcpiUtRemoveReference (Info->ReturnObject); + Info->ReturnObject = NULL; + } + + /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ + Status = AE_OK; + } + + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "*** Completed evaluation of object %s ***\n", Info->Pathname)); + + /* + * Namespace was unlocked by the handling AcpiNs* function, so we + * just return + */ return_ACPI_STATUS (Status); } |