Blame view

drivers/acpi/acpica/exresop.c 17.8 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
  
  /******************************************************************************
   *
   * Module Name: exresop - AML Interpreter operand/object resolution
   *
   *****************************************************************************/
  
  /*
75a44ce00   Len Brown   ACPICA: update In...
9
   * Copyright (C) 2000 - 2008, Intel Corp.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions, and the following disclaimer,
   *    without modification.
   * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   *    substantially similar to the "NO WARRANTY" disclaimer below
   *    ("Disclaimer") and any redistribution must be conditioned upon
   *    including a substantially similar Disclaimer requirement for further
   *    binary redistribution.
   * 3. Neither the names of the above-listed copyright holders nor the names
   *    of any contributors may be used to endorse or promote products derived
   *    from this software without specific prior written permission.
   *
   * Alternatively, this software may be distributed under the terms of the
   * GNU General Public License ("GPL") version 2 as published by the Free
   * Software Foundation.
   *
   * NO WARRANTY
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   * POSSIBILITY OF SUCH DAMAGES.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
  #include <acpi/acpi.h>
e2f7a7772   Len Brown   ACPICA: hide priv...
45
46
47
48
49
  #include "accommon.h"
  #include "amlcode.h"
  #include "acparser.h"
  #include "acinterp.h"
  #include "acnamesp.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
  #define _COMPONENT          ACPI_EXECUTER
4be44fcd3   Len Brown   [ACPI] Lindent al...
52
  ACPI_MODULE_NAME("exresop")
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53

44f6c0124   Robert Moore   ACPICA 20050408 f...
54
  /* Local prototypes */
44f6c0124   Robert Moore   ACPICA 20050408 f...
55
  static acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
56
57
  acpi_ex_check_object_type(acpi_object_type type_needed,
  			  acpi_object_type this_type, void *object);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
59
60
61
62
63
64
65
66
67
68
69
70
71
  
  /*******************************************************************************
   *
   * FUNCTION:    acpi_ex_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
   *
   ******************************************************************************/
44f6c0124   Robert Moore   ACPICA 20050408 f...
72
  static acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
73
74
  acpi_ex_check_object_type(acpi_object_type type_needed,
  			  acpi_object_type this_type, void *object)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
  {
4a90c7e86   Bob Moore   [ACPI] ACPICA 200...
76
  	ACPI_FUNCTION_ENTRY();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
  
  	if (type_needed == ACPI_TYPE_ANY) {
52fc0b026   Bob Moore   [ACPI] ACPICA 200...
79

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
81
82
83
84
85
86
87
88
89
90
91
  		/* All types OK, so we don't perform any typechecks */
  
  		return (AE_OK);
  	}
  
  	if (type_needed == ACPI_TYPE_LOCAL_REFERENCE) {
  		/*
  		 * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference
  		 * objects and thus allow them to be targets.  (As per the ACPI
  		 * specification, a store to a constant is a noop.)
  		 */
  		if ((this_type == ACPI_TYPE_INTEGER) &&
4be44fcd3   Len Brown   [ACPI] Lindent al...
92
93
  		    (((union acpi_operand_object *)object)->common.
  		     flags & AOPOBJ_AML_CONSTANT)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
96
97
98
  			return (AE_OK);
  		}
  	}
  
  	if (type_needed != this_type) {
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
99
100
101
102
  		ACPI_ERROR((AE_INFO,
  			    "Needed type [%s], found [%s] %p",
  			    acpi_ut_get_type_name(type_needed),
  			    acpi_ut_get_type_name(this_type), object));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
104
105
106
107
108
  
  		return (AE_AML_OPERAND_TYPE);
  	}
  
  	return (AE_OK);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
  /*******************************************************************************
   *
   * FUNCTION:    acpi_ex_resolve_operands
   *
   * PARAMETERS:  Opcode              - Opcode being interpreted
   *              stack_ptr           - Pointer to the operand stack to be
   *                                    resolved
   *              walk_state          - Current state
   *
   * RETURN:      Status
   *
   * DESCRIPTION: Convert multiple input operands to the types required by the
   *              target operator.
   *
   *      Each 5-bit group in arg_types represents one required
   *      operand and indicates the required Type. The corresponding operand
   *      will be converted to the required type if possible, otherwise we
   *      abort with an exception.
   *
   ******************************************************************************/
  
  acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
131
132
133
  acpi_ex_resolve_operands(u16 opcode,
  			 union acpi_operand_object ** stack_ptr,
  			 struct acpi_walk_state * walk_state)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
135
136
137
  	union acpi_operand_object *obj_desc;
  	acpi_status status = AE_OK;
  	u8 object_type;
4be44fcd3   Len Brown   [ACPI] Lindent al...
138
139
140
141
142
  	u32 arg_types;
  	const struct acpi_opcode_info *op_info;
  	u32 this_arg_type;
  	acpi_object_type type_needed;
  	u16 target_op = 0;
b229cf92e   Bob Moore   ACPI: ACPICA 2006...
143
  	ACPI_FUNCTION_TRACE_U32(ex_resolve_operands, opcode);
4be44fcd3   Len Brown   [ACPI] Lindent al...
144
145
  
  	op_info = acpi_ps_get_opcode_info(opcode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
  	if (op_info->class == AML_CLASS_UNKNOWN) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
147
  		return_ACPI_STATUS(AE_AML_BAD_OPCODE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
149
150
151
  	}
  
  	arg_types = op_info->runtime_args;
  	if (arg_types == ARGI_INVALID_OPCODE) {
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
152
  		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", opcode));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153

4be44fcd3   Len Brown   [ACPI] Lindent al...
154
  		return_ACPI_STATUS(AE_AML_INTERNAL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155
  	}
4be44fcd3   Len Brown   [ACPI] Lindent al...
156
  	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
b229cf92e   Bob Moore   ACPI: ACPICA 2006...
157
158
  			  "Opcode %X [%s] RequiredOperandTypes=%8.8X
  ",
4be44fcd3   Len Brown   [ACPI] Lindent al...
159
  			  opcode, op_info->name, arg_types));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
161
162
163
164
165
166
167
  
  	/*
  	 * Normal exit is with (arg_types == 0) at end of argument list.
  	 * Function will return an exception from within the loop upon
  	 * finding an entry which is not (or cannot be converted
  	 * to) the required type; if stack underflows; or upon
  	 * finding a NULL stack entry (which should not happen).
  	 */
4be44fcd3   Len Brown   [ACPI] Lindent al...
168
  	while (GET_CURRENT_ARG_TYPE(arg_types)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
169
  		if (!stack_ptr || !*stack_ptr) {
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
170
171
  			ACPI_ERROR((AE_INFO, "Null stack entry at %p",
  				    stack_ptr));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172

4be44fcd3   Len Brown   [ACPI] Lindent al...
173
  			return_ACPI_STATUS(AE_AML_INTERNAL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
175
176
177
178
179
180
  		}
  
  		/* Extract useful items */
  
  		obj_desc = *stack_ptr;
  
  		/* Decode the descriptor type */
4be44fcd3   Len Brown   [ACPI] Lindent al...
181
  		switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
  		case ACPI_DESC_TYPE_NAMED:
44f6c0124   Robert Moore   ACPICA 20050408 f...
183
  			/* Namespace Node */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184

4be44fcd3   Len Brown   [ACPI] Lindent al...
185
186
  			object_type =
  			    ((struct acpi_namespace_node *)obj_desc)->type;
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
  
  			/*
  			 * Resolve an alias object. The construction of these objects
  			 * guarantees that there is only one level of alias indirection;
  			 * thus, the attached object is always the aliased namespace node
  			 */
  			if (object_type == ACPI_TYPE_LOCAL_ALIAS) {
  				obj_desc =
  				    acpi_ns_get_attached_object((struct
  								 acpi_namespace_node
  								 *)obj_desc);
  				*stack_ptr = obj_desc;
  				object_type =
  				    ((struct acpi_namespace_node *)obj_desc)->
  				    type;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
204
205
206
  		case ACPI_DESC_TYPE_OPERAND:
  
  			/* ACPI internal object */
3371c19c2   Bob Moore   ACPICA: Remove AC...
207
  			object_type = obj_desc->common.type;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
209
  
  			/* Check for bad acpi_object_type */
4be44fcd3   Len Brown   [ACPI] Lindent al...
210
  			if (!acpi_ut_valid_object_type(object_type)) {
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
211
212
213
  				ACPI_ERROR((AE_INFO,
  					    "Bad operand object type [%X]",
  					    object_type));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214

4be44fcd3   Len Brown   [ACPI] Lindent al...
215
  				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216
217
218
  			}
  
  			if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) {
52fc0b026   Bob Moore   [ACPI] ACPICA 200...
219

1044f1f65   Bob Moore   ACPICA: Cleanup f...
220
  				/* Validate the Reference */
44f6c0124   Robert Moore   ACPICA 20050408 f...
221

1044f1f65   Bob Moore   ACPICA: Cleanup f...
222
223
  				switch (obj_desc->reference.class) {
  				case ACPI_REFCLASS_DEBUG:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224

44f6c0124   Robert Moore   ACPICA 20050408 f...
225
226
227
  					target_op = AML_DEBUG_OP;
  
  					/*lint -fallthrough */
1044f1f65   Bob Moore   ACPICA: Cleanup f...
228
229
230
231
232
233
234
235
236
237
238
239
240
241
  				case ACPI_REFCLASS_ARG:
  				case ACPI_REFCLASS_LOCAL:
  				case ACPI_REFCLASS_INDEX:
  				case ACPI_REFCLASS_REFOF:
  				case ACPI_REFCLASS_TABLE:	/* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
  				case ACPI_REFCLASS_NAME:	/* Reference to a named object */
  
  					ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
  							  "Operand is a Reference, Class [%s] %2.2X
  ",
  							  acpi_ut_get_reference_name
  							  (obj_desc),
  							  obj_desc->reference.
  							  class));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242
243
244
  					break;
  
  				default:
1044f1f65   Bob Moore   ACPICA: Cleanup f...
245

b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
246
  					ACPI_ERROR((AE_INFO,
1044f1f65   Bob Moore   ACPICA: Cleanup f...
247
248
249
  						    "Unknown Reference Class %2.2X in %p",
  						    obj_desc->reference.class,
  						    obj_desc));
4be44fcd3   Len Brown   [ACPI] Lindent al...
250
251
  
  					return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252
253
254
  				}
  			}
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255
256
257
  		default:
  
  			/* Invalid descriptor */
1044f1f65   Bob Moore   ACPICA: Cleanup f...
258
  			ACPI_ERROR((AE_INFO, "Invalid descriptor %p [%s]",
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
259
260
  				    obj_desc,
  				    acpi_ut_get_descriptor_name(obj_desc)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261

4be44fcd3   Len Brown   [ACPI] Lindent al...
262
  			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263
  		}
44f6c0124   Robert Moore   ACPICA 20050408 f...
264
  		/* Get one argument type, point to the next */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265

4be44fcd3   Len Brown   [ACPI] Lindent al...
266
267
  		this_arg_type = GET_CURRENT_ARG_TYPE(arg_types);
  		INCREMENT_ARG_LIST(arg_types);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
268
269
270
271
272
273
  
  		/*
  		 * Handle cases where the object does not need to be
  		 * resolved to a value
  		 */
  		switch (this_arg_type) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
274
  		case ARGI_REF_OR_STRING:	/* Can be a String or Reference */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275

4be44fcd3   Len Brown   [ACPI] Lindent al...
276
277
  			if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
  			     ACPI_DESC_TYPE_OPERAND)
3371c19c2   Bob Moore   ACPICA: Remove AC...
278
  			    && (obj_desc->common.type == ACPI_TYPE_STRING)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279
  				/*
44f6c0124   Robert Moore   ACPICA 20050408 f...
280
281
  				 * String found - the string references a named object and
  				 * must be resolved to a node
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
283
284
  				 */
  				goto next_operand;
  			}
44f6c0124   Robert Moore   ACPICA 20050408 f...
285
286
287
288
  			/*
  			 * Else not a string - fall through to the normal Reference
  			 * case below
  			 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
289
  			/*lint -fallthrough */
4be44fcd3   Len Brown   [ACPI] Lindent al...
290
  		case ARGI_REFERENCE:	/* References: */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
292
293
  		case ARGI_INTEGER_REF:
  		case ARGI_OBJECT_REF:
  		case ARGI_DEVICE_REF:
4be44fcd3   Len Brown   [ACPI] Lindent al...
294
295
296
  		case ARGI_TARGETREF:	/* Allows implicit conversion rules before store */
  		case ARGI_FIXED_TARGET:	/* No implicit conversion before store to target */
  		case ARGI_SIMPLE_TARGET:	/* Name, Local, or Arg - no implicit conversion  */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297

44f6c0124   Robert Moore   ACPICA 20050408 f...
298
299
300
301
  			/*
  			 * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
  			 * A Namespace Node is OK as-is
  			 */
4be44fcd3   Len Brown   [ACPI] Lindent al...
302
303
  			if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
  			    ACPI_DESC_TYPE_NAMED) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
305
  				goto next_operand;
  			}
4be44fcd3   Len Brown   [ACPI] Lindent al...
306
307
308
309
310
  			status =
  			    acpi_ex_check_object_type(ACPI_TYPE_LOCAL_REFERENCE,
  						      object_type, obj_desc);
  			if (ACPI_FAILURE(status)) {
  				return_ACPI_STATUS(status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
311
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312
  			goto next_operand;
4be44fcd3   Len Brown   [ACPI] Lindent al...
313
  		case ARGI_DATAREFOBJ:	/* Store operator only */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
314
315
316
317
318
319
320
321
  
  			/*
  			 * 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 ((opcode == AML_STORE_OP) &&
3371c19c2   Bob Moore   ACPICA: Remove AC...
322
  			    ((*stack_ptr)->common.type ==
4be44fcd3   Len Brown   [ACPI] Lindent al...
323
  			     ACPI_TYPE_LOCAL_REFERENCE)
1044f1f65   Bob Moore   ACPICA: Cleanup f...
324
  			    && ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
325
326
327
328
329
330
331
332
  				goto next_operand;
  			}
  			break;
  
  		default:
  			/* All cases covered above */
  			break;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
333
334
335
  		/*
  		 * Resolve this object to a value
  		 */
4be44fcd3   Len Brown   [ACPI] Lindent al...
336
337
338
  		status = acpi_ex_resolve_to_value(stack_ptr, walk_state);
  		if (ACPI_FAILURE(status)) {
  			return_ACPI_STATUS(status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339
340
341
342
343
344
345
346
347
348
  		}
  
  		/* Get the resolved object */
  
  		obj_desc = *stack_ptr;
  
  		/*
  		 * Check the resulting object (value) type
  		 */
  		switch (this_arg_type) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
349
350
351
352
  			/*
  			 * For the simple cases, only one type of resolved object
  			 * is allowed
  			 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
353
354
355
356
357
358
359
360
361
362
363
364
365
  		case ARGI_MUTEX:
  
  			/* Need an operand of type ACPI_TYPE_MUTEX */
  
  			type_needed = ACPI_TYPE_MUTEX;
  			break;
  
  		case ARGI_EVENT:
  
  			/* Need an operand of type ACPI_TYPE_EVENT */
  
  			type_needed = ACPI_TYPE_EVENT;
  			break;
4be44fcd3   Len Brown   [ACPI] Lindent al...
366
  		case ARGI_PACKAGE:	/* Package */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
  
  			/* Need an operand of type ACPI_TYPE_PACKAGE */
  
  			type_needed = ACPI_TYPE_PACKAGE;
  			break;
  
  		case ARGI_ANYTYPE:
  
  			/* Any operand type will do */
  
  			type_needed = ACPI_TYPE_ANY;
  			break;
  
  		case ARGI_DDBHANDLE:
  
  			/* Need an operand of type ACPI_TYPE_DDB_HANDLE */
  
  			type_needed = ACPI_TYPE_LOCAL_REFERENCE;
  			break;
4be44fcd3   Len Brown   [ACPI] Lindent al...
386
387
388
  			/*
  			 * The more complex cases allow multiple resolved object types
  			 */
44f6c0124   Robert Moore   ACPICA 20050408 f...
389
  		case ARGI_INTEGER:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
391
392
393
394
395
  
  			/*
  			 * Need an operand of type ACPI_TYPE_INTEGER,
  			 * But we can implicitly convert from a STRING or BUFFER
  			 * Aka - "Implicit Source Operand Conversion"
  			 */
4be44fcd3   Len Brown   [ACPI] Lindent al...
396
397
398
  			status =
  			    acpi_ex_convert_to_integer(obj_desc, stack_ptr, 16);
  			if (ACPI_FAILURE(status)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399
  				if (status == AE_TYPE) {
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
400
401
402
403
  					ACPI_ERROR((AE_INFO,
  						    "Needed [Integer/String/Buffer], found [%s] %p",
  						    acpi_ut_get_object_type_name
  						    (obj_desc), obj_desc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
404

4be44fcd3   Len Brown   [ACPI] Lindent al...
405
  					return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
406
  				}
4be44fcd3   Len Brown   [ACPI] Lindent al...
407
  				return_ACPI_STATUS(status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
408
  			}
f9f4601f3   Robert Moore   ACPICA 20050708 f...
409
410
  
  			if (obj_desc != *stack_ptr) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
411
  				acpi_ut_remove_reference(obj_desc);
f9f4601f3   Robert Moore   ACPICA 20050708 f...
412
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
413
  			goto next_operand;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
414
415
416
417
418
419
420
  		case ARGI_BUFFER:
  
  			/*
  			 * Need an operand of type ACPI_TYPE_BUFFER,
  			 * But we can implicitly convert from a STRING or INTEGER
  			 * Aka - "Implicit Source Operand Conversion"
  			 */
4be44fcd3   Len Brown   [ACPI] Lindent al...
421
422
  			status = acpi_ex_convert_to_buffer(obj_desc, stack_ptr);
  			if (ACPI_FAILURE(status)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
  				if (status == AE_TYPE) {
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
424
425
426
427
  					ACPI_ERROR((AE_INFO,
  						    "Needed [Integer/String/Buffer], found [%s] %p",
  						    acpi_ut_get_object_type_name
  						    (obj_desc), obj_desc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
428

4be44fcd3   Len Brown   [ACPI] Lindent al...
429
  					return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
430
  				}
4be44fcd3   Len Brown   [ACPI] Lindent al...
431
  				return_ACPI_STATUS(status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
432
  			}
f9f4601f3   Robert Moore   ACPICA 20050708 f...
433
434
  
  			if (obj_desc != *stack_ptr) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
435
  				acpi_ut_remove_reference(obj_desc);
f9f4601f3   Robert Moore   ACPICA 20050708 f...
436
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
437
  			goto next_operand;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
439
440
441
442
443
444
  		case ARGI_STRING:
  
  			/*
  			 * Need an operand of type ACPI_TYPE_STRING,
  			 * But we can implicitly convert from a BUFFER or INTEGER
  			 * Aka - "Implicit Source Operand Conversion"
  			 */
4be44fcd3   Len Brown   [ACPI] Lindent al...
445
446
447
  			status = acpi_ex_convert_to_string(obj_desc, stack_ptr,
  							   ACPI_IMPLICIT_CONVERT_HEX);
  			if (ACPI_FAILURE(status)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
  				if (status == AE_TYPE) {
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
449
450
451
452
  					ACPI_ERROR((AE_INFO,
  						    "Needed [Integer/String/Buffer], found [%s] %p",
  						    acpi_ut_get_object_type_name
  						    (obj_desc), obj_desc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
453

4be44fcd3   Len Brown   [ACPI] Lindent al...
454
  					return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
455
  				}
4be44fcd3   Len Brown   [ACPI] Lindent al...
456
  				return_ACPI_STATUS(status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
457
  			}
f9f4601f3   Robert Moore   ACPICA 20050708 f...
458
459
  
  			if (obj_desc != *stack_ptr) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
460
  				acpi_ut_remove_reference(obj_desc);
f9f4601f3   Robert Moore   ACPICA 20050708 f...
461
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
  			goto next_operand;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463
464
465
  		case ARGI_COMPUTEDATA:
  
  			/* Need an operand of type INTEGER, STRING or BUFFER */
3371c19c2   Bob Moore   ACPICA: Remove AC...
466
  			switch (obj_desc->common.type) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
467
468
469
470
471
  			case ACPI_TYPE_INTEGER:
  			case ACPI_TYPE_STRING:
  			case ACPI_TYPE_BUFFER:
  
  				/* Valid operand */
4be44fcd3   Len Brown   [ACPI] Lindent al...
472
  				break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
473
474
  
  			default:
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
475
476
477
478
  				ACPI_ERROR((AE_INFO,
  					    "Needed [Integer/String/Buffer], found [%s] %p",
  					    acpi_ut_get_object_type_name
  					    (obj_desc), obj_desc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
479

4be44fcd3   Len Brown   [ACPI] Lindent al...
480
  				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
481
482
  			}
  			goto next_operand;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483
484
485
  		case ARGI_BUFFER_OR_STRING:
  
  			/* Need an operand of type STRING or BUFFER */
3371c19c2   Bob Moore   ACPICA: Remove AC...
486
  			switch (obj_desc->common.type) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
487
488
489
490
  			case ACPI_TYPE_STRING:
  			case ACPI_TYPE_BUFFER:
  
  				/* Valid operand */
4be44fcd3   Len Brown   [ACPI] Lindent al...
491
  				break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
493
494
495
  
  			case ACPI_TYPE_INTEGER:
  
  				/* Highest priority conversion is to type Buffer */
4be44fcd3   Len Brown   [ACPI] Lindent al...
496
497
498
499
500
  				status =
  				    acpi_ex_convert_to_buffer(obj_desc,
  							      stack_ptr);
  				if (ACPI_FAILURE(status)) {
  					return_ACPI_STATUS(status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501
  				}
f9f4601f3   Robert Moore   ACPICA 20050708 f...
502
503
  
  				if (obj_desc != *stack_ptr) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
504
  					acpi_ut_remove_reference(obj_desc);
f9f4601f3   Robert Moore   ACPICA 20050708 f...
505
  				}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
506
507
508
  				break;
  
  			default:
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
509
510
511
512
  				ACPI_ERROR((AE_INFO,
  					    "Needed [Integer/String/Buffer], found [%s] %p",
  					    acpi_ut_get_object_type_name
  					    (obj_desc), obj_desc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
513

4be44fcd3   Len Brown   [ACPI] Lindent al...
514
  				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
515
516
  			}
  			goto next_operand;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
517
518
519
520
521
522
523
524
  		case ARGI_DATAOBJECT:
  			/*
  			 * ARGI_DATAOBJECT is only used by the size_of operator.
  			 * Need a buffer, string, package, or ref_of reference.
  			 *
  			 * The only reference allowed here is a direct reference to
  			 * a namespace node.
  			 */
3371c19c2   Bob Moore   ACPICA: Remove AC...
525
  			switch (obj_desc->common.type) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
527
528
529
530
531
532
533
534
  			case ACPI_TYPE_PACKAGE:
  			case ACPI_TYPE_STRING:
  			case ACPI_TYPE_BUFFER:
  			case ACPI_TYPE_LOCAL_REFERENCE:
  
  				/* Valid operand */
  				break;
  
  			default:
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
535
536
537
538
  				ACPI_ERROR((AE_INFO,
  					    "Needed [Buffer/String/Package/Reference], found [%s] %p",
  					    acpi_ut_get_object_type_name
  					    (obj_desc), obj_desc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539

4be44fcd3   Len Brown   [ACPI] Lindent al...
540
  				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
541
542
  			}
  			goto next_operand;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
543
544
545
  		case ARGI_COMPLEXOBJ:
  
  			/* Need a buffer or package or (ACPI 2.0) String */
3371c19c2   Bob Moore   ACPICA: Remove AC...
546
  			switch (obj_desc->common.type) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
547
548
549
550
551
552
553
554
  			case ACPI_TYPE_PACKAGE:
  			case ACPI_TYPE_STRING:
  			case ACPI_TYPE_BUFFER:
  
  				/* Valid operand */
  				break;
  
  			default:
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
555
556
557
558
  				ACPI_ERROR((AE_INFO,
  					    "Needed [Buffer/String/Package], found [%s] %p",
  					    acpi_ut_get_object_type_name
  					    (obj_desc), obj_desc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
559

4be44fcd3   Len Brown   [ACPI] Lindent al...
560
  				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
561
562
  			}
  			goto next_operand;
a6823e12c   Alexey Starikovskiy   ACPICA: Fixes for...
563
  		case ARGI_REGION_OR_BUFFER:	/* Used by Load() only */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
564

a6823e12c   Alexey Starikovskiy   ACPICA: Fixes for...
565
  			/* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
566

3371c19c2   Bob Moore   ACPICA: Remove AC...
567
  			switch (obj_desc->common.type) {
a6823e12c   Alexey Starikovskiy   ACPICA: Fixes for...
568
  			case ACPI_TYPE_BUFFER:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
569
  			case ACPI_TYPE_REGION:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
570
571
572
573
574
  
  				/* Valid operand */
  				break;
  
  			default:
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
575
  				ACPI_ERROR((AE_INFO,
a6823e12c   Alexey Starikovskiy   ACPICA: Fixes for...
576
  					    "Needed [Region/Buffer], found [%s] %p",
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
577
578
  					    acpi_ut_get_object_type_name
  					    (obj_desc), obj_desc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
579

4be44fcd3   Len Brown   [ACPI] Lindent al...
580
  				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581
582
  			}
  			goto next_operand;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
583
584
585
  		case ARGI_DATAREFOBJ:
  
  			/* Used by the Store() operator only */
3371c19c2   Bob Moore   ACPICA: Remove AC...
586
  			switch (obj_desc->common.type) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
  			case ACPI_TYPE_INTEGER:
  			case ACPI_TYPE_PACKAGE:
  			case ACPI_TYPE_STRING:
  			case ACPI_TYPE_BUFFER:
  			case ACPI_TYPE_BUFFER_FIELD:
  			case ACPI_TYPE_LOCAL_REFERENCE:
  			case ACPI_TYPE_LOCAL_REGION_FIELD:
  			case ACPI_TYPE_LOCAL_BANK_FIELD:
  			case ACPI_TYPE_LOCAL_INDEX_FIELD:
  			case ACPI_TYPE_DDB_HANDLE:
  
  				/* Valid operand */
  				break;
  
  			default:
  
  				if (acpi_gbl_enable_interpreter_slack) {
  					/*
  					 * Enable original behavior of Store(), allowing any and all
  					 * objects as the source operand.  The ACPI spec does not
  					 * allow this, however.
  					 */
  					break;
  				}
44f6c0124   Robert Moore   ACPICA 20050408 f...
611
  				if (target_op == AML_DEBUG_OP) {
52fc0b026   Bob Moore   [ACPI] ACPICA 200...
612

44f6c0124   Robert Moore   ACPICA 20050408 f...
613
614
615
616
  					/* Allow store of any object to the Debug object */
  
  					break;
  				}
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
617
618
619
620
  				ACPI_ERROR((AE_INFO,
  					    "Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p",
  					    acpi_ut_get_object_type_name
  					    (obj_desc), obj_desc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
621

4be44fcd3   Len Brown   [ACPI] Lindent al...
622
  				return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
623
624
  			}
  			goto next_operand;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
625
626
627
  		default:
  
  			/* Unknown type */
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
628
629
630
  			ACPI_ERROR((AE_INFO,
  				    "Internal - Unknown ARGI (required operand) type %X",
  				    this_arg_type));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
631

4be44fcd3   Len Brown   [ACPI] Lindent al...
632
  			return_ACPI_STATUS(AE_BAD_PARAMETER);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633
634
635
636
637
638
  		}
  
  		/*
  		 * Make sure that the original object was resolved to the
  		 * required object type (Simple cases only).
  		 */
4be44fcd3   Len Brown   [ACPI] Lindent al...
639
  		status = acpi_ex_check_object_type(type_needed,
3371c19c2   Bob Moore   ACPICA: Remove AC...
640
641
  						   (*stack_ptr)->common.type,
  						   *stack_ptr);
4be44fcd3   Len Brown   [ACPI] Lindent al...
642
643
  		if (ACPI_FAILURE(status)) {
  			return_ACPI_STATUS(status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
644
  		}
4be44fcd3   Len Brown   [ACPI] Lindent al...
645
  	      next_operand:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646
647
648
649
  		/*
  		 * If more operands needed, decrement stack_ptr to point
  		 * to next operand on stack
  		 */
4be44fcd3   Len Brown   [ACPI] Lindent al...
650
  		if (GET_CURRENT_ARG_TYPE(arg_types)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
651
652
  			stack_ptr--;
  		}
44f6c0124   Robert Moore   ACPICA 20050408 f...
653
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654

71d993e11   Bob Moore   ACPICA: Cleanup d...
655
656
657
  	ACPI_DUMP_OPERANDS(walk_state->operands,
  			   acpi_ps_get_opcode_name(opcode),
  			   walk_state->num_operands);
4be44fcd3   Len Brown   [ACPI] Lindent al...
658
  	return_ACPI_STATUS(status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
659
  }