patch-2.4.1 linux/drivers/acpi/interpreter/amstoren.c

Next file: linux/drivers/acpi/interpreter/amstorob.c
Previous file: linux/drivers/acpi/interpreter/amstore.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0/linux/drivers/acpi/interpreter/amstoren.c linux/drivers/acpi/interpreter/amstoren.c
@@ -2,13 +2,13 @@
 /******************************************************************************
  *
  * Module Name: amstoren - AML Interpreter object store support,
- *                         Store to Node (namespace object)
- *              $Revision: 24 $
+ *                        Store to Node (namespace object)
+ *              $Revision: 28 $
  *
  *****************************************************************************/
 
 /*
- *  Copyright (C) 2000 R. Byron Moore
+ *  Copyright (C) 2000, 2001 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
@@ -41,127 +41,72 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    Acpi_aml_store_object_to_node
+ * FUNCTION:    Acpi_aml_resolve_object
  *
- * PARAMETERS:  *Val_desc           - Value to be stored
- *              *Node           - Named object to recieve the value
+ * PARAMETERS:  Source_desc_ptr     - Pointer to the source object
+ *              Target_type         - Current type of the target
+ *              Walk_state          - Current walk state
  *
- * RETURN:      Status
- *
- * DESCRIPTION: Store the object to the named object.
+ * RETURN:      Status, resolved object in Source_desc_ptr.
  *
- *              The Assignment of an object to a named object is handled here
- *              The val passed in will replace the current value (if any)
- *              with the input value.
- *
- *              When storing into an object the data is converted to the
- *              target object type then stored in the object.  This means
- *              that the target object type (for an initialized target) will
- *              not be changed by a store operation.
- *
- *              NOTE: the global lock is acquired early.  This will result
- *              in the global lock being held a bit longer.  Also, if the
- *              function fails during set up we may get the lock when we
- *              don't really need it.  I don't think we care.
+ * DESCRIPTION: Resolve an object.  If the object is a reference, dereference
+ *              it and return the actual object in the Source_desc_ptr.
  *
  ******************************************************************************/
 
 ACPI_STATUS
-acpi_aml_store_object_to_node (
-	ACPI_OPERAND_OBJECT     *val_desc,
-	ACPI_NAMESPACE_NODE     *node,
+acpi_aml_resolve_object (
+	ACPI_OPERAND_OBJECT     **source_desc_ptr,
+	OBJECT_TYPE_INTERNAL    target_type,
 	ACPI_WALK_STATE         *walk_state)
 {
+	ACPI_OPERAND_OBJECT     *source_desc = *source_desc_ptr;
 	ACPI_STATUS             status = AE_OK;
-	u8                      *buffer = NULL;
-	u32                     length = 0;
-	u32                     mask;
-	u32                     new_value;
-	u8                      locked = FALSE;
-	u8                      *location=NULL;
-	ACPI_OPERAND_OBJECT     *dest_desc;
-	OBJECT_TYPE_INTERNAL    destination_type = ACPI_TYPE_ANY;
 
 
 	/*
-	 *  Assuming the parameters are valid!!!
+	 * Ensure we have a Source that can be stored in the target
 	 */
-	ACPI_ASSERT((node) && (val_desc));
+	switch (target_type)
+	{
 
-	destination_type = acpi_ns_get_type (node);
+	/* This case handles the "interchangeable" types Integer, String, and Buffer. */
 
 	/*
-	 *  First ensure we have a value that can be stored in the target
+	 * These cases all require only Integers or values that
+	 * can be converted to Integers (Strings or Buffers)
 	 */
-	switch (destination_type)
-	{
-		/* Type of Name's existing value */
-
-	case INTERNAL_TYPE_ALIAS:
-
-		/*
-		 *  Aliases are resolved by Acpi_aml_prep_operands
-		 */
-
-		status = AE_AML_INTERNAL;
-		break;
-
-
+	case ACPI_TYPE_INTEGER:
+	case ACPI_TYPE_FIELD_UNIT:
 	case INTERNAL_TYPE_BANK_FIELD:
 	case INTERNAL_TYPE_INDEX_FIELD:
-	case ACPI_TYPE_FIELD_UNIT:
-	case ACPI_TYPE_NUMBER:
-
-		/*
-		 *  These cases all require only number values or values that
-		 *  can be converted to numbers.
-		 *
-		 *  If value is not a Number, try to resolve it to one.
-		 */
-
-		if (val_desc->common.type != ACPI_TYPE_NUMBER) {
-			/*
-			 *  Initially not a number, convert
-			 */
-			status = acpi_aml_resolve_to_value (&val_desc, walk_state);
-			if (ACPI_SUCCESS (status) &&
-				(val_desc->common.type != ACPI_TYPE_NUMBER))
-			{
-				/*
-				 *  Conversion successful but still not a number
-				 */
-				status = AE_AML_OPERAND_TYPE;
-			}
-		}
-
-		break;
 
+	/*
+	 * Stores into a Field/Region or into a Buffer/String
+	 * are all essentially the same.
+	 */
 	case ACPI_TYPE_STRING:
 	case ACPI_TYPE_BUFFER:
 	case INTERNAL_TYPE_DEF_FIELD:
 
 		/*
-		 *  Storing into a Field in a region or into a buffer or into
-		 *  a string all is essentially the same.
-		 *
-		 *  If value is not a valid type, try to resolve it to one.
+		 * If Source_desc is not a valid type, try to resolve it to one.
 		 */
-
-		if ((val_desc->common.type != ACPI_TYPE_NUMBER) &&
-			(val_desc->common.type != ACPI_TYPE_BUFFER) &&
-			(val_desc->common.type != ACPI_TYPE_STRING))
+		if ((source_desc->common.type != ACPI_TYPE_INTEGER)    &&
+			(source_desc->common.type != ACPI_TYPE_BUFFER)     &&
+			(source_desc->common.type != ACPI_TYPE_STRING))
 		{
 			/*
-			 *  Initially not a valid type, convert
+			 * Initially not a valid type, convert
 			 */
-			status = acpi_aml_resolve_to_value (&val_desc, walk_state);
+			status = acpi_aml_resolve_to_value (source_desc_ptr, walk_state);
 			if (ACPI_SUCCESS (status) &&
-				(val_desc->common.type != ACPI_TYPE_NUMBER) &&
-				(val_desc->common.type != ACPI_TYPE_BUFFER) &&
-				(val_desc->common.type != ACPI_TYPE_STRING))
+				(source_desc->common.type != ACPI_TYPE_INTEGER)    &&
+				(source_desc->common.type != ACPI_TYPE_BUFFER)     &&
+				(source_desc->common.type != ACPI_TYPE_STRING))
 			{
 				/*
-				 *  Conversion successful but still not a valid type
+				 * Conversion successful but still not a valid type
 				 */
 				status = AE_AML_OPERAND_TYPE;
 			}
@@ -169,347 +114,133 @@
 		break;
 
 
-	case ACPI_TYPE_PACKAGE:
+	case INTERNAL_TYPE_ALIAS:
 
 		/*
-		 *  TBD: [Unhandled] Not real sure what to do here
+		 * Aliases are resolved by Acpi_aml_prep_operands
 		 */
-		status = AE_NOT_IMPLEMENTED;
+		status = AE_AML_INTERNAL;
 		break;
 
 
+	case ACPI_TYPE_PACKAGE:
 	default:
 
 		/*
-		 * All other types than Alias and the various Fields come here.
-		 * Store Val_desc as the new value of the Name, and set
-		 * the Name's type to that of the value being stored in it.
-		 * Val_desc reference count is incremented by Attach_object.
+		 * All other types than Alias and the various Fields come here,
+		 * including the untyped case - ACPI_TYPE_ANY.
 		 */
-
-		status = acpi_ns_attach_object (node, val_desc, val_desc->common.type);
-
-		goto clean_up_and_bail_out;
 		break;
 	}
 
-	/* Exit now if failure above */
+	return (status);
+}
 
-	if (ACPI_FAILURE (status)) {
-		goto clean_up_and_bail_out;
-	}
 
-	/*
-	 *  Get descriptor for object attached to Node
-	 */
-	dest_desc = acpi_ns_get_attached_object (node);
-	if (!dest_desc) {
-		/*
-		 *  There is no existing object attached to this Node
-		 */
-		status = AE_AML_INTERNAL;
-		goto clean_up_and_bail_out;
-	}
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_aml_store_object
+ *
+ * PARAMETERS:  Source_desc         - Object to store
+ *              Target_type         - Current type of the target
+ *              Target_desc_ptr     - Pointer to the target
+ *              Walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: "Store" an object to another object.  This may include
+ *              converting the source type to the target type (implicit
+ *              conversion), and a copy of the value of the source to
+ *              the target.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_aml_store_object (
+	ACPI_OPERAND_OBJECT     *source_desc,
+	OBJECT_TYPE_INTERNAL    target_type,
+	ACPI_OPERAND_OBJECT     **target_desc_ptr,
+	ACPI_WALK_STATE         *walk_state)
+{
+	ACPI_OPERAND_OBJECT     *target_desc = *target_desc_ptr;
+	ACPI_STATUS             status;
+
 
 	/*
-	 *  Make sure the destination Object is the same as the Node
+	 * Perform the "implicit conversion" of the source to the current type
+	 * of the target - As per the ACPI specification.
+	 *
+	 * If no conversion performed, Source_desc is left alone, otherwise it
+	 * is updated with a new object.
 	 */
-	if (dest_desc->common.type != (u8) destination_type) {
-		status = AE_AML_INTERNAL;
-		goto clean_up_and_bail_out;
+	status = acpi_aml_convert_to_target_type (target_type, &source_desc, walk_state);
+	if (ACPI_FAILURE (status)) {
+		return (status);
 	}
 
+
 	/*
-	 * Acpi_everything is ready to execute now, We have
-	 * a value we can handle, just perform the update
+	 * We now have two objects of identical types, and we can perform a
+	 * copy of the *value* of the source object.
 	 */
-
-	switch (destination_type)
+	switch (target_type)
 	{
-		/* Type of Name's existing value */
-
-	case INTERNAL_TYPE_BANK_FIELD:
-
-		/*
-		 * Get the global lock if needed
-		 */
-		locked = acpi_aml_acquire_global_lock (dest_desc->bank_field.lock_rule);
+	case ACPI_TYPE_ANY:
+	case INTERNAL_TYPE_DEF_ANY:
 
 		/*
-		 *  Set Bank value to select proper Bank
-		 *  Perform the update (Set Bank Select)
+		 * The target namespace node is uninitialized (has no target object),
+		 * and will take on the type of the source object
 		 */
 
-		status = acpi_aml_access_named_field (ACPI_WRITE,
-				 dest_desc->bank_field.bank_select,
-				 &dest_desc->bank_field.value,
-				 sizeof (dest_desc->bank_field.value));
-		if (ACPI_SUCCESS (status)) {
-			/* Set bank select successful, set data value  */
-
-			status = acpi_aml_access_named_field (ACPI_WRITE,
-					   dest_desc->bank_field.bank_select,
-					   &val_desc->bank_field.value,
-					   sizeof (val_desc->bank_field.value));
-		}
-
+		*target_desc_ptr = source_desc;
 		break;
 
 
-	case INTERNAL_TYPE_DEF_FIELD:
-
-		/*
-		 * Get the global lock if needed
-		 */
-		locked = acpi_aml_acquire_global_lock (val_desc->field.lock_rule);
+	case ACPI_TYPE_INTEGER:
 
-		/*
-		 *  Perform the update
-		 */
-
-		switch (val_desc->common.type)
-		{
-		case ACPI_TYPE_NUMBER:
-			buffer = (u8 *) &val_desc->number.value;
-			length = sizeof (val_desc->number.value);
-			break;
-
-		case ACPI_TYPE_BUFFER:
-			buffer = (u8 *) val_desc->buffer.pointer;
-			length = val_desc->buffer.length;
-			break;
-
-		case ACPI_TYPE_STRING:
-			buffer = (u8 *) val_desc->string.pointer;
-			length = val_desc->string.length;
-			break;
-		}
-
-		status = acpi_aml_access_named_field (ACPI_WRITE,
-				  node, buffer, length);
-
-		break;      /* Global Lock released below   */
-
-
-	case ACPI_TYPE_STRING:
+		target_desc->integer.value = source_desc->integer.value;
 
-		/*
-		 *  Perform the update
-		 */
-
-		switch (val_desc->common.type)
-		{
-		case ACPI_TYPE_NUMBER:
-			buffer = (u8 *) &val_desc->number.value;
-			length = sizeof (val_desc->number.value);
-			break;
-
-		case ACPI_TYPE_BUFFER:
-			buffer = (u8 *) val_desc->buffer.pointer;
-			length = val_desc->buffer.length;
-			break;
-
-		case ACPI_TYPE_STRING:
-			buffer = (u8 *) val_desc->string.pointer;
-			length = val_desc->string.length;
-			break;
-		}
-
-		/*
-		 *  Setting a string value replaces the old string
-		 */
-
-		if (length < dest_desc->string.length) {
-			/*
-			 *  Zero fill, not willing to do pointer arithmetic for
-			 *  archetecture independance.  Just clear the whole thing
-			 */
-			MEMSET(dest_desc->string.pointer, 0, dest_desc->string.length);
-			MEMCPY(dest_desc->string.pointer, buffer, length);
-		}
-		else {
-			/*
-			 *  Free the current buffer, then allocate a buffer
-			 *  large enough to hold the value
-			 */
-			if ( dest_desc->string.pointer &&
-				!acpi_tb_system_table_pointer (dest_desc->string.pointer))
-			{
-				/*
-				 *  Only free if not a pointer into the DSDT
-				 */
+		/* Truncate value if we are executing from a 32-bit ACPI table */
 
-				acpi_cm_free(dest_desc->string.pointer);
-			}
+		acpi_aml_truncate_for32bit_table (target_desc, walk_state);
+		break;
 
-			dest_desc->string.pointer = acpi_cm_allocate (length + 1);
-			dest_desc->string.length = length;
 
-			if (!dest_desc->string.pointer) {
-				status = AE_NO_MEMORY;
-				goto clean_up_and_bail_out;
-			}
+	case ACPI_TYPE_FIELD_UNIT:
 
-			MEMCPY(dest_desc->string.pointer, buffer, length);
-		}
+		status = acpi_aml_copy_integer_to_field_unit (source_desc, target_desc);
 		break;
 
 
-	case ACPI_TYPE_BUFFER:
-
-		/*
-		 *  Perform the update to the buffer
-		 */
-
-		switch (val_desc->common.type)
-		{
-		case ACPI_TYPE_NUMBER:
-			buffer = (u8 *) &val_desc->number.value;
-			length = sizeof (val_desc->number.value);
-			break;
-
-		case ACPI_TYPE_BUFFER:
-			buffer = (u8 *) val_desc->buffer.pointer;
-			length = val_desc->buffer.length;
-			break;
-
-		case ACPI_TYPE_STRING:
-			buffer = (u8 *) val_desc->string.pointer;
-			length = val_desc->string.length;
-			break;
-		}
+	case INTERNAL_TYPE_BANK_FIELD:
 
-		/*
-		 *  Buffer is a static allocation,
-		 *  only place what will fit in the buffer.
-		 */
-		if (length <= dest_desc->buffer.length) {
-			/*
-			 *  Zero fill first, not willing to do pointer arithmetic for
-			 *  archetecture independence.  Just clear the whole thing
-			 */
-			MEMSET(dest_desc->buffer.pointer, 0, dest_desc->buffer.length);
-			MEMCPY(dest_desc->buffer.pointer, buffer, length);
-		}
-		else {
-			/*
-			 *  truncate, copy only what will fit
-			 */
-			MEMCPY(dest_desc->buffer.pointer, buffer, dest_desc->buffer.length);
-		}
+		status = acpi_aml_copy_integer_to_bank_field (source_desc, target_desc);
 		break;
 
 
 	case INTERNAL_TYPE_INDEX_FIELD:
 
-		/*
-		 * Get the global lock if needed
-		 */
-		locked = acpi_aml_acquire_global_lock (dest_desc->index_field.lock_rule);
-
-		/*
-		 *  Set Index value to select proper Data register
-		 *  perform the update (Set index)
-		 */
-
-		status = acpi_aml_access_named_field (ACPI_WRITE,
-				 dest_desc->index_field.index,
-				 &dest_desc->index_field.value,
-				 sizeof (dest_desc->index_field.value));
-
-		if (ACPI_SUCCESS (status)) {
-			/* set index successful, next set Data value */
-
-			status = acpi_aml_access_named_field (ACPI_WRITE,
-					   dest_desc->index_field.data,
-					   &val_desc->number.value,
-					   sizeof (val_desc->number.value));
-		}
+		status = acpi_aml_copy_integer_to_index_field (source_desc, target_desc);
 		break;
 
 
-	case ACPI_TYPE_FIELD_UNIT:
-
-
-		/*
-		 * If the Field Buffer and Index have not been previously evaluated,
-		 * evaluate them and save the results.
-		 */
-		if (!(dest_desc->common.flags & AOPOBJ_DATA_VALID)) {
-			status = acpi_ds_get_field_unit_arguments (dest_desc);
-			if (ACPI_FAILURE (status)) {
-				return (status);
-			}
-		}
-
-		if ((!dest_desc->field_unit.container ||
-			ACPI_TYPE_BUFFER != dest_desc->field_unit.container->common.type))
-		{
-			status = AE_AML_INTERNAL;
-			goto clean_up_and_bail_out;
-		}
-
-		/*
-		 *  Get the global lock if needed
-		 */
-		locked = acpi_aml_acquire_global_lock (dest_desc->field_unit.lock_rule);
-
-		/*
-		 * TBD: [Unhandled] REMOVE this limitation
-		 * Make sure the operation is within the limits of our implementation
-		 * this is not a Spec limitation!!
-		 */
-		if (dest_desc->field_unit.length + dest_desc->field_unit.bit_offset > 32) {
-			status = AE_NOT_IMPLEMENTED;
-			goto clean_up_and_bail_out;
-		}
-
-		/* Field location is (base of buffer) + (byte offset) */
-
-		location = dest_desc->field_unit.container->buffer.pointer
-				  + dest_desc->field_unit.offset;
-
-		/*
-		 * Construct Mask with 1 bits where the field is,
-		 * 0 bits elsewhere
-		 */
-		mask = ((u32) 1 << dest_desc->field_unit.length) - ((u32)1
-				   << dest_desc->field_unit.bit_offset);
-
-		/* Zero out the field in the buffer */
-
-		MOVE_UNALIGNED32_TO_32 (&new_value, location);
-		new_value &= ~mask;
-
-		/*
-		 * Shift and mask the new value into position,
-		 * and or it into the buffer.
-		 */
-		new_value |= (val_desc->number.value << dest_desc->field_unit.bit_offset) &
-				 mask;
-
-		/* Store back the value */
-
-		MOVE_UNALIGNED32_TO_32 (location, &new_value);
+	case ACPI_TYPE_STRING:
 
+		status = acpi_aml_copy_string_to_string (source_desc, target_desc);
 		break;
 
 
-	case ACPI_TYPE_NUMBER:
-
-
-		dest_desc->number.value = val_desc->number.value;
-
-		/* Truncate value if we are executing from a 32-bit ACPI table */
+	case ACPI_TYPE_BUFFER:
 
-		acpi_aml_truncate_for32bit_table (dest_desc, walk_state);
+		status = acpi_aml_copy_buffer_to_buffer (source_desc, target_desc);
 		break;
 
 
 	case ACPI_TYPE_PACKAGE:
 
 		/*
-		 *  TBD: [Unhandled] Not real sure what to do here
+		 * TBD: [Unhandled] Not real sure what to do here
 		 */
 		status = AE_NOT_IMPLEMENTED;
 		break;
@@ -518,23 +249,12 @@
 	default:
 
 		/*
-		 * All other types than Alias and the various Fields come here.
-		 * Store Val_desc as the new value of the Name, and set
-		 * the Name's type to that of the value being stored in it.
-		 * Val_desc reference count is incremented by Attach_object.
+		 * All other types come here.
 		 */
-
 		status = AE_NOT_IMPLEMENTED;
 		break;
 	}
 
-
-clean_up_and_bail_out:
-
-	/*
-	 * Release global lock if we acquired it earlier
-	 */
-	acpi_aml_release_global_lock (locked);
 
 	return (status);
 }

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