patch-2.4.0-test3 linux/drivers/acpi/dispatcher/dsmthdat.c

Next file: linux/drivers/acpi/dispatcher/dsobject.c
Previous file: linux/drivers/acpi/dispatcher/dsmethod.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test2/linux/drivers/acpi/dispatcher/dsmthdat.c linux/drivers/acpi/dispatcher/dsmthdat.c
@@ -0,0 +1,682 @@
+
+/******************************************************************************
+ *
+ * Module Name: dsmthdat - control method arguments and local variables
+ *
+ *****************************************************************************/
+
+/*
+ *  Copyright (C) 2000 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "parser.h"
+#include "dispatch.h"
+#include "interp.h"
+#include "amlcode.h"
+#include "namesp.h"
+
+
+#define _COMPONENT          DISPATCHER
+	 MODULE_NAME         ("dsmthdat");
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ds_method_data_init
+ *
+ * PARAMETERS:  *Obj_desc
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize the data structures that hold the method's arguments
+ *              and locals.  The data struct is an array of NTEs for each.
+ *              This allows Ref_of and De_ref_of to work properly for these
+ *              special data types.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ds_method_data_init (
+	ACPI_WALK_STATE         *walk_state)
+{
+	u32                     i;
+
+
+	/*
+	 * Walk_state fields are initialized to zero by the
+	 * Acpi_cm_callocate().
+	 *
+	 * An NTE is assigned to each argument and local so
+	 * that Ref_of() can return a pointer to the NTE.
+	 */
+
+	/* Init the method arguments */
+
+	for (i = 0; i < MTH_NUM_ARGS; i++) {
+		MOVE_UNALIGNED32_TO_32 (&walk_state->arguments[i].name,
+				 NAMEOF_ARG_NTE);
+
+		walk_state->arguments[i].name           |= (i << 24);
+		walk_state->arguments[i].data_type      = ACPI_DESC_TYPE_NAMED;
+		walk_state->arguments[i].type           =
+				   INTERNAL_TYPE_METHOD_ARGUMENT;
+	}
+
+	/* Init the method locals */
+
+	for (i = 0; i < MTH_NUM_LOCALS; i++) {
+		MOVE_UNALIGNED32_TO_32 (&walk_state->local_variables[i].name,
+				 NAMEOF_LOCAL_NTE);
+
+		walk_state->local_variables[i].name     |= (i << 24);
+		walk_state->local_variables[i].data_type = ACPI_DESC_TYPE_NAMED;
+		walk_state->local_variables[i].type     =
+				   INTERNAL_TYPE_METHOD_LOCAL_VAR;
+	}
+
+
+	return (AE_OK);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ds_method_data_delete_all
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Delete method locals and arguments.  Arguments are only
+ *              deleted if this method was called from another method.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ds_method_data_delete_all (
+	ACPI_WALK_STATE         *walk_state)
+{
+	u32                     index;
+	ACPI_OBJECT_INTERNAL    *object;
+
+
+	/* Delete the locals */
+
+	for (index = 0; index < MTH_NUM_LOCALS; index++) {
+		object = walk_state->local_variables[index].object;
+		if (object) {
+			/* Remove first */
+			walk_state->local_variables[index].object = NULL;
+			/* Was given a ref when stored */
+			acpi_cm_remove_reference (object);
+	   }
+	}
+
+
+	/* Delete the arguments */
+
+	for (index = 0; index < MTH_NUM_ARGS; index++) {
+		object = walk_state->arguments[index].object;
+		if (object) {
+			/* Remove first */
+			walk_state->arguments[index].object = NULL;
+			 /* Was given a ref when stored */
+			acpi_cm_remove_reference (object);
+		}
+	}
+
+	return (AE_OK);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ds_method_data_init_args
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initialize arguments for a method
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ds_method_data_init_args (
+	ACPI_OBJECT_INTERNAL    **params,
+	u32                     max_param_count)
+{
+	ACPI_STATUS             status;
+	u32                     mindex;
+	u32                     pindex;
+
+
+	if (!params) {
+		return (AE_OK);
+	}
+
+	/* Copy passed parameters into the new method stack frame  */
+
+	for (pindex = mindex = 0;
+		(mindex < MTH_NUM_ARGS) && (pindex < max_param_count);
+		mindex++)
+	{
+		if (params[pindex]) {
+			/*
+			 * A valid parameter.
+			 * Set the current method argument to the
+			 * Params[Pindex++] argument object descriptor
+			 */
+			status = acpi_ds_method_data_set_value (MTH_TYPE_ARG,
+					 mindex,
+					 params[pindex]);
+			if (ACPI_FAILURE (status)) {
+				break;
+			}
+
+			pindex++;
+		}
+
+		else {
+			break;
+		}
+	}
+
+	return (AE_OK);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ds_method_data_get_entry
+ *
+ * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
+ *              Index               - Which local_var or argument to get
+ *              Entry               - Pointer to where a pointer to the stack
+ *                                    entry is returned.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get the address of the stack entry given by Type:Index
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ds_method_data_get_entry (
+	u32                     type,
+	u32                     index,
+	ACPI_OBJECT_INTERNAL    ***entry)
+{
+	ACPI_WALK_STATE         *walk_state;
+
+
+	walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
+
+	/*
+	 * Get the requested object.
+	 * The stack "Type" is either a Local_variable or an Argument
+	 */
+
+	switch (type)
+	{
+
+	case MTH_TYPE_LOCAL:
+
+		if (index > MTH_MAX_LOCAL) {
+			return (AE_BAD_PARAMETER);
+		}
+
+		*entry =
+			(ACPI_OBJECT_INTERNAL **) &walk_state->local_variables[index].object;
+		break;
+
+
+	case MTH_TYPE_ARG:
+
+		if (index > MTH_MAX_ARG) {
+			return (AE_BAD_PARAMETER);
+		}
+
+		*entry =
+			(ACPI_OBJECT_INTERNAL **) &walk_state->arguments[index].object;
+		break;
+
+
+	default:
+		return (AE_BAD_PARAMETER);
+	}
+
+
+	return (AE_OK);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ds_method_data_set_entry
+ *
+ * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
+ *              Index               - Which local_var or argument to get
+ *              Object              - Object to be inserted into the stack entry
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Insert an object onto the method stack at entry Type:Index.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ds_method_data_set_entry (
+	u32                     type,
+	u32                     index,
+	ACPI_OBJECT_INTERNAL    *object)
+{
+	ACPI_STATUS             status;
+	ACPI_OBJECT_INTERNAL    **entry;
+
+
+	/* Get a pointer to the stack entry to set */
+
+	status = acpi_ds_method_data_get_entry (type, index, &entry);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Increment ref count so object can't be deleted while installed */
+
+	acpi_cm_add_reference (object);
+
+	/* Install the object into the stack entry */
+
+	*entry = object;
+
+	return (AE_OK);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ds_method_data_get_type
+ *
+ * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
+ *              Index               - Which local_var or argument whose type
+ *                                      to get
+ *
+ * RETURN:      Data type of selected Arg or Local
+ *              Used only in Exec_monadic2()/Type_op.
+ *
+ ****************************************************************************/
+
+OBJECT_TYPE_INTERNAL
+acpi_ds_method_data_get_type (
+	u32                     type,
+	u32                     index)
+{
+	ACPI_STATUS             status;
+	ACPI_OBJECT_INTERNAL    **entry;
+	ACPI_OBJECT_INTERNAL    *object;
+
+
+	/* Get a pointer to the requested stack entry */
+
+	status = acpi_ds_method_data_get_entry (type, index, &entry);
+	if (ACPI_FAILURE (status)) {
+		return ((ACPI_TYPE_NOT_FOUND));
+	}
+
+	/* Get the object from the method stack */
+
+	object = *entry;
+
+	/* Get the object type */
+
+	if (!object) {
+		/* Any == 0 => "uninitialized" -- see spec 15.2.3.5.2.28 */
+		return (ACPI_TYPE_ANY);
+	}
+
+	return (object->common.type);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ds_method_data_get_nte
+ *
+ * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
+ *              Index               - Which local_var or argument whose type
+ *                                      to get
+ *
+ * RETURN:      Get the NTE associated with a local or arg.
+ *
+ ****************************************************************************/
+
+ACPI_NAMED_OBJECT*
+acpi_ds_method_data_get_nte (
+	u32                     type,
+	u32                     index)
+{
+	ACPI_NAMED_OBJECT       *entry = NULL;
+	ACPI_WALK_STATE         *walk_state;
+
+
+	walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
+
+
+	switch (type)
+	{
+
+	case MTH_TYPE_LOCAL:
+
+		if (index > MTH_MAX_LOCAL) {
+			return (entry);
+		}
+
+		entry =  &walk_state->local_variables[index];
+		break;
+
+
+	case MTH_TYPE_ARG:
+
+		if (index > MTH_MAX_ARG) {
+			return (entry);
+		}
+
+		entry = &walk_state->arguments[index];
+		break;
+
+
+	default:
+		break;
+	}
+
+
+	return (entry);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ds_method_data_get_value
+ *
+ * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
+ *              Index               - Which local_var or argument to get
+ *              *Dest_desc           - Descriptor into which selected Arg
+ *                                    or Local value should be copied
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Retrieve value of selected Arg or Local from the method frame
+ *              at the current top of the method stack.
+ *              Used only in Acpi_aml_resolve_to_value().
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ds_method_data_get_value (
+	u32                     type,
+	u32                     index,
+	ACPI_OBJECT_INTERNAL    **dest_desc)
+{
+	ACPI_STATUS             status;
+	ACPI_OBJECT_INTERNAL    **entry;
+	ACPI_OBJECT_INTERNAL    *object;
+
+
+	/* Validate the object descriptor */
+
+	if (!dest_desc) {
+		return (AE_BAD_PARAMETER);
+	}
+
+
+	/* Get a pointer to the requested method stack entry */
+
+	status = acpi_ds_method_data_get_entry (type, index, &entry);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Get the object from the method stack */
+
+	object = *entry;
+
+
+	/* Examine the returned object, it must be valid. */
+
+	if (!object) {
+		/*
+		 * Index points to uninitialized object stack value.
+		 * This means that either 1) The expected argument was
+		 * not passed to the method, or 2) A local variable
+		 * was referenced by the method (via the ASL)
+		 * before it was initialized.  Either case is an error.
+		 */
+
+		switch (type)
+		{
+		case MTH_TYPE_ARG:
+			return (AE_AML_UNINITIALIZED_ARG);
+			break;
+
+		case MTH_TYPE_LOCAL:
+			return (AE_AML_UNINITIALIZED_LOCAL);
+			break;
+		}
+	}
+
+
+	/*
+	 * Index points to initialized and valid object stack value.
+	 * Return an additional reference to the object
+	 */
+
+	*dest_desc = object;
+	acpi_cm_add_reference (object);
+
+	return (AE_OK);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ds_method_data_delete_value
+ *
+ * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
+ *              Index               - Which local_var or argument to delete
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Delete the entry at Type:Index on the method stack.  Inserts
+ *              a null into the stack slot after the object is deleted.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ds_method_data_delete_value (
+	u32                     type,
+	u32                     index)
+{
+	ACPI_STATUS             status;
+	ACPI_OBJECT_INTERNAL    **entry;
+	ACPI_OBJECT_INTERNAL    *object;
+
+
+	/* Get a pointer to the requested entry */
+
+	status = acpi_ds_method_data_get_entry (type, index, &entry);
+	if (ACPI_FAILURE (status)) {
+		return (status);
+	}
+
+	/* Get the current entry in this slot k */
+
+	object = *entry;
+
+	/*
+	 * Undefine the Arg or Local by setting its descriptor
+	 * pointer to NULL. Locals/Args can contain both
+	 * ACPI_OBJECT_INTERNALS and ACPI_NAMED_OBJECTs
+	 */
+	*entry = NULL;
+
+
+	if ((object) &&
+		(VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_INTERNAL)))
+	{
+		/*
+		 * There is a valid object in this slot
+		 * Decrement the reference count by one to balance the
+		 * increment when the object was stored in the slot.
+		 */
+
+		acpi_cm_remove_reference (object);
+	}
+
+
+	return (AE_OK);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    Acpi_ds_method_data_set_value
+ *
+ * PARAMETERS:  Type                - Either MTH_TYPE_LOCAL or MTH_TYPE_ARG
+ *              Index               - Which local_var or argument to set
+ *              *Src_desc           - Value to be stored
+ *              *Dest_desc          - Descriptor into which *Src_desc
+ *                                    can be copied, or NULL if one must
+ *                                    be allocated for the purpose.  If
+ *                                    provided, this descriptor will be
+ *                                    used for the new value.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Store a value in an Arg or Local.  The Src_desc is installed
+ *              as the new value for the Arg or Local and the reference count
+ *              is incremented.
+ *
+ ****************************************************************************/
+
+ACPI_STATUS
+acpi_ds_method_data_set_value (
+	u32                     type,
+	u32                     index,
+	ACPI_OBJECT_INTERNAL    *src_desc)
+{
+	ACPI_STATUS             status;
+	ACPI_OBJECT_INTERNAL    **entry;
+
+
+	/* Parameter validation */
+
+	if (!src_desc) {
+		return (AE_BAD_PARAMETER);
+	}
+
+
+	/* Get a pointer to the requested method stack entry */
+
+	status = acpi_ds_method_data_get_entry (type, index, &entry);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	if (*entry == src_desc) {
+		goto cleanup;
+	}
+
+
+	/*
+	 * If there is an object already in this slot, we either
+	 * have to delete it, or if this is an argument and there
+	 * is an object reference stored there, we have to do
+	 * an indirect store!
+	 */
+
+	if (*entry) {
+		/*
+		 * Check for an indirect store if an argument
+		 * contains an object reference (stored as an NTE).
+		 * We don't allow this automatic dereferencing for
+		 * locals, since a store to a local should overwrite
+		 * anything there, including an object reference.
+		 *
+		 * If both Arg0 and Local0 contain Ref_of (Local4):
+		 *
+		 * Store (1, Arg0)             - Causes indirect store to local4
+		 * Store (1, Local0)           - Stores 1 in local0, overwriting
+		 *                                  the reference to local4
+		 * Store (1, De_refof (Local0)) - Causes indirect store to local4
+		 *
+		 * Weird, but true.
+		 */
+
+		if ((type == MTH_TYPE_ARG) &&
+			(VALID_DESCRIPTOR_TYPE (*entry, ACPI_DESC_TYPE_NAMED)))
+		{
+			/* Detach an existing object from the NTE */
+
+			acpi_ns_detach_object (*entry);
+
+			/*
+			 * Store this object into the NTE
+			 * (do the indirect store)
+			 */
+
+			status = acpi_ns_attach_object (*entry, src_desc,
+					   src_desc->common.type);
+			return (status);
+		}
+
+
+		/*
+		 * Otherwise, just delete the existing object
+		 * before storing the new one
+		 */
+
+		acpi_ds_method_data_delete_value (type, index);
+	}
+
+
+	/*
+	 * Install the Obj_stack descriptor (*Src_desc) into
+	 * the descriptor for the Arg or Local.
+	 * Install the new object in the stack entry
+	 * (increments the object reference count by one)
+	 */
+
+	status = acpi_ds_method_data_set_entry (type, index, src_desc);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	/* Normal exit */
+
+	return (AE_OK);
+
+
+	/* Error exit */
+
+cleanup:
+
+	return (status);
+}
+

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)