Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2/******************************************************************************
  3 *
  4 * Module Name: exresolv - AML Interpreter object resolution
  5 *
  6 * Copyright (C) 2000 - 2023, Intel Corp.
  7 *
  8 *****************************************************************************/
  9
 10#include <acpi/acpi.h>
 11#include "accommon.h"
 12#include "amlcode.h"
 13#include "acdispat.h"
 14#include "acinterp.h"
 15#include "acnamesp.h"
 16
 17#define _COMPONENT          ACPI_EXECUTER
 18ACPI_MODULE_NAME("exresolv")
 19
 20/* Local prototypes */
 21static acpi_status
 22acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
 23				struct acpi_walk_state *walk_state);
 24
 25/*******************************************************************************
 26 *
 27 * FUNCTION:    acpi_ex_resolve_to_value
 28 *
 29 * PARAMETERS:  **stack_ptr         - Points to entry on obj_stack, which can
 30 *                                    be either an (union acpi_operand_object *)
 31 *                                    or an acpi_handle.
 32 *              walk_state          - Current method state
 33 *
 34 * RETURN:      Status
 35 *
 36 * DESCRIPTION: Convert Reference objects to values
 37 *
 38 ******************************************************************************/
 39
 40acpi_status
 41acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr,
 42			 struct acpi_walk_state *walk_state)
 43{
 44	acpi_status status;
 45
 46	ACPI_FUNCTION_TRACE_PTR(ex_resolve_to_value, stack_ptr);
 47
 48	if (!stack_ptr || !*stack_ptr) {
 49		ACPI_ERROR((AE_INFO, "Internal - null pointer"));
 50		return_ACPI_STATUS(AE_AML_NO_OPERAND);
 51	}
 52
 53	/*
 54	 * The entity pointed to by the stack_ptr can be either
 55	 * 1) A valid union acpi_operand_object, or
 56	 * 2) A struct acpi_namespace_node (named_obj)
 57	 */
 58	if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_OPERAND) {
 59		status = acpi_ex_resolve_object_to_value(stack_ptr, walk_state);
 60		if (ACPI_FAILURE(status)) {
 61			return_ACPI_STATUS(status);
 62		}
 63
 64		if (!*stack_ptr) {
 65			ACPI_ERROR((AE_INFO, "Internal - null pointer"));
 66			return_ACPI_STATUS(AE_AML_NO_OPERAND);
 67		}
 68	}
 69
 70	/*
 71	 * Object on the stack may have changed if acpi_ex_resolve_object_to_value()
 72	 * was called (i.e., we can't use an _else_ here.)
 73	 */
 74	if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_NAMED) {
 75		status =
 76		    acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
 77						  (struct acpi_namespace_node,
 78						   stack_ptr), walk_state);
 79		if (ACPI_FAILURE(status)) {
 80			return_ACPI_STATUS(status);
 81		}
 82	}
 83
 84	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Resolved object %p\n", *stack_ptr));
 85	return_ACPI_STATUS(AE_OK);
 86}
 87
 88/*******************************************************************************
 89 *
 90 * FUNCTION:    acpi_ex_resolve_object_to_value
 91 *
 92 * PARAMETERS:  stack_ptr       - Pointer to an internal object
 93 *              walk_state      - Current method state
 94 *
 95 * RETURN:      Status
 96 *
 97 * DESCRIPTION: Retrieve the value from an internal object. The Reference type
 98 *              uses the associated AML opcode to determine the value.
 99 *
100 ******************************************************************************/
101
102static acpi_status
103acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
104				struct acpi_walk_state *walk_state)
105{
106	acpi_status status = AE_OK;
107	union acpi_operand_object *stack_desc;
108	union acpi_operand_object *obj_desc = NULL;
109	u8 ref_type;
110
111	ACPI_FUNCTION_TRACE(ex_resolve_object_to_value);
112
113	stack_desc = *stack_ptr;
114
115	/* This is an object of type union acpi_operand_object */
116
117	switch (stack_desc->common.type) {
118	case ACPI_TYPE_LOCAL_REFERENCE:
119
120		ref_type = stack_desc->reference.class;
121
122		switch (ref_type) {
123		case ACPI_REFCLASS_LOCAL:
124		case ACPI_REFCLASS_ARG:
125			/*
126			 * Get the local from the method's state info
127			 * Note: this increments the local's object reference count
128			 */
129			status = acpi_ds_method_data_get_value(ref_type,
130							       stack_desc->
131							       reference.value,
132							       walk_state,
133							       &obj_desc);
134			if (ACPI_FAILURE(status)) {
135				return_ACPI_STATUS(status);
136			}
137
138			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
139					  "[Arg/Local %X] ValueObj is %p\n",
140					  stack_desc->reference.value,
141					  obj_desc));
142
143			/*
144			 * Now we can delete the original Reference Object and
145			 * replace it with the resolved value
146			 */
147			acpi_ut_remove_reference(stack_desc);
148			*stack_ptr = obj_desc;
149			break;
150
151		case ACPI_REFCLASS_INDEX:
152
153			switch (stack_desc->reference.target_type) {
154			case ACPI_TYPE_BUFFER_FIELD:
155
156				/* Just return - do not dereference */
157				break;
158
159			case ACPI_TYPE_PACKAGE:
160
161				/* If method call or copy_object - do not dereference */
162
163				if ((walk_state->opcode ==
164				     AML_INT_METHODCALL_OP)
165				    || (walk_state->opcode ==
166					AML_COPY_OBJECT_OP)) {
167					break;
168				}
169
170				/* Otherwise, dereference the package_index to a package element */
171
172				obj_desc = *stack_desc->reference.where;
173				if (obj_desc) {
174					/*
175					 * Valid object descriptor, copy pointer to return value
176					 * (i.e., dereference the package index)
177					 * Delete the ref object, increment the returned object
178					 */
179					acpi_ut_add_reference(obj_desc);
180					*stack_ptr = obj_desc;
181				} else {
182					/*
183					 * A NULL object descriptor means an uninitialized element of
184					 * the package, can't dereference it
185					 */
186					ACPI_ERROR((AE_INFO,
187						    "Attempt to dereference an Index to "
188						    "NULL package element Idx=%p",
189						    stack_desc));
190					status = AE_AML_UNINITIALIZED_ELEMENT;
191				}
192				break;
193
194			default:
195
196				/* Invalid reference object */
197
198				ACPI_ERROR((AE_INFO,
199					    "Unknown TargetType 0x%X in Index/Reference object %p",
200					    stack_desc->reference.target_type,
201					    stack_desc));
202				status = AE_AML_INTERNAL;
203				break;
204			}
205			break;
206
207		case ACPI_REFCLASS_REFOF:
208		case ACPI_REFCLASS_DEBUG:
209		case ACPI_REFCLASS_TABLE:
210
211			/* Just leave the object as-is, do not dereference */
212
213			break;
214
215		case ACPI_REFCLASS_NAME:	/* Reference to a named object */
216
217			/* Dereference the name */
218
219			if ((stack_desc->reference.node->type ==
220			     ACPI_TYPE_DEVICE)
221			    || (stack_desc->reference.node->type ==
222				ACPI_TYPE_THERMAL)) {
223
224				/* These node types do not have 'real' subobjects */
225
226				*stack_ptr = (void *)stack_desc->reference.node;
227			} else {
228				/* Get the object pointed to by the namespace node */
229
230				*stack_ptr =
231				    (stack_desc->reference.node)->object;
232				acpi_ut_add_reference(*stack_ptr);
233			}
234
235			acpi_ut_remove_reference(stack_desc);
236			break;
237
238		default:
239
240			ACPI_ERROR((AE_INFO,
241				    "Unknown Reference type 0x%X in %p",
242				    ref_type, stack_desc));
243			status = AE_AML_INTERNAL;
244			break;
245		}
246		break;
247
248	case ACPI_TYPE_BUFFER:
249
250		status = acpi_ds_get_buffer_arguments(stack_desc);
251		break;
252
253	case ACPI_TYPE_PACKAGE:
254
255		status = acpi_ds_get_package_arguments(stack_desc);
256		break;
257
258	case ACPI_TYPE_BUFFER_FIELD:
259	case ACPI_TYPE_LOCAL_REGION_FIELD:
260	case ACPI_TYPE_LOCAL_BANK_FIELD:
261	case ACPI_TYPE_LOCAL_INDEX_FIELD:
262
263		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
264				  "FieldRead SourceDesc=%p Type=%X\n",
265				  stack_desc, stack_desc->common.type));
266
267		status =
268		    acpi_ex_read_data_from_field(walk_state, stack_desc,
269						 &obj_desc);
270
271		/* Remove a reference to the original operand, then override */
272
273		acpi_ut_remove_reference(*stack_ptr);
274		*stack_ptr = (void *)obj_desc;
275		break;
276
277	default:
278
279		break;
280	}
281
282	return_ACPI_STATUS(status);
283}
284
285/*******************************************************************************
286 *
287 * FUNCTION:    acpi_ex_resolve_multiple
288 *
289 * PARAMETERS:  walk_state          - Current state (contains AML opcode)
290 *              operand             - Starting point for resolution
291 *              return_type         - Where the object type is returned
292 *              return_desc         - Where the resolved object is returned
293 *
294 * RETURN:      Status
295 *
296 * DESCRIPTION: Return the base object and type. Traverse a reference list if
297 *              necessary to get to the base object.
298 *
299 ******************************************************************************/
300
301acpi_status
302acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
303			 union acpi_operand_object *operand,
304			 acpi_object_type *return_type,
305			 union acpi_operand_object **return_desc)
306{
307	union acpi_operand_object *obj_desc = ACPI_CAST_PTR(void, operand);
308	struct acpi_namespace_node *node =
309	    ACPI_CAST_PTR(struct acpi_namespace_node, operand);
310	acpi_object_type type;
311	acpi_status status;
312
313	ACPI_FUNCTION_TRACE(acpi_ex_resolve_multiple);
314
315	/* Operand can be either a namespace node or an operand descriptor */
316
317	switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
318	case ACPI_DESC_TYPE_OPERAND:
319
320		type = obj_desc->common.type;
321		break;
322
323	case ACPI_DESC_TYPE_NAMED:
324
325		type = ((struct acpi_namespace_node *)obj_desc)->type;
326		obj_desc = acpi_ns_get_attached_object(node);
327
328		/* If we had an Alias node, use the attached object for type info */
329
330		if (type == ACPI_TYPE_LOCAL_ALIAS) {
331			type = ((struct acpi_namespace_node *)obj_desc)->type;
332			obj_desc = acpi_ns_get_attached_object((struct
333								acpi_namespace_node
334								*)obj_desc);
335		}
336
337		switch (type) {
338		case ACPI_TYPE_DEVICE:
339		case ACPI_TYPE_THERMAL:
340
341			/* These types have no attached subobject */
342			break;
343
344		default:
345
346			/* All other types require a subobject */
347
348			if (!obj_desc) {
349				ACPI_ERROR((AE_INFO,
350					    "[%4.4s] Node is unresolved or uninitialized",
351					    acpi_ut_get_node_name(node)));
352				return_ACPI_STATUS(AE_AML_UNINITIALIZED_NODE);
353			}
354			break;
355		}
356		break;
357
358	default:
359		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
360	}
361
362	/* If type is anything other than a reference, we are done */
363
364	if (type != ACPI_TYPE_LOCAL_REFERENCE) {
365		goto exit;
366	}
367
368	/*
369	 * For reference objects created via the ref_of, Index, or Load/load_table
370	 * operators, we need to get to the base object (as per the ACPI
371	 * specification of the object_type and size_of operators). This means
372	 * traversing the list of possibly many nested references.
373	 */
374	while (obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
375		switch (obj_desc->reference.class) {
376		case ACPI_REFCLASS_REFOF:
377		case ACPI_REFCLASS_NAME:
378
379			/* Dereference the reference pointer */
380
381			if (obj_desc->reference.class == ACPI_REFCLASS_REFOF) {
382				node = obj_desc->reference.object;
383			} else {	/* AML_INT_NAMEPATH_OP */
384
385				node = obj_desc->reference.node;
386			}
387
388			/* All "References" point to a NS node */
389
390			if (ACPI_GET_DESCRIPTOR_TYPE(node) !=
391			    ACPI_DESC_TYPE_NAMED) {
392				ACPI_ERROR((AE_INFO,
393					    "Not a namespace node %p [%s]",
394					    node,
395					    acpi_ut_get_descriptor_name(node)));
396				return_ACPI_STATUS(AE_AML_INTERNAL);
397			}
398
399			/* Get the attached object */
400
401			obj_desc = acpi_ns_get_attached_object(node);
402			if (!obj_desc) {
403
404				/* No object, use the NS node type */
405
406				type = acpi_ns_get_type(node);
407				goto exit;
408			}
409
410			/* Check for circular references */
411
412			if (obj_desc == operand) {
413				return_ACPI_STATUS(AE_AML_CIRCULAR_REFERENCE);
414			}
415			break;
416
417		case ACPI_REFCLASS_INDEX:
418
419			/* Get the type of this reference (index into another object) */
420
421			type = obj_desc->reference.target_type;
422			if (type != ACPI_TYPE_PACKAGE) {
423				goto exit;
424			}
425
426			/*
427			 * The main object is a package, we want to get the type
428			 * of the individual package element that is referenced by
429			 * the index.
430			 *
431			 * This could of course in turn be another reference object.
432			 */
433			obj_desc = *(obj_desc->reference.where);
434			if (!obj_desc) {
435
436				/* NULL package elements are allowed */
437
438				type = 0;	/* Uninitialized */
439				goto exit;
440			}
441			break;
442
443		case ACPI_REFCLASS_TABLE:
444
445			type = ACPI_TYPE_DDB_HANDLE;
446			goto exit;
447
448		case ACPI_REFCLASS_LOCAL:
449		case ACPI_REFCLASS_ARG:
450
451			if (return_desc) {
452				status =
453				    acpi_ds_method_data_get_value(obj_desc->
454								  reference.
455								  class,
456								  obj_desc->
457								  reference.
458								  value,
459								  walk_state,
460								  &obj_desc);
461				if (ACPI_FAILURE(status)) {
462					return_ACPI_STATUS(status);
463				}
464				acpi_ut_remove_reference(obj_desc);
465			} else {
466				status =
467				    acpi_ds_method_data_get_node(obj_desc->
468								 reference.
469								 class,
470								 obj_desc->
471								 reference.
472								 value,
473								 walk_state,
474								 &node);
475				if (ACPI_FAILURE(status)) {
476					return_ACPI_STATUS(status);
477				}
478
479				obj_desc = acpi_ns_get_attached_object(node);
480				if (!obj_desc) {
481					type = ACPI_TYPE_ANY;
482					goto exit;
483				}
484			}
485			break;
486
487		case ACPI_REFCLASS_DEBUG:
488
489			/* The Debug Object is of type "DebugObject" */
490
491			type = ACPI_TYPE_DEBUG_OBJECT;
492			goto exit;
493
494		default:
495
496			ACPI_ERROR((AE_INFO,
497				    "Unknown Reference Class 0x%2.2X",
498				    obj_desc->reference.class));
499			return_ACPI_STATUS(AE_AML_INTERNAL);
500		}
501	}
502
503	/*
504	 * Now we are guaranteed to have an object that has not been created
505	 * via the ref_of or Index operators.
506	 */
507	type = obj_desc->common.type;
508
509exit:
510	/* Convert internal types to external types */
511
512	switch (type) {
513	case ACPI_TYPE_LOCAL_REGION_FIELD:
514	case ACPI_TYPE_LOCAL_BANK_FIELD:
515	case ACPI_TYPE_LOCAL_INDEX_FIELD:
516
517		type = ACPI_TYPE_FIELD_UNIT;
518		break;
519
520	case ACPI_TYPE_LOCAL_SCOPE:
521
522		/* Per ACPI Specification, Scope is untyped */
523
524		type = ACPI_TYPE_ANY;
525		break;
526
527	default:
528
529		/* No change to Type required */
530
531		break;
532	}
533
534	*return_type = type;
535	if (return_desc) {
536		*return_desc = obj_desc;
537	}
538	return_ACPI_STATUS(AE_OK);
539}
v5.14.15
  1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2/******************************************************************************
  3 *
  4 * Module Name: exresolv - AML Interpreter object resolution
  5 *
  6 * Copyright (C) 2000 - 2021, Intel Corp.
  7 *
  8 *****************************************************************************/
  9
 10#include <acpi/acpi.h>
 11#include "accommon.h"
 12#include "amlcode.h"
 13#include "acdispat.h"
 14#include "acinterp.h"
 15#include "acnamesp.h"
 16
 17#define _COMPONENT          ACPI_EXECUTER
 18ACPI_MODULE_NAME("exresolv")
 19
 20/* Local prototypes */
 21static acpi_status
 22acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
 23				struct acpi_walk_state *walk_state);
 24
 25/*******************************************************************************
 26 *
 27 * FUNCTION:    acpi_ex_resolve_to_value
 28 *
 29 * PARAMETERS:  **stack_ptr         - Points to entry on obj_stack, which can
 30 *                                    be either an (union acpi_operand_object *)
 31 *                                    or an acpi_handle.
 32 *              walk_state          - Current method state
 33 *
 34 * RETURN:      Status
 35 *
 36 * DESCRIPTION: Convert Reference objects to values
 37 *
 38 ******************************************************************************/
 39
 40acpi_status
 41acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr,
 42			 struct acpi_walk_state *walk_state)
 43{
 44	acpi_status status;
 45
 46	ACPI_FUNCTION_TRACE_PTR(ex_resolve_to_value, stack_ptr);
 47
 48	if (!stack_ptr || !*stack_ptr) {
 49		ACPI_ERROR((AE_INFO, "Internal - null pointer"));
 50		return_ACPI_STATUS(AE_AML_NO_OPERAND);
 51	}
 52
 53	/*
 54	 * The entity pointed to by the stack_ptr can be either
 55	 * 1) A valid union acpi_operand_object, or
 56	 * 2) A struct acpi_namespace_node (named_obj)
 57	 */
 58	if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_OPERAND) {
 59		status = acpi_ex_resolve_object_to_value(stack_ptr, walk_state);
 60		if (ACPI_FAILURE(status)) {
 61			return_ACPI_STATUS(status);
 62		}
 63
 64		if (!*stack_ptr) {
 65			ACPI_ERROR((AE_INFO, "Internal - null pointer"));
 66			return_ACPI_STATUS(AE_AML_NO_OPERAND);
 67		}
 68	}
 69
 70	/*
 71	 * Object on the stack may have changed if acpi_ex_resolve_object_to_value()
 72	 * was called (i.e., we can't use an _else_ here.)
 73	 */
 74	if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_NAMED) {
 75		status =
 76		    acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
 77						  (struct acpi_namespace_node,
 78						   stack_ptr), walk_state);
 79		if (ACPI_FAILURE(status)) {
 80			return_ACPI_STATUS(status);
 81		}
 82	}
 83
 84	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Resolved object %p\n", *stack_ptr));
 85	return_ACPI_STATUS(AE_OK);
 86}
 87
 88/*******************************************************************************
 89 *
 90 * FUNCTION:    acpi_ex_resolve_object_to_value
 91 *
 92 * PARAMETERS:  stack_ptr       - Pointer to an internal object
 93 *              walk_state      - Current method state
 94 *
 95 * RETURN:      Status
 96 *
 97 * DESCRIPTION: Retrieve the value from an internal object. The Reference type
 98 *              uses the associated AML opcode to determine the value.
 99 *
100 ******************************************************************************/
101
102static acpi_status
103acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
104				struct acpi_walk_state *walk_state)
105{
106	acpi_status status = AE_OK;
107	union acpi_operand_object *stack_desc;
108	union acpi_operand_object *obj_desc = NULL;
109	u8 ref_type;
110
111	ACPI_FUNCTION_TRACE(ex_resolve_object_to_value);
112
113	stack_desc = *stack_ptr;
114
115	/* This is an object of type union acpi_operand_object */
116
117	switch (stack_desc->common.type) {
118	case ACPI_TYPE_LOCAL_REFERENCE:
119
120		ref_type = stack_desc->reference.class;
121
122		switch (ref_type) {
123		case ACPI_REFCLASS_LOCAL:
124		case ACPI_REFCLASS_ARG:
125			/*
126			 * Get the local from the method's state info
127			 * Note: this increments the local's object reference count
128			 */
129			status = acpi_ds_method_data_get_value(ref_type,
130							       stack_desc->
131							       reference.value,
132							       walk_state,
133							       &obj_desc);
134			if (ACPI_FAILURE(status)) {
135				return_ACPI_STATUS(status);
136			}
137
138			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
139					  "[Arg/Local %X] ValueObj is %p\n",
140					  stack_desc->reference.value,
141					  obj_desc));
142
143			/*
144			 * Now we can delete the original Reference Object and
145			 * replace it with the resolved value
146			 */
147			acpi_ut_remove_reference(stack_desc);
148			*stack_ptr = obj_desc;
149			break;
150
151		case ACPI_REFCLASS_INDEX:
152
153			switch (stack_desc->reference.target_type) {
154			case ACPI_TYPE_BUFFER_FIELD:
155
156				/* Just return - do not dereference */
157				break;
158
159			case ACPI_TYPE_PACKAGE:
160
161				/* If method call or copy_object - do not dereference */
162
163				if ((walk_state->opcode ==
164				     AML_INT_METHODCALL_OP)
165				    || (walk_state->opcode ==
166					AML_COPY_OBJECT_OP)) {
167					break;
168				}
169
170				/* Otherwise, dereference the package_index to a package element */
171
172				obj_desc = *stack_desc->reference.where;
173				if (obj_desc) {
174					/*
175					 * Valid object descriptor, copy pointer to return value
176					 * (i.e., dereference the package index)
177					 * Delete the ref object, increment the returned object
178					 */
179					acpi_ut_add_reference(obj_desc);
180					*stack_ptr = obj_desc;
181				} else {
182					/*
183					 * A NULL object descriptor means an uninitialized element of
184					 * the package, can't dereference it
185					 */
186					ACPI_ERROR((AE_INFO,
187						    "Attempt to dereference an Index to "
188						    "NULL package element Idx=%p",
189						    stack_desc));
190					status = AE_AML_UNINITIALIZED_ELEMENT;
191				}
192				break;
193
194			default:
195
196				/* Invalid reference object */
197
198				ACPI_ERROR((AE_INFO,
199					    "Unknown TargetType 0x%X in Index/Reference object %p",
200					    stack_desc->reference.target_type,
201					    stack_desc));
202				status = AE_AML_INTERNAL;
203				break;
204			}
205			break;
206
207		case ACPI_REFCLASS_REFOF:
208		case ACPI_REFCLASS_DEBUG:
209		case ACPI_REFCLASS_TABLE:
210
211			/* Just leave the object as-is, do not dereference */
212
213			break;
214
215		case ACPI_REFCLASS_NAME:	/* Reference to a named object */
216
217			/* Dereference the name */
218
219			if ((stack_desc->reference.node->type ==
220			     ACPI_TYPE_DEVICE)
221			    || (stack_desc->reference.node->type ==
222				ACPI_TYPE_THERMAL)) {
223
224				/* These node types do not have 'real' subobjects */
225
226				*stack_ptr = (void *)stack_desc->reference.node;
227			} else {
228				/* Get the object pointed to by the namespace node */
229
230				*stack_ptr =
231				    (stack_desc->reference.node)->object;
232				acpi_ut_add_reference(*stack_ptr);
233			}
234
235			acpi_ut_remove_reference(stack_desc);
236			break;
237
238		default:
239
240			ACPI_ERROR((AE_INFO,
241				    "Unknown Reference type 0x%X in %p",
242				    ref_type, stack_desc));
243			status = AE_AML_INTERNAL;
244			break;
245		}
246		break;
247
248	case ACPI_TYPE_BUFFER:
249
250		status = acpi_ds_get_buffer_arguments(stack_desc);
251		break;
252
253	case ACPI_TYPE_PACKAGE:
254
255		status = acpi_ds_get_package_arguments(stack_desc);
256		break;
257
258	case ACPI_TYPE_BUFFER_FIELD:
259	case ACPI_TYPE_LOCAL_REGION_FIELD:
260	case ACPI_TYPE_LOCAL_BANK_FIELD:
261	case ACPI_TYPE_LOCAL_INDEX_FIELD:
262
263		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
264				  "FieldRead SourceDesc=%p Type=%X\n",
265				  stack_desc, stack_desc->common.type));
266
267		status =
268		    acpi_ex_read_data_from_field(walk_state, stack_desc,
269						 &obj_desc);
270
271		/* Remove a reference to the original operand, then override */
272
273		acpi_ut_remove_reference(*stack_ptr);
274		*stack_ptr = (void *)obj_desc;
275		break;
276
277	default:
278
279		break;
280	}
281
282	return_ACPI_STATUS(status);
283}
284
285/*******************************************************************************
286 *
287 * FUNCTION:    acpi_ex_resolve_multiple
288 *
289 * PARAMETERS:  walk_state          - Current state (contains AML opcode)
290 *              operand             - Starting point for resolution
291 *              return_type         - Where the object type is returned
292 *              return_desc         - Where the resolved object is returned
293 *
294 * RETURN:      Status
295 *
296 * DESCRIPTION: Return the base object and type. Traverse a reference list if
297 *              necessary to get to the base object.
298 *
299 ******************************************************************************/
300
301acpi_status
302acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
303			 union acpi_operand_object *operand,
304			 acpi_object_type *return_type,
305			 union acpi_operand_object **return_desc)
306{
307	union acpi_operand_object *obj_desc = ACPI_CAST_PTR(void, operand);
308	struct acpi_namespace_node *node =
309	    ACPI_CAST_PTR(struct acpi_namespace_node, operand);
310	acpi_object_type type;
311	acpi_status status;
312
313	ACPI_FUNCTION_TRACE(acpi_ex_resolve_multiple);
314
315	/* Operand can be either a namespace node or an operand descriptor */
316
317	switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
318	case ACPI_DESC_TYPE_OPERAND:
319
320		type = obj_desc->common.type;
321		break;
322
323	case ACPI_DESC_TYPE_NAMED:
324
325		type = ((struct acpi_namespace_node *)obj_desc)->type;
326		obj_desc = acpi_ns_get_attached_object(node);
327
328		/* If we had an Alias node, use the attached object for type info */
329
330		if (type == ACPI_TYPE_LOCAL_ALIAS) {
331			type = ((struct acpi_namespace_node *)obj_desc)->type;
332			obj_desc = acpi_ns_get_attached_object((struct
333								acpi_namespace_node
334								*)obj_desc);
335		}
336
337		switch (type) {
338		case ACPI_TYPE_DEVICE:
339		case ACPI_TYPE_THERMAL:
340
341			/* These types have no attached subobject */
342			break;
343
344		default:
345
346			/* All other types require a subobject */
347
348			if (!obj_desc) {
349				ACPI_ERROR((AE_INFO,
350					    "[%4.4s] Node is unresolved or uninitialized",
351					    acpi_ut_get_node_name(node)));
352				return_ACPI_STATUS(AE_AML_UNINITIALIZED_NODE);
353			}
354			break;
355		}
356		break;
357
358	default:
359		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
360	}
361
362	/* If type is anything other than a reference, we are done */
363
364	if (type != ACPI_TYPE_LOCAL_REFERENCE) {
365		goto exit;
366	}
367
368	/*
369	 * For reference objects created via the ref_of, Index, or Load/load_table
370	 * operators, we need to get to the base object (as per the ACPI
371	 * specification of the object_type and size_of operators). This means
372	 * traversing the list of possibly many nested references.
373	 */
374	while (obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
375		switch (obj_desc->reference.class) {
376		case ACPI_REFCLASS_REFOF:
377		case ACPI_REFCLASS_NAME:
378
379			/* Dereference the reference pointer */
380
381			if (obj_desc->reference.class == ACPI_REFCLASS_REFOF) {
382				node = obj_desc->reference.object;
383			} else {	/* AML_INT_NAMEPATH_OP */
384
385				node = obj_desc->reference.node;
386			}
387
388			/* All "References" point to a NS node */
389
390			if (ACPI_GET_DESCRIPTOR_TYPE(node) !=
391			    ACPI_DESC_TYPE_NAMED) {
392				ACPI_ERROR((AE_INFO,
393					    "Not a namespace node %p [%s]",
394					    node,
395					    acpi_ut_get_descriptor_name(node)));
396				return_ACPI_STATUS(AE_AML_INTERNAL);
397			}
398
399			/* Get the attached object */
400
401			obj_desc = acpi_ns_get_attached_object(node);
402			if (!obj_desc) {
403
404				/* No object, use the NS node type */
405
406				type = acpi_ns_get_type(node);
407				goto exit;
408			}
409
410			/* Check for circular references */
411
412			if (obj_desc == operand) {
413				return_ACPI_STATUS(AE_AML_CIRCULAR_REFERENCE);
414			}
415			break;
416
417		case ACPI_REFCLASS_INDEX:
418
419			/* Get the type of this reference (index into another object) */
420
421			type = obj_desc->reference.target_type;
422			if (type != ACPI_TYPE_PACKAGE) {
423				goto exit;
424			}
425
426			/*
427			 * The main object is a package, we want to get the type
428			 * of the individual package element that is referenced by
429			 * the index.
430			 *
431			 * This could of course in turn be another reference object.
432			 */
433			obj_desc = *(obj_desc->reference.where);
434			if (!obj_desc) {
435
436				/* NULL package elements are allowed */
437
438				type = 0;	/* Uninitialized */
439				goto exit;
440			}
441			break;
442
443		case ACPI_REFCLASS_TABLE:
444
445			type = ACPI_TYPE_DDB_HANDLE;
446			goto exit;
447
448		case ACPI_REFCLASS_LOCAL:
449		case ACPI_REFCLASS_ARG:
450
451			if (return_desc) {
452				status =
453				    acpi_ds_method_data_get_value(obj_desc->
454								  reference.
455								  class,
456								  obj_desc->
457								  reference.
458								  value,
459								  walk_state,
460								  &obj_desc);
461				if (ACPI_FAILURE(status)) {
462					return_ACPI_STATUS(status);
463				}
464				acpi_ut_remove_reference(obj_desc);
465			} else {
466				status =
467				    acpi_ds_method_data_get_node(obj_desc->
468								 reference.
469								 class,
470								 obj_desc->
471								 reference.
472								 value,
473								 walk_state,
474								 &node);
475				if (ACPI_FAILURE(status)) {
476					return_ACPI_STATUS(status);
477				}
478
479				obj_desc = acpi_ns_get_attached_object(node);
480				if (!obj_desc) {
481					type = ACPI_TYPE_ANY;
482					goto exit;
483				}
484			}
485			break;
486
487		case ACPI_REFCLASS_DEBUG:
488
489			/* The Debug Object is of type "DebugObject" */
490
491			type = ACPI_TYPE_DEBUG_OBJECT;
492			goto exit;
493
494		default:
495
496			ACPI_ERROR((AE_INFO,
497				    "Unknown Reference Class 0x%2.2X",
498				    obj_desc->reference.class));
499			return_ACPI_STATUS(AE_AML_INTERNAL);
500		}
501	}
502
503	/*
504	 * Now we are guaranteed to have an object that has not been created
505	 * via the ref_of or Index operators.
506	 */
507	type = obj_desc->common.type;
508
509exit:
510	/* Convert internal types to external types */
511
512	switch (type) {
513	case ACPI_TYPE_LOCAL_REGION_FIELD:
514	case ACPI_TYPE_LOCAL_BANK_FIELD:
515	case ACPI_TYPE_LOCAL_INDEX_FIELD:
516
517		type = ACPI_TYPE_FIELD_UNIT;
518		break;
519
520	case ACPI_TYPE_LOCAL_SCOPE:
521
522		/* Per ACPI Specification, Scope is untyped */
523
524		type = ACPI_TYPE_ANY;
525		break;
526
527	default:
528
529		/* No change to Type required */
530
531		break;
532	}
533
534	*return_type = type;
535	if (return_desc) {
536		*return_desc = obj_desc;
537	}
538	return_ACPI_STATUS(AE_OK);
539}