/home/lenb/src/to-akpm branch 'acpi-2.6.12'
[linux-2.6] / drivers / acpi / dispatcher / dsmthdat.c
1 /*******************************************************************************
2  *
3  * Module Name: dsmthdat - control method arguments and local variables
4  *
5  ******************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2005, R. Byron Moore
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44
45 #include <acpi/acpi.h>
46 #include <acpi/acdispat.h>
47 #include <acpi/amlcode.h>
48 #include <acpi/acnamesp.h>
49 #include <acpi/acinterp.h>
50
51
52 #define _COMPONENT          ACPI_DISPATCHER
53          ACPI_MODULE_NAME    ("dsmthdat")
54
55 /* Local prototypes */
56
57 static void
58 acpi_ds_method_data_delete_value (
59         u16                             opcode,
60         u32                             index,
61         struct acpi_walk_state          *walk_state);
62
63 static acpi_status
64 acpi_ds_method_data_set_value (
65         u16                             opcode,
66         u32                             index,
67         union acpi_operand_object       *object,
68         struct acpi_walk_state          *walk_state);
69
70 #ifdef ACPI_OBSOLETE_FUNCTIONS
71 acpi_object_type
72 acpi_ds_method_data_get_type (
73         u16                             opcode,
74         u32                             index,
75         struct acpi_walk_state          *walk_state);
76 #endif
77
78
79 /*******************************************************************************
80  *
81  * FUNCTION:    acpi_ds_method_data_init
82  *
83  * PARAMETERS:  walk_state          - Current walk state object
84  *
85  * RETURN:      Status
86  *
87  * DESCRIPTION: Initialize the data structures that hold the method's arguments
88  *              and locals.  The data struct is an array of namespace nodes for
89  *              each - this allows ref_of and de_ref_of to work properly for these
90  *              special data types.
91  *
92  * NOTES:       walk_state fields are initialized to zero by the
93  *              ACPI_MEM_CALLOCATE().
94  *
95  *              A pseudo-Namespace Node is assigned to each argument and local
96  *              so that ref_of() can return a pointer to the Node.
97  *
98  ******************************************************************************/
99
100 void
101 acpi_ds_method_data_init (
102         struct acpi_walk_state          *walk_state)
103 {
104         u32                             i;
105
106
107         ACPI_FUNCTION_TRACE ("ds_method_data_init");
108
109
110         /* Init the method arguments */
111
112         for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
113                 ACPI_MOVE_32_TO_32 (&walk_state->arguments[i].name,
114                                    NAMEOF_ARG_NTE);
115                 walk_state->arguments[i].name.integer |= (i << 24);
116                 walk_state->arguments[i].descriptor   = ACPI_DESC_TYPE_NAMED;
117                 walk_state->arguments[i].type         = ACPI_TYPE_ANY;
118                 walk_state->arguments[i].flags        = ANOBJ_END_OF_PEER_LIST |
119                                   ANOBJ_METHOD_ARG;
120         }
121
122         /* Init the method locals */
123
124         for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
125                 ACPI_MOVE_32_TO_32 (&walk_state->local_variables[i].name,
126                                    NAMEOF_LOCAL_NTE);
127
128                 walk_state->local_variables[i].name.integer |= (i << 24);
129                 walk_state->local_variables[i].descriptor  = ACPI_DESC_TYPE_NAMED;
130                 walk_state->local_variables[i].type        = ACPI_TYPE_ANY;
131                 walk_state->local_variables[i].flags       = ANOBJ_END_OF_PEER_LIST |
132                                  ANOBJ_METHOD_LOCAL;
133         }
134
135         return_VOID;
136 }
137
138
139 /*******************************************************************************
140  *
141  * FUNCTION:    acpi_ds_method_data_delete_all
142  *
143  * PARAMETERS:  walk_state          - Current walk state object
144  *
145  * RETURN:      None
146  *
147  * DESCRIPTION: Delete method locals and arguments.  Arguments are only
148  *              deleted if this method was called from another method.
149  *
150  ******************************************************************************/
151
152 void
153 acpi_ds_method_data_delete_all (
154         struct acpi_walk_state          *walk_state)
155 {
156         u32                             index;
157
158
159         ACPI_FUNCTION_TRACE ("ds_method_data_delete_all");
160
161
162         /* Detach the locals */
163
164         for (index = 0; index < ACPI_METHOD_NUM_LOCALS; index++) {
165                 if (walk_state->local_variables[index].object) {
166                         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%p\n",
167                                         index, walk_state->local_variables[index].object));
168
169                         /* Detach object (if present) and remove a reference */
170
171                         acpi_ns_detach_object (&walk_state->local_variables[index]);
172                 }
173         }
174
175         /* Detach the arguments */
176
177         for (index = 0; index < ACPI_METHOD_NUM_ARGS; index++) {
178                 if (walk_state->arguments[index].object) {
179                         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%p\n",
180                                         index, walk_state->arguments[index].object));
181
182                         /* Detach object (if present) and remove a reference */
183
184                         acpi_ns_detach_object (&walk_state->arguments[index]);
185                 }
186         }
187
188         return_VOID;
189 }
190
191
192 /*******************************************************************************
193  *
194  * FUNCTION:    acpi_ds_method_data_init_args
195  *
196  * PARAMETERS:  *Params         - Pointer to a parameter list for the method
197  *              max_param_count - The arg count for this method
198  *              walk_state      - Current walk state object
199  *
200  * RETURN:      Status
201  *
202  * DESCRIPTION: Initialize arguments for a method.  The parameter list is a list
203  *              of ACPI operand objects, either null terminated or whose length
204  *              is defined by max_param_count.
205  *
206  ******************************************************************************/
207
208 acpi_status
209 acpi_ds_method_data_init_args (
210         union acpi_operand_object       **params,
211         u32                             max_param_count,
212         struct acpi_walk_state          *walk_state)
213 {
214         acpi_status                     status;
215         u32                             index = 0;
216
217
218         ACPI_FUNCTION_TRACE_PTR ("ds_method_data_init_args", params);
219
220
221         if (!params) {
222                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
223                 return_ACPI_STATUS (AE_OK);
224         }
225
226         /* Copy passed parameters into the new method stack frame */
227
228         while ((index < ACPI_METHOD_NUM_ARGS) &&
229                    (index < max_param_count)      &&
230                         params[index]) {
231                 /*
232                  * A valid parameter.
233                  * Store the argument in the method/walk descriptor.
234                  * Do not copy the arg in order to implement call by reference
235                  */
236                 status = acpi_ds_method_data_set_value (AML_ARG_OP, index,
237                                  params[index], walk_state);
238                 if (ACPI_FAILURE (status)) {
239                         return_ACPI_STATUS (status);
240                 }
241
242                 index++;
243         }
244
245         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", index));
246         return_ACPI_STATUS (AE_OK);
247 }
248
249
250 /*******************************************************************************
251  *
252  * FUNCTION:    acpi_ds_method_data_get_node
253  *
254  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
255  *              Index               - Which Local or Arg whose type to get
256  *              walk_state          - Current walk state object
257  *              Node                - Where the node is returned.
258  *
259  * RETURN:      Status and node
260  *
261  * DESCRIPTION: Get the Node associated with a local or arg.
262  *
263  ******************************************************************************/
264
265 acpi_status
266 acpi_ds_method_data_get_node (
267         u16                             opcode,
268         u32                             index,
269         struct acpi_walk_state          *walk_state,
270         struct acpi_namespace_node      **node)
271 {
272         ACPI_FUNCTION_TRACE ("ds_method_data_get_node");
273
274
275         /*
276          * Method Locals and Arguments are supported
277          */
278         switch (opcode) {
279         case AML_LOCAL_OP:
280
281                 if (index > ACPI_METHOD_MAX_LOCAL) {
282                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
283                                 "Local index %d is invalid (max %d)\n",
284                                 index, ACPI_METHOD_MAX_LOCAL));
285                         return_ACPI_STATUS (AE_AML_INVALID_INDEX);
286                 }
287
288                 /* Return a pointer to the pseudo-node */
289
290                 *node = &walk_state->local_variables[index];
291                 break;
292
293         case AML_ARG_OP:
294
295                 if (index > ACPI_METHOD_MAX_ARG) {
296                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
297                                 "Arg index %d is invalid (max %d)\n",
298                                 index, ACPI_METHOD_MAX_ARG));
299                         return_ACPI_STATUS (AE_AML_INVALID_INDEX);
300                 }
301
302                 /* Return a pointer to the pseudo-node */
303
304                 *node = &walk_state->arguments[index];
305                 break;
306
307         default:
308                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Opcode %d is invalid\n", opcode));
309                 return_ACPI_STATUS (AE_AML_BAD_OPCODE);
310         }
311
312         return_ACPI_STATUS (AE_OK);
313 }
314
315
316 /*******************************************************************************
317  *
318  * FUNCTION:    acpi_ds_method_data_set_value
319  *
320  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
321  *              Index               - Which Local or Arg to get
322  *              Object              - Object to be inserted into the stack entry
323  *              walk_state          - Current walk state object
324  *
325  * RETURN:      Status
326  *
327  * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
328  *              Note: There is no "implicit conversion" for locals.
329  *
330  ******************************************************************************/
331
332 static acpi_status
333 acpi_ds_method_data_set_value (
334         u16                             opcode,
335         u32                             index,
336         union acpi_operand_object       *object,
337         struct acpi_walk_state          *walk_state)
338 {
339         acpi_status                     status;
340         struct acpi_namespace_node      *node;
341
342
343         ACPI_FUNCTION_TRACE ("ds_method_data_set_value");
344
345
346         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
347                 "new_obj %p Opcode %X, Refs=%d [%s]\n", object,
348                 opcode, object->common.reference_count,
349                 acpi_ut_get_type_name (object->common.type)));
350
351         /* Get the namespace node for the arg/local */
352
353         status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
354         if (ACPI_FAILURE (status)) {
355                 return_ACPI_STATUS (status);
356         }
357
358         /*
359          * Increment ref count so object can't be deleted while installed.
360          * NOTE: We do not copy the object in order to preserve the call by
361          * reference semantics of ACPI Control Method invocation.
362          * (See ACPI specification 2.0_c)
363          */
364         acpi_ut_add_reference (object);
365
366         /* Install the object */
367
368         node->object = object;
369         return_ACPI_STATUS (status);
370 }
371
372
373 /*******************************************************************************
374  *
375  * FUNCTION:    acpi_ds_method_data_get_value
376  *
377  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
378  *              Index               - which local_var or argument to get
379  *              walk_state          - Current walk state object
380  *              dest_desc           - Where Arg or Local value is returned
381  *
382  * RETURN:      Status
383  *
384  * DESCRIPTION: Retrieve value of selected Arg or Local for this method
385  *              Used only in acpi_ex_resolve_to_value().
386  *
387  ******************************************************************************/
388
389 acpi_status
390 acpi_ds_method_data_get_value (
391         u16                             opcode,
392         u32                             index,
393         struct acpi_walk_state          *walk_state,
394         union acpi_operand_object       **dest_desc)
395 {
396         acpi_status                     status;
397         struct acpi_namespace_node      *node;
398         union acpi_operand_object       *object;
399
400
401         ACPI_FUNCTION_TRACE ("ds_method_data_get_value");
402
403
404         /* Validate the object descriptor */
405
406         if (!dest_desc) {
407                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null object descriptor pointer\n"));
408                 return_ACPI_STATUS (AE_BAD_PARAMETER);
409         }
410
411         /* Get the namespace node for the arg/local */
412
413         status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
414         if (ACPI_FAILURE (status)) {
415                 return_ACPI_STATUS (status);
416         }
417
418         /* Get the object from the node */
419
420         object = node->object;
421
422         /* Examine the returned object, it must be valid. */
423
424         if (!object) {
425                 /*
426                  * Index points to uninitialized object.
427                  * This means that either 1) The expected argument was
428                  * not passed to the method, or 2) A local variable
429                  * was referenced by the method (via the ASL)
430                  * before it was initialized.  Either case is an error.
431                  */
432
433                 /* If slack enabled, init the local_x/arg_x to an Integer of value zero */
434
435                 if (acpi_gbl_enable_interpreter_slack) {
436                         object = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
437                         if (!object) {
438                                 return_ACPI_STATUS (AE_NO_MEMORY);
439                         }
440
441                         object->integer.value = 0;
442                         node->object = object;
443                 }
444
445                 /* Otherwise, return the error */
446
447                 else switch (opcode) {
448                 case AML_ARG_OP:
449
450                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
451                                 "Uninitialized Arg[%d] at node %p\n",
452                                 index, node));
453
454                         return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
455
456                 case AML_LOCAL_OP:
457
458                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
459                                 "Uninitialized Local[%d] at node %p\n",
460                                 index, node));
461
462                         return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
463
464                 default:
465                         ACPI_REPORT_ERROR (("Not Arg/Local opcode: %X\n", opcode));
466                         return_ACPI_STATUS (AE_AML_INTERNAL);
467                 }
468         }
469
470         /*
471          * The Index points to an initialized and valid object.
472          * Return an additional reference to the object
473          */
474         *dest_desc = object;
475         acpi_ut_add_reference (object);
476
477         return_ACPI_STATUS (AE_OK);
478 }
479
480
481 /*******************************************************************************
482  *
483  * FUNCTION:    acpi_ds_method_data_delete_value
484  *
485  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
486  *              Index               - which local_var or argument to delete
487  *              walk_state          - Current walk state object
488  *
489  * RETURN:      None
490  *
491  * DESCRIPTION: Delete the entry at Opcode:Index.  Inserts
492  *              a null into the stack slot after the object is deleted.
493  *
494  ******************************************************************************/
495
496 static void
497 acpi_ds_method_data_delete_value (
498         u16                             opcode,
499         u32                             index,
500         struct acpi_walk_state          *walk_state)
501 {
502         acpi_status                     status;
503         struct acpi_namespace_node      *node;
504         union acpi_operand_object       *object;
505
506
507         ACPI_FUNCTION_TRACE ("ds_method_data_delete_value");
508
509
510         /* Get the namespace node for the arg/local */
511
512         status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
513         if (ACPI_FAILURE (status)) {
514                 return_VOID;
515         }
516
517         /* Get the associated object */
518
519         object = acpi_ns_get_attached_object (node);
520
521         /*
522          * Undefine the Arg or Local by setting its descriptor
523          * pointer to NULL. Locals/Args can contain both
524          * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
525          */
526         node->object = NULL;
527
528         if ((object) &&
529                 (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_OPERAND)) {
530                 /*
531                  * There is a valid object.
532                  * Decrement the reference count by one to balance the
533                  * increment when the object was stored.
534                  */
535                 acpi_ut_remove_reference (object);
536         }
537
538         return_VOID;
539 }
540
541
542 /*******************************************************************************
543  *
544  * FUNCTION:    acpi_ds_store_object_to_local
545  *
546  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
547  *              Index               - Which Local or Arg to set
548  *              obj_desc            - Value to be stored
549  *              walk_state          - Current walk state
550  *
551  * RETURN:      Status
552  *
553  * DESCRIPTION: Store a value in an Arg or Local.  The obj_desc is installed
554  *              as the new value for the Arg or Local and the reference count
555  *              for obj_desc is incremented.
556  *
557  ******************************************************************************/
558
559 acpi_status
560 acpi_ds_store_object_to_local (
561         u16                             opcode,
562         u32                             index,
563         union acpi_operand_object       *obj_desc,
564         struct acpi_walk_state          *walk_state)
565 {
566         acpi_status                     status;
567         struct acpi_namespace_node      *node;
568         union acpi_operand_object       *current_obj_desc;
569         union acpi_operand_object       *new_obj_desc;
570
571
572         ACPI_FUNCTION_TRACE ("ds_store_object_to_local");
573         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%X Index=%d Obj=%p\n",
574                 opcode, index, obj_desc));
575
576         /* Parameter validation */
577
578         if (!obj_desc) {
579                 return_ACPI_STATUS (AE_BAD_PARAMETER);
580         }
581
582         /* Get the namespace node for the arg/local */
583
584         status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
585         if (ACPI_FAILURE (status)) {
586                 return_ACPI_STATUS (status);
587         }
588
589         current_obj_desc = acpi_ns_get_attached_object (node);
590         if (current_obj_desc == obj_desc) {
591                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
592                         obj_desc));
593                 return_ACPI_STATUS (status);
594         }
595
596         /*
597          * If the reference count on the object is more than one, we must
598          * take a copy of the object before we store.  A reference count
599          * of exactly 1 means that the object was just created during the
600          * evaluation of an expression, and we can safely use it since it
601          * is not used anywhere else.
602          */
603         new_obj_desc = obj_desc;
604         if (obj_desc->common.reference_count > 1) {
605                 status = acpi_ut_copy_iobject_to_iobject (obj_desc, &new_obj_desc, walk_state);
606                 if (ACPI_FAILURE (status)) {
607                         return_ACPI_STATUS (status);
608                 }
609         }
610
611         /*
612          * If there is an object already in this slot, we either
613          * have to delete it, or if this is an argument and there
614          * is an object reference stored there, we have to do
615          * an indirect store!
616          */
617         if (current_obj_desc) {
618                 /*
619                  * Check for an indirect store if an argument
620                  * contains an object reference (stored as an Node).
621                  * We don't allow this automatic dereferencing for
622                  * locals, since a store to a local should overwrite
623                  * anything there, including an object reference.
624                  *
625                  * If both Arg0 and Local0 contain ref_of (Local4):
626                  *
627                  * Store (1, Arg0)             - Causes indirect store to local4
628                  * Store (1, Local0)           - Stores 1 in local0, overwriting
629                  *                                  the reference to local4
630                  * Store (1, de_refof (Local0)) - Causes indirect store to local4
631                  *
632                  * Weird, but true.
633                  */
634                 if (opcode == AML_ARG_OP) {
635                         /*
636                          * If we have a valid reference object that came from ref_of(),
637                          * do the indirect store
638                          */
639                         if ((ACPI_GET_DESCRIPTOR_TYPE (current_obj_desc) == ACPI_DESC_TYPE_OPERAND) &&
640                                 (current_obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
641                                 (current_obj_desc->reference.opcode == AML_REF_OF_OP)) {
642                                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
643                                                 "Arg (%p) is an obj_ref(Node), storing in node %p\n",
644                                                 new_obj_desc, current_obj_desc));
645
646                                 /*
647                                  * Store this object to the Node (perform the indirect store)
648                                  * NOTE: No implicit conversion is performed, as per the ACPI
649                                  * specification rules on storing to Locals/Args.
650                                  */
651                                 status = acpi_ex_store_object_to_node (new_obj_desc,
652                                                  current_obj_desc->reference.object, walk_state,
653                                                  ACPI_NO_IMPLICIT_CONVERSION);
654
655                                 /* Remove local reference if we copied the object above */
656
657                                 if (new_obj_desc != obj_desc) {
658                                         acpi_ut_remove_reference (new_obj_desc);
659                                 }
660                                 return_ACPI_STATUS (status);
661                         }
662                 }
663
664                 /*
665                  * Delete the existing object
666                  * before storing the new one
667                  */
668                 acpi_ds_method_data_delete_value (opcode, index, walk_state);
669         }
670
671         /*
672          * Install the Obj descriptor (*new_obj_desc) into
673          * the descriptor for the Arg or Local.
674          * (increments the object reference count by one)
675          */
676         status = acpi_ds_method_data_set_value (opcode, index, new_obj_desc, walk_state);
677
678         /* Remove local reference if we copied the object above */
679
680         if (new_obj_desc != obj_desc) {
681                 acpi_ut_remove_reference (new_obj_desc);
682         }
683
684         return_ACPI_STATUS (status);
685 }
686
687
688 #ifdef ACPI_OBSOLETE_FUNCTIONS
689 /*******************************************************************************
690  *
691  * FUNCTION:    acpi_ds_method_data_get_type
692  *
693  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
694  *              Index               - Which Local or Arg whose type to get
695  *              walk_state          - Current walk state object
696  *
697  * RETURN:      Data type of current value of the selected Arg or Local
698  *
699  * DESCRIPTION: Get the type of the object stored in the Local or Arg
700  *
701  ******************************************************************************/
702
703 acpi_object_type
704 acpi_ds_method_data_get_type (
705         u16                             opcode,
706         u32                             index,
707         struct acpi_walk_state          *walk_state)
708 {
709         acpi_status                     status;
710         struct acpi_namespace_node      *node;
711         union acpi_operand_object       *object;
712
713
714         ACPI_FUNCTION_TRACE ("ds_method_data_get_type");
715
716
717         /* Get the namespace node for the arg/local */
718
719         status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
720         if (ACPI_FAILURE (status)) {
721                 return_VALUE ((ACPI_TYPE_NOT_FOUND));
722         }
723
724         /* Get the object */
725
726         object = acpi_ns_get_attached_object (node);
727         if (!object) {
728                 /* Uninitialized local/arg, return TYPE_ANY */
729
730                 return_VALUE (ACPI_TYPE_ANY);
731         }
732
733         /* Get the object type */
734
735         return_VALUE (ACPI_GET_OBJECT_TYPE (object));
736 }
737 #endif
738
739