patch-2.4.0-prerelease linux/drivers/acpi/interpreter/amresop.c

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

diff -u --recursive --new-file v2.4.0-test12/linux/drivers/acpi/interpreter/amresop.c linux/drivers/acpi/interpreter/amresop.c
@@ -2,7 +2,7 @@
 /******************************************************************************
  *
  * Module Name: amresop - AML Interpreter operand/object resolution
- *              $Revision: 15 $
+ *              $Revision: 18 $
  *
  *****************************************************************************/
 
@@ -41,6 +41,44 @@
 
 /*******************************************************************************
  *
+ * FUNCTION:    Acpi_aml_check_object_type
+ *
+ * PARAMETERS:  Type_needed         Object type needed
+ *              This_type           Actual object type
+ *              Object              Object pointer
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check required type against actual type
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_aml_check_object_type (
+	ACPI_OBJECT_TYPE        type_needed,
+	ACPI_OBJECT_TYPE        this_type,
+	void                    *object)
+{
+
+
+	if (type_needed == ACPI_TYPE_ANY) {
+		/* All types OK, so we don't perform any typechecks */
+
+		return (AE_OK);
+	}
+
+
+	if (type_needed != this_type) {
+		return (AE_AML_OPERAND_TYPE);
+	}
+
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
  * FUNCTION:    Acpi_aml_resolve_operands
  *
  * PARAMETERS:  Opcode              Opcode being interpreted
@@ -71,6 +109,7 @@
 	u32                     arg_types;
 	ACPI_OPCODE_INFO        *op_info;
 	u32                     this_arg_type;
+	ACPI_OBJECT_TYPE        type_needed;
 
 
 	op_info = acpi_ps_get_opcode_info (opcode);
@@ -81,8 +120,7 @@
 
 	arg_types = op_info->runtime_args;
 	if (arg_types == ARGI_INVALID_OPCODE) {
-		status = AE_AML_INTERNAL;
-		goto cleanup;
+		return (AE_AML_INTERNAL);
 	}
 
 
@@ -96,8 +134,7 @@
 
 	while (GET_CURRENT_ARG_TYPE (arg_types)) {
 		if (!stack_ptr || !*stack_ptr) {
-			status = AE_AML_INTERNAL;
-			goto cleanup;
+			return (AE_AML_INTERNAL);
 		}
 
 		/* Extract useful items */
@@ -120,8 +157,7 @@
 			/* Check for bad ACPI_OBJECT_TYPE */
 
 			if (!acpi_aml_validate_object_type (object_type)) {
-				status = AE_AML_OPERAND_TYPE;
-				goto cleanup;
+				return (AE_AML_OPERAND_TYPE);
 			}
 
 			if (object_type == (u8) INTERNAL_TYPE_REFERENCE) {
@@ -149,30 +185,32 @@
 					break;
 
 				default:
-					status = AE_AML_OPERAND_TYPE;
-					goto cleanup;
+					return (AE_AML_OPERAND_TYPE);
 					break;
 				}
 			}
-
 		}
 
 		else {
 			/* Invalid descriptor */
 
-			status = AE_AML_OPERAND_TYPE;
-			goto cleanup;
+			return (AE_AML_OPERAND_TYPE);
 		}
 
 
 		/*
-		 * Decode a character from the type string
+		 * Get one argument type, point to the next
 		 */
 
 		this_arg_type = GET_CURRENT_ARG_TYPE (arg_types);
 		INCREMENT_ARG_LIST (arg_types);
 
 
+		/*
+		 * Handle cases where the object does not need to be
+		 * resolved to a value
+		 */
+
 		switch (this_arg_type)
 		{
 
@@ -182,14 +220,16 @@
 			/* Need an operand of type INTERNAL_TYPE_REFERENCE */
 
 			if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED))            /* direct name ptr OK as-is */ {
-				break;
+				goto next_operand;
 			}
 
-			if (INTERNAL_TYPE_REFERENCE != object_type) {
-				status = AE_AML_OPERAND_TYPE;
-				goto cleanup;
+			status = acpi_aml_check_object_type (INTERNAL_TYPE_REFERENCE,
+					  object_type, obj_desc);
+			if (ACPI_FAILURE (status)) {
+				return (status);
 			}
 
+
 			if (AML_NAME_OP == obj_desc->reference.op_code) {
 				/*
 				 * Convert an indirect name ptr to direct name ptr and put
@@ -200,159 +240,120 @@
 				acpi_cm_remove_reference (obj_desc);
 				(*stack_ptr) = temp_handle;
 			}
-			break;
 
+			goto next_operand;
+			break;
 
-		case ARGI_NUMBER:   /* Number */
 
-			/* Need an operand of type ACPI_TYPE_NUMBER */
+		case ARGI_ANYTYPE:
 
-			status = acpi_aml_resolve_to_value (stack_ptr, walk_state);
-			if (ACPI_FAILURE (status)) {
-				goto cleanup;
-			}
+			/*
+			 * We don't want to resolve Index_op reference objects during
+			 * a store because this would be an implicit De_ref_of operation.
+			 * Instead, we just want to store the reference object.
+			 * -- All others must be resolved below.
+			 */
 
-			if (ACPI_TYPE_NUMBER != (*stack_ptr)->common.type) {
-				status = AE_AML_OPERAND_TYPE;
-				goto cleanup;
+			if ((opcode == AML_STORE_OP) &&
+				((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) &&
+				((*stack_ptr)->reference.op_code == AML_INDEX_OP))
+			{
+				goto next_operand;
 			}
 			break;
+		}
 
 
-		case ARGI_STRING:
+		/*
+		 * Resolve this object to a value
+		 */
 
-			/* Need an operand of type ACPI_TYPE_STRING or ACPI_TYPE_BUFFER */
+		status = acpi_aml_resolve_to_value (stack_ptr, walk_state);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
 
-			status = acpi_aml_resolve_to_value (stack_ptr, walk_state);
-			if (ACPI_FAILURE (status)) {
-				goto cleanup;
-			}
 
-			if ((ACPI_TYPE_STRING != (*stack_ptr)->common.type) &&
-				(ACPI_TYPE_BUFFER != (*stack_ptr)->common.type))
-			{
-				status = AE_AML_OPERAND_TYPE;
-				goto cleanup;
-			}
-			break;
+		/*
+		 * Check the resulting object (value) type
+		 */
+		switch (this_arg_type)
+		{
+		/*
+		 * For the simple cases, only one type of resolved object
+		 * is allowed
+		 */
+		case ARGI_NUMBER:   /* Number */
 
+			/* Need an operand of type ACPI_TYPE_NUMBER */
+
+			type_needed = ACPI_TYPE_NUMBER;
+			break;
 
 		case ARGI_BUFFER:
 
 			/* Need an operand of type ACPI_TYPE_BUFFER */
 
-			status = acpi_aml_resolve_to_value (stack_ptr, walk_state);
-			if (ACPI_FAILURE (status)) {
-				goto cleanup;
-			}
-
-			if (ACPI_TYPE_BUFFER != (*stack_ptr)->common.type) {
-				status = AE_AML_OPERAND_TYPE;
-				goto cleanup;
-			}
+			type_needed = ACPI_TYPE_BUFFER;
 			break;
 
-
 		case ARGI_MUTEX:
 
 			/* Need an operand of type ACPI_TYPE_MUTEX */
 
-			status = acpi_aml_resolve_to_value (stack_ptr, walk_state);
-			if (ACPI_FAILURE (status)) {
-				goto cleanup;
-			}
-
-			if (ACPI_TYPE_MUTEX != (*stack_ptr)->common.type) {
-				status = AE_AML_OPERAND_TYPE;
-				goto cleanup;
-			}
+			type_needed = ACPI_TYPE_MUTEX;
 			break;
 
-
 		case ARGI_EVENT:
 
 			/* Need an operand of type ACPI_TYPE_EVENT */
 
-			status = acpi_aml_resolve_to_value (stack_ptr, walk_state);
-			if (ACPI_FAILURE (status)) {
-				goto cleanup;
-			}
-
-			if (ACPI_TYPE_EVENT != (*stack_ptr)->common.type) {
-				status = AE_AML_OPERAND_TYPE;
-				goto cleanup;
-			}
+			type_needed = ACPI_TYPE_EVENT;
 			break;
 
-
 		case ARGI_REGION:
 
 			/* Need an operand of type ACPI_TYPE_REGION */
 
-			status = acpi_aml_resolve_to_value (stack_ptr, walk_state);
-			if (ACPI_FAILURE (status)) {
-				goto cleanup;
-			}
-
-			if (ACPI_TYPE_REGION != (*stack_ptr)->common.type) {
-				status = AE_AML_OPERAND_TYPE;
-				goto cleanup;
-			}
+			type_needed = ACPI_TYPE_REGION;
 			break;
 
-
-		 case ARGI_IF:   /* If */
+		case ARGI_IF:   /* If */
 
 			/* Need an operand of type INTERNAL_TYPE_IF */
 
-			if (INTERNAL_TYPE_IF != (*stack_ptr)->common.type) {
-				status = AE_AML_OPERAND_TYPE;
-				goto cleanup;
-			}
+			type_needed = INTERNAL_TYPE_IF;
 			break;
 
-
 		case ARGI_PACKAGE:   /* Package */
 
 			/* Need an operand of type ACPI_TYPE_PACKAGE */
 
-			status = acpi_aml_resolve_to_value (stack_ptr, walk_state);
-			if (ACPI_FAILURE (status)) {
-				goto cleanup;
-			}
-
-			if (ACPI_TYPE_PACKAGE != (*stack_ptr)->common.type) {
-				status = AE_AML_OPERAND_TYPE;
-				goto cleanup;
-			}
+			type_needed = ACPI_TYPE_PACKAGE;
 			break;
 
-
 		case ARGI_ANYTYPE:
 
+			/* Any operand type will do */
 
-			/*
-			 * We don't want to resolve Index_op reference objects during
-			 * a store because this would be an implicit De_ref_of operation.
-			 * Instead, we just want to store the reference object.
-			 */
+			type_needed = ACPI_TYPE_ANY;
+			break;
 
-			if ((opcode == AML_STORE_OP) &&
-				((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) &&
-				((*stack_ptr)->reference.op_code == AML_INDEX_OP))
-			{
-				break;
-			}
 
-			/* All others must be resolved */
+		/*
+		 * The more complex cases allow multiple resolved object types
+		 */
 
-			status = acpi_aml_resolve_to_value (stack_ptr, walk_state);
-			if (ACPI_FAILURE (status)) {
-				goto cleanup;
-			}
+		case ARGI_STRING:
 
-			/* All types OK, so we don't perform any typechecks */
+			/* Need an operand of type ACPI_TYPE_STRING or ACPI_TYPE_BUFFER */
 
+			if ((ACPI_TYPE_STRING != (*stack_ptr)->common.type) &&
+				(ACPI_TYPE_BUFFER != (*stack_ptr)->common.type))
+			{
+				return (AE_AML_OPERAND_TYPE);
+			}
+			goto next_operand;
 			break;
 
 
@@ -366,11 +367,6 @@
 			 *  error with a size of 4.
 			 */
 
-			status = acpi_aml_resolve_to_value (stack_ptr, walk_state);
-			if (ACPI_FAILURE (status)) {
-				goto cleanup;
-			}
-
 			/* Need a buffer, string, package or Node reference */
 
 			if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) &&
@@ -378,8 +374,7 @@
 				((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE) &&
 				((*stack_ptr)->common.type != INTERNAL_TYPE_REFERENCE))
 			{
-				status = AE_AML_OPERAND_TYPE;
-				goto cleanup;
+				return (AE_AML_OPERAND_TYPE);
 			}
 
 			/*
@@ -387,44 +382,49 @@
 			 */
 			if ((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) {
 				if (!(*stack_ptr)->reference.node) {
-					status = AE_AML_OPERAND_TYPE;
-					goto cleanup;
+					return (AE_AML_OPERAND_TYPE);
 				}
 			}
-
+			goto next_operand;
 			break;
 
 
 		case ARGI_COMPLEXOBJ:
 
-			status = acpi_aml_resolve_to_value (stack_ptr, walk_state);
-			if (ACPI_FAILURE (status)) {
-				goto cleanup;
-			}
-
 			/* Need a buffer or package */
 
 			if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) &&
 				((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE))
 			{
-				status = AE_AML_OPERAND_TYPE;
-				goto cleanup;
+				return (AE_AML_OPERAND_TYPE);
 			}
+			goto next_operand;
 			break;
 
 
-		/* Unknown abbreviation passed in */
-
 		default:
-			status = AE_BAD_PARAMETER;
-			goto cleanup;
 
-		}   /* switch (*Types++) */
+			/* Unknown type */
 
+			return (AE_BAD_PARAMETER);
+		}
+
+
+		/*
+		 * Make sure that the original object was resolved to the
+		 * required object type (Simple cases only).
+		 */
+		status = acpi_aml_check_object_type (type_needed,
+				  (*stack_ptr)->common.type, *stack_ptr);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
 
+
+next_operand:
 		/*
 		 * If more operands needed, decrement Stack_ptr to point
-		 * to next operand on stack (after checking for underflow).
+		 * to next operand on stack
 		 */
 		if (GET_CURRENT_ARG_TYPE (arg_types)) {
 			stack_ptr--;
@@ -433,9 +433,7 @@
 	}   /* while (*Types) */
 
 
-cleanup:
-
-  return (status);
+	return (status);
 }
 
 

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