aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/dispatcher
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2007-10-17 16:10:18 -0400
committerLen Brown <len.brown@intel.com>2007-12-02 14:26:55 -0500
commit152c300d007c70c4a1847dad39ecdaba22e7d457 (patch)
treed3889cb8e4cdbfd8361fbc97717f295011bdacbd /drivers/acpi/dispatcher
parent92d499d991ec4f5cbd00d6f33967eab9d3ee8d6c (diff)
ACPICA: fix acpi-cpufreq boot crash due to _PSD return-by-reference
Changed resolution of named references in packages Fixed a problem with the Package operator where all named references were created as object references and left otherwise unresolved. According to the ACPI specification, a Package can only contain Data Objects or references to control methods. The implication is that named references to Data Objects (Integer, Buffer, String, Package, BufferField, Field) should be resolved immediately upon package creation. This is the approach taken with this change. References to all other named objects (Methods, Devices, Scopes, etc.) are all now properly created as reference objects. http://bugzilla.kernel.org/show_bug.cgi?id=5328 http://bugzilla.kernel.org/show_bug.cgi?id=9429 Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/dispatcher')
-rw-r--r--drivers/acpi/dispatcher/dsobject.c91
1 files changed, 85 insertions, 6 deletions
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
index a474ca2334d5..954ac8ce958a 100644
--- a/drivers/acpi/dispatcher/dsobject.c
+++ b/drivers/acpi/dispatcher/dsobject.c
@@ -137,6 +137,71 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
137 return_ACPI_STATUS(status); 137 return_ACPI_STATUS(status);
138 } 138 }
139 } 139 }
140
141 /* Special object resolution for elements of a package */
142
143 if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
144 (op->common.parent->common.aml_opcode ==
145 AML_VAR_PACKAGE_OP)) {
146 /*
147 * Attempt to resolve the node to a value before we insert it into
148 * the package. If this is a reference to a common data type,
149 * resolve it immediately. According to the ACPI spec, package
150 * elements can only be "data objects" or method references.
151 * Attempt to resolve to an Integer, Buffer, String or Package.
152 * If cannot, return the named reference (for things like Devices,
153 * Methods, etc.) Buffer Fields and Fields will resolve to simple
154 * objects (int/buf/str/pkg).
155 *
156 * NOTE: References to things like Devices, Methods, Mutexes, etc.
157 * will remain as named references. This behavior is not described
158 * in the ACPI spec, but it appears to be an oversight.
159 */
160 obj_desc = (union acpi_operand_object *)op->common.node;
161
162 status =
163 acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
164 (struct
165 acpi_namespace_node,
166 &obj_desc),
167 walk_state);
168 if (ACPI_FAILURE(status)) {
169 return_ACPI_STATUS(status);
170 }
171
172 switch (op->common.node->type) {
173 /*
174 * For these types, we need the actual node, not the subobject.
175 * However, the subobject got an extra reference count above.
176 */
177 case ACPI_TYPE_MUTEX:
178 case ACPI_TYPE_METHOD:
179 case ACPI_TYPE_POWER:
180 case ACPI_TYPE_PROCESSOR:
181 case ACPI_TYPE_EVENT:
182 case ACPI_TYPE_REGION:
183 case ACPI_TYPE_DEVICE:
184 case ACPI_TYPE_THERMAL:
185
186 obj_desc =
187 (union acpi_operand_object *)op->common.
188 node;
189 break;
190
191 default:
192 break;
193 }
194
195 /*
196 * If above resolved to an operand object, we are done. Otherwise,
197 * we have a NS node, we must create the package entry as a named
198 * reference.
199 */
200 if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) !=
201 ACPI_DESC_TYPE_NAMED) {
202 goto exit;
203 }
204 }
140 } 205 }
141 206
142 /* Create and init a new internal ACPI object */ 207 /* Create and init a new internal ACPI object */
@@ -156,6 +221,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
156 return_ACPI_STATUS(status); 221 return_ACPI_STATUS(status);
157 } 222 }
158 223
224 exit:
159 *obj_desc_ptr = obj_desc; 225 *obj_desc_ptr = obj_desc;
160 return_ACPI_STATUS(AE_OK); 226 return_ACPI_STATUS(AE_OK);
161} 227}
@@ -356,12 +422,25 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
356 arg = arg->common.next; 422 arg = arg->common.next;
357 for (i = 0; arg && (i < element_count); i++) { 423 for (i = 0; arg && (i < element_count); i++) {
358 if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { 424 if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
359 425 if (arg->common.node->type == ACPI_TYPE_METHOD) {
360 /* This package element is already built, just get it */ 426 /*
361 427 * A method reference "looks" to the parser to be a method
362 obj_desc->package.elements[i] = 428 * invocation, so we special case it here
363 ACPI_CAST_PTR(union acpi_operand_object, 429 */
364 arg->common.node); 430 arg->common.aml_opcode = AML_INT_NAMEPATH_OP;
431 status =
432 acpi_ds_build_internal_object(walk_state,
433 arg,
434 &obj_desc->
435 package.
436 elements[i]);
437 } else {
438 /* This package element is already built, just get it */
439
440 obj_desc->package.elements[i] =
441 ACPI_CAST_PTR(union acpi_operand_object,
442 arg->common.node);
443 }
365 } else { 444 } else {
366 status = acpi_ds_build_internal_object(walk_state, arg, 445 status = acpi_ds_build_internal_object(walk_state, arg,
367 &obj_desc-> 446 &obj_desc->