ia64/linux-2.6.18-xen.hg

changeset 678:3057b932abea

ACPI cpufreq fix (2/2)

commit 8f9337c88335846b01801b1047a4caf10527a320
Author: Bob Moore <robert.moore@intel.com>
Date: Fri Feb 2 19:48:18 2007 +0300

ACPICA: Handle case NumElements > Package length

Additional update for NumElements fix. Must handle
case where NumElements > Package list length, pad package
with null elements.

Signed-off-by: Alexey Starikovskiy
<alexey.y.starikovskiy@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Sep 25 13:06:40 2008 +0100 (2008-09-25)
parents 28419b05401c
children 2afa279661de
files drivers/acpi/dispatcher/dsobject.c
line diff
     1.1 --- a/drivers/acpi/dispatcher/dsobject.c	Thu Sep 25 13:06:12 2008 +0100
     1.2 +++ b/drivers/acpi/dispatcher/dsobject.c	Thu Sep 25 13:06:40 2008 +0100
     1.3 @@ -326,7 +326,7 @@ acpi_ds_build_internal_buffer_obj(struct
     1.4  	}
     1.5  
     1.6  	obj_desc->buffer.flags |= AOPOBJ_DATA_VALID;
     1.7 -	op->common.node = (struct acpi_namespace_node *)obj_desc;
     1.8 +	op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc);
     1.9  	return_ACPI_STATUS(AE_OK);
    1.10  }
    1.11  
    1.12 @@ -336,7 +336,8 @@ acpi_ds_build_internal_buffer_obj(struct
    1.13   *
    1.14   * PARAMETERS:  walk_state      - Current walk state
    1.15   *              Op              - Parser object to be translated
    1.16 - *              package_length  - Number of elements in the package
    1.17 + *              element_count   - Number of elements in the package - this is
    1.18 + *                                the num_elements argument to Package()
    1.19   *              obj_desc_ptr    - Where the ACPI internal object is returned
    1.20   *
    1.21   * RETURN:      Status
    1.22 @@ -344,18 +345,29 @@ acpi_ds_build_internal_buffer_obj(struct
    1.23   * DESCRIPTION: Translate a parser Op package object to the equivalent
    1.24   *              namespace object
    1.25   *
    1.26 + * NOTE: The number of elements in the package will be always be the num_elements
    1.27 + * count, regardless of the number of elements in the package list. If
    1.28 + * num_elements is smaller, only that many package list elements are used.
    1.29 + * if num_elements is larger, the Package object is padded out with
    1.30 + * objects of type Uninitialized (as per ACPI spec.)
    1.31 + *
    1.32 + * Even though the ASL compilers do not allow num_elements to be smaller
    1.33 + * than the Package list length (for the fixed length package opcode), some
    1.34 + * BIOS code modifies the AML on the fly to adjust the num_elements, and
    1.35 + * this code compensates for that. This also provides compatibility with
    1.36 + * other AML interpreters.
    1.37 + *
    1.38   ******************************************************************************/
    1.39  
    1.40  acpi_status
    1.41  acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
    1.42  				   union acpi_parse_object *op,
    1.43 -				   u32 package_length,
    1.44 +				   u32 element_count,
    1.45  				   union acpi_operand_object **obj_desc_ptr)
    1.46  {
    1.47  	union acpi_parse_object *arg;
    1.48  	union acpi_parse_object *parent;
    1.49  	union acpi_operand_object *obj_desc = NULL;
    1.50 -	u32 package_list_length;
    1.51  	acpi_status status = AE_OK;
    1.52  	acpi_native_uint i;
    1.53  
    1.54 @@ -384,43 +396,13 @@ acpi_ds_build_internal_package_obj(struc
    1.55  		obj_desc->package.node = parent->common.node;
    1.56  	}
    1.57  
    1.58 -	/* Count the *actual* number of items in the package list */
    1.59 -
    1.60 -	arg = op->common.value.arg;
    1.61 -	arg = arg->common.next;
    1.62 -	for (package_list_length = 0; arg; package_list_length++) {
    1.63 -		arg = arg->common.next;
    1.64 -	}
    1.65 -
    1.66  	/*
    1.67 -	 * The number of elements in the package will be the lesser of the
    1.68 -	 * specified element count and the length of the initializer list.
    1.69 -	 *
    1.70 -	 * Even though the ASL compilers do not allow this to happen (for the
    1.71 -	 * fixed length package opcode), some BIOS code modifies the AML on the
    1.72 -	 * fly to adjust the package length, and this code compensates for that.
    1.73 -	 * This also provides compatibility with other AML interpreters.
    1.74 -	 */
    1.75 -	obj_desc->package.count = package_length;
    1.76 -
    1.77 -	if (package_list_length != package_length) {
    1.78 -		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
    1.79 -				  "Package length mismatch, using lesser of %X(Length Arg) and %X(AML Length)\n",
    1.80 -				  package_length, package_list_length));
    1.81 -
    1.82 -		if (package_list_length < package_length) {
    1.83 -			obj_desc->package.count = package_list_length;
    1.84 -		}
    1.85 -	}
    1.86 -
    1.87 -	/*
    1.88 -	 * Allocate the pointer array (array of pointers to the
    1.89 -	 * individual objects). Add an extra pointer slot so
    1.90 -	 * that the list is always null terminated.
    1.91 +	 * Allocate the element array (array of pointers to the individual
    1.92 +	 * objects) based on the num_elements parameter. Add an extra pointer slot
    1.93 +	 * so that the list is always null terminated.
    1.94  	 */
    1.95  	obj_desc->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
    1.96 -							   obj_desc->package.
    1.97 -							   count +
    1.98 +							   element_count +
    1.99  							   1) * sizeof(void *));
   1.100  
   1.101  	if (!obj_desc->package.elements) {
   1.102 @@ -428,12 +410,17 @@ acpi_ds_build_internal_package_obj(struc
   1.103  		return_ACPI_STATUS(AE_NO_MEMORY);
   1.104  	}
   1.105  
   1.106 +	obj_desc->package.count = element_count;
   1.107 +
   1.108  	/*
   1.109 -	 * Initialize all elements of the package
   1.110 +	 * Initialize the elements of the package, up to the num_elements count.
   1.111 +	 * Package is automatically padded with uninitialized (NULL) elements
   1.112 +	 * if num_elements is greater than the package list length. Likewise,
   1.113 +	 * Package is truncated if num_elements is less than the list length.
   1.114  	 */
   1.115  	arg = op->common.value.arg;
   1.116  	arg = arg->common.next;
   1.117 -	for (i = 0; i < obj_desc->package.count; i++) {
   1.118 +	for (i = 0; arg && (i < element_count); i++) {
   1.119  		if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
   1.120  			if (arg->common.node->type == ACPI_TYPE_METHOD) {
   1.121  				/*
   1.122 @@ -463,8 +450,14 @@ acpi_ds_build_internal_package_obj(struc
   1.123  		arg = arg->common.next;
   1.124  	}
   1.125  
   1.126 +	if (!arg) {
   1.127 +		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
   1.128 +				  "Package List length larger than NumElements count (%X), truncated\n",
   1.129 +				  element_count));
   1.130 +	}
   1.131 +
   1.132  	obj_desc->package.flags |= AOPOBJ_DATA_VALID;
   1.133 -	op->common.node = (struct acpi_namespace_node *)obj_desc;
   1.134 +	op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc);
   1.135  	return_ACPI_STATUS(status);
   1.136  }
   1.137  
   1.138 @@ -578,8 +571,9 @@ acpi_ds_init_object_from_op(struct acpi_
   1.139  		/*
   1.140  		 * Defer evaluation of Buffer term_arg operand
   1.141  		 */
   1.142 -		obj_desc->buffer.node = (struct acpi_namespace_node *)
   1.143 -		    walk_state->operands[0];
   1.144 +		obj_desc->buffer.node =
   1.145 +		    ACPI_CAST_PTR(struct acpi_namespace_node,
   1.146 +				  walk_state->operands[0]);
   1.147  		obj_desc->buffer.aml_start = op->named.data;
   1.148  		obj_desc->buffer.aml_length = op->named.length;
   1.149  		break;
   1.150 @@ -589,8 +583,9 @@ acpi_ds_init_object_from_op(struct acpi_
   1.151  		/*
   1.152  		 * Defer evaluation of Package term_arg operand
   1.153  		 */
   1.154 -		obj_desc->package.node = (struct acpi_namespace_node *)
   1.155 -		    walk_state->operands[0];
   1.156 +		obj_desc->package.node =
   1.157 +		    ACPI_CAST_PTR(struct acpi_namespace_node,
   1.158 +				  walk_state->operands[0]);
   1.159  		obj_desc->package.aml_start = op->named.data;
   1.160  		obj_desc->package.aml_length = op->named.length;
   1.161  		break;