xref: /titanic_51/usr/src/uts/intel/io/acpica/dispatcher/dsmthdat.c (revision bbaa8b60dd95d714741fc474adad3cf710ef4efd)
1 /*******************************************************************************
2  *
3  * Module Name: dsmthdat - control method arguments and local variables
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2011, Intel Corp.
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 #define __DSMTHDAT_C__
45 
46 #include "acpi.h"
47 #include "accommon.h"
48 #include "acdispat.h"
49 #include "acnamesp.h"
50 #include "acinterp.h"
51 
52 
53 #define _COMPONENT          ACPI_DISPATCHER
54         ACPI_MODULE_NAME    ("dsmthdat")
55 
56 /* Local prototypes */
57 
58 static void
59 AcpiDsMethodDataDeleteValue (
60     UINT8                   Type,
61     UINT32                  Index,
62     ACPI_WALK_STATE         *WalkState);
63 
64 static ACPI_STATUS
65 AcpiDsMethodDataSetValue (
66     UINT8                   Type,
67     UINT32                  Index,
68     ACPI_OPERAND_OBJECT     *Object,
69     ACPI_WALK_STATE         *WalkState);
70 
71 #ifdef ACPI_OBSOLETE_FUNCTIONS
72 ACPI_OBJECT_TYPE
73 AcpiDsMethodDataGetType (
74     UINT16                  Opcode,
75     UINT32                  Index,
76     ACPI_WALK_STATE         *WalkState);
77 #endif
78 
79 
80 /*******************************************************************************
81  *
82  * FUNCTION:    AcpiDsMethodDataInit
83  *
84  * PARAMETERS:  WalkState           - Current walk state object
85  *
86  * RETURN:      Status
87  *
88  * DESCRIPTION: Initialize the data structures that hold the method's arguments
89  *              and locals.  The data struct is an array of namespace nodes for
90  *              each - this allows RefOf and DeRefOf to work properly for these
91  *              special data types.
92  *
93  * NOTES:       WalkState fields are initialized to zero by the
94  *              ACPI_ALLOCATE_ZEROED().
95  *
96  *              A pseudo-Namespace Node is assigned to each argument and local
97  *              so that RefOf() can return a pointer to the Node.
98  *
99  ******************************************************************************/
100 
101 void
102 AcpiDsMethodDataInit (
103     ACPI_WALK_STATE         *WalkState)
104 {
105     UINT32                  i;
106 
107 
108     ACPI_FUNCTION_TRACE (DsMethodDataInit);
109 
110 
111     /* Init the method arguments */
112 
113     for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
114     {
115         ACPI_MOVE_32_TO_32 (&WalkState->Arguments[i].Name, NAMEOF_ARG_NTE);
116         WalkState->Arguments[i].Name.Integer |= (i << 24);
117         WalkState->Arguments[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
118         WalkState->Arguments[i].Type = ACPI_TYPE_ANY;
119         WalkState->Arguments[i].Flags = ANOBJ_METHOD_ARG;
120     }
121 
122     /* Init the method locals */
123 
124     for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
125     {
126         ACPI_MOVE_32_TO_32 (&WalkState->LocalVariables[i].Name, NAMEOF_LOCAL_NTE);
127 
128         WalkState->LocalVariables[i].Name.Integer |= (i << 24);
129         WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
130         WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY;
131         WalkState->LocalVariables[i].Flags = ANOBJ_METHOD_LOCAL;
132     }
133 
134     return_VOID;
135 }
136 
137 
138 /*******************************************************************************
139  *
140  * FUNCTION:    AcpiDsMethodDataDeleteAll
141  *
142  * PARAMETERS:  WalkState           - Current walk state object
143  *
144  * RETURN:      None
145  *
146  * DESCRIPTION: Delete method locals and arguments.  Arguments are only
147  *              deleted if this method was called from another method.
148  *
149  ******************************************************************************/
150 
151 void
152 AcpiDsMethodDataDeleteAll (
153     ACPI_WALK_STATE         *WalkState)
154 {
155     UINT32                  Index;
156 
157 
158     ACPI_FUNCTION_TRACE (DsMethodDataDeleteAll);
159 
160 
161     /* Detach the locals */
162 
163     for (Index = 0; Index < ACPI_METHOD_NUM_LOCALS; Index++)
164     {
165         if (WalkState->LocalVariables[Index].Object)
166         {
167             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%u=%p\n",
168                     Index, WalkState->LocalVariables[Index].Object));
169 
170             /* Detach object (if present) and remove a reference */
171 
172             AcpiNsDetachObject (&WalkState->LocalVariables[Index]);
173         }
174     }
175 
176     /* Detach the arguments */
177 
178     for (Index = 0; Index < ACPI_METHOD_NUM_ARGS; Index++)
179     {
180         if (WalkState->Arguments[Index].Object)
181         {
182             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%u=%p\n",
183                     Index, WalkState->Arguments[Index].Object));
184 
185             /* Detach object (if present) and remove a reference */
186 
187             AcpiNsDetachObject (&WalkState->Arguments[Index]);
188         }
189     }
190 
191     return_VOID;
192 }
193 
194 
195 /*******************************************************************************
196  *
197  * FUNCTION:    AcpiDsMethodDataInitArgs
198  *
199  * PARAMETERS:  *Params         - Pointer to a parameter list for the method
200  *              MaxParamCount   - The arg count for this method
201  *              WalkState       - Current walk state object
202  *
203  * RETURN:      Status
204  *
205  * DESCRIPTION: Initialize arguments for a method.  The parameter list is a list
206  *              of ACPI operand objects, either null terminated or whose length
207  *              is defined by MaxParamCount.
208  *
209  ******************************************************************************/
210 
211 ACPI_STATUS
212 AcpiDsMethodDataInitArgs (
213     ACPI_OPERAND_OBJECT     **Params,
214     UINT32                  MaxParamCount,
215     ACPI_WALK_STATE         *WalkState)
216 {
217     ACPI_STATUS             Status;
218     UINT32                  Index = 0;
219 
220 
221     ACPI_FUNCTION_TRACE_PTR (DsMethodDataInitArgs, Params);
222 
223 
224     if (!Params)
225     {
226         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
227         return_ACPI_STATUS (AE_OK);
228     }
229 
230     /* Copy passed parameters into the new method stack frame */
231 
232     while ((Index < ACPI_METHOD_NUM_ARGS) &&
233            (Index < MaxParamCount)        &&
234             Params[Index])
235     {
236         /*
237          * A valid parameter.
238          * Store the argument in the method/walk descriptor.
239          * Do not copy the arg in order to implement call by reference
240          */
241         Status = AcpiDsMethodDataSetValue (ACPI_REFCLASS_ARG, Index,
242                     Params[Index], WalkState);
243         if (ACPI_FAILURE (Status))
244         {
245             return_ACPI_STATUS (Status);
246         }
247 
248         Index++;
249     }
250 
251     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%u args passed to method\n", Index));
252     return_ACPI_STATUS (AE_OK);
253 }
254 
255 
256 /*******************************************************************************
257  *
258  * FUNCTION:    AcpiDsMethodDataGetNode
259  *
260  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
261  *                                    ACPI_REFCLASS_ARG
262  *              Index               - Which Local or Arg whose type to get
263  *              WalkState           - Current walk state object
264  *              Node                - Where the node is returned.
265  *
266  * RETURN:      Status and node
267  *
268  * DESCRIPTION: Get the Node associated with a local or arg.
269  *
270  ******************************************************************************/
271 
272 ACPI_STATUS
273 AcpiDsMethodDataGetNode (
274     UINT8                   Type,
275     UINT32                  Index,
276     ACPI_WALK_STATE         *WalkState,
277     ACPI_NAMESPACE_NODE     **Node)
278 {
279     ACPI_FUNCTION_TRACE (DsMethodDataGetNode);
280 
281 
282     /*
283      * Method Locals and Arguments are supported
284      */
285     switch (Type)
286     {
287     case ACPI_REFCLASS_LOCAL:
288 
289         if (Index > ACPI_METHOD_MAX_LOCAL)
290         {
291             ACPI_ERROR ((AE_INFO,
292                 "Local index %u is invalid (max %u)",
293                 Index, ACPI_METHOD_MAX_LOCAL));
294             return_ACPI_STATUS (AE_AML_INVALID_INDEX);
295         }
296 
297         /* Return a pointer to the pseudo-node */
298 
299         *Node = &WalkState->LocalVariables[Index];
300         break;
301 
302     case ACPI_REFCLASS_ARG:
303 
304         if (Index > ACPI_METHOD_MAX_ARG)
305         {
306             ACPI_ERROR ((AE_INFO,
307                 "Arg index %u is invalid (max %u)",
308                 Index, ACPI_METHOD_MAX_ARG));
309             return_ACPI_STATUS (AE_AML_INVALID_INDEX);
310         }
311 
312         /* Return a pointer to the pseudo-node */
313 
314         *Node = &WalkState->Arguments[Index];
315         break;
316 
317     default:
318         ACPI_ERROR ((AE_INFO, "Type %u is invalid", Type));
319         return_ACPI_STATUS (AE_TYPE);
320     }
321 
322     return_ACPI_STATUS (AE_OK);
323 }
324 
325 
326 /*******************************************************************************
327  *
328  * FUNCTION:    AcpiDsMethodDataSetValue
329  *
330  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
331  *                                    ACPI_REFCLASS_ARG
332  *              Index               - Which Local or Arg to get
333  *              Object              - Object to be inserted into the stack entry
334  *              WalkState           - Current walk state object
335  *
336  * RETURN:      Status
337  *
338  * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
339  *              Note: There is no "implicit conversion" for locals.
340  *
341  ******************************************************************************/
342 
343 static ACPI_STATUS
344 AcpiDsMethodDataSetValue (
345     UINT8                   Type,
346     UINT32                  Index,
347     ACPI_OPERAND_OBJECT     *Object,
348     ACPI_WALK_STATE         *WalkState)
349 {
350     ACPI_STATUS             Status;
351     ACPI_NAMESPACE_NODE     *Node;
352 
353 
354     ACPI_FUNCTION_TRACE (DsMethodDataSetValue);
355 
356 
357     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
358         "NewObj %p Type %2.2X, Refs=%u [%s]\n", Object,
359         Type, Object->Common.ReferenceCount,
360         AcpiUtGetTypeName (Object->Common.Type)));
361 
362     /* Get the namespace node for the arg/local */
363 
364     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
365     if (ACPI_FAILURE (Status))
366     {
367         return_ACPI_STATUS (Status);
368     }
369 
370     /*
371      * Increment ref count so object can't be deleted while installed.
372      * NOTE: We do not copy the object in order to preserve the call by
373      * reference semantics of ACPI Control Method invocation.
374      * (See ACPI Specification 2.0C)
375      */
376     AcpiUtAddReference (Object);
377 
378     /* Install the object */
379 
380     Node->Object = Object;
381     return_ACPI_STATUS (Status);
382 }
383 
384 
385 /*******************************************************************************
386  *
387  * FUNCTION:    AcpiDsMethodDataGetValue
388  *
389  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
390  *                                    ACPI_REFCLASS_ARG
391  *              Index               - Which localVar or argument to get
392  *              WalkState           - Current walk state object
393  *              DestDesc            - Where Arg or Local value is returned
394  *
395  * RETURN:      Status
396  *
397  * DESCRIPTION: Retrieve value of selected Arg or Local for this method
398  *              Used only in AcpiExResolveToValue().
399  *
400  ******************************************************************************/
401 
402 ACPI_STATUS
403 AcpiDsMethodDataGetValue (
404     UINT8                   Type,
405     UINT32                  Index,
406     ACPI_WALK_STATE         *WalkState,
407     ACPI_OPERAND_OBJECT     **DestDesc)
408 {
409     ACPI_STATUS             Status;
410     ACPI_NAMESPACE_NODE     *Node;
411     ACPI_OPERAND_OBJECT     *Object;
412 
413 
414     ACPI_FUNCTION_TRACE (DsMethodDataGetValue);
415 
416 
417     /* Validate the object descriptor */
418 
419     if (!DestDesc)
420     {
421         ACPI_ERROR ((AE_INFO, "Null object descriptor pointer"));
422         return_ACPI_STATUS (AE_BAD_PARAMETER);
423     }
424 
425     /* Get the namespace node for the arg/local */
426 
427     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
428     if (ACPI_FAILURE (Status))
429     {
430         return_ACPI_STATUS (Status);
431     }
432 
433     /* Get the object from the node */
434 
435     Object = Node->Object;
436 
437     /* Examine the returned object, it must be valid. */
438 
439     if (!Object)
440     {
441         /*
442          * Index points to uninitialized object.
443          * This means that either 1) The expected argument was
444          * not passed to the method, or 2) A local variable
445          * was referenced by the method (via the ASL)
446          * before it was initialized.  Either case is an error.
447          */
448 
449         /* If slack enabled, init the LocalX/ArgX to an Integer of value zero */
450 
451         if (AcpiGbl_EnableInterpreterSlack)
452         {
453             Object = AcpiUtCreateIntegerObject ((UINT64) 0);
454             if (!Object)
455             {
456                 return_ACPI_STATUS (AE_NO_MEMORY);
457             }
458 
459             Node->Object = Object;
460         }
461 
462         /* Otherwise, return the error */
463 
464         else switch (Type)
465         {
466         case ACPI_REFCLASS_ARG:
467 
468             ACPI_ERROR ((AE_INFO,
469                 "Uninitialized Arg[%u] at node %p",
470                 Index, Node));
471 
472             return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
473 
474         case ACPI_REFCLASS_LOCAL:
475 
476             /*
477              * No error message for this case, will be trapped again later to
478              * detect and ignore cases of Store(LocalX,LocalX)
479              */
480             return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
481 
482         default:
483 
484             ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: 0x%X", Type));
485             return_ACPI_STATUS (AE_AML_INTERNAL);
486         }
487     }
488 
489     /*
490      * The Index points to an initialized and valid object.
491      * Return an additional reference to the object
492      */
493     *DestDesc = Object;
494     AcpiUtAddReference (Object);
495 
496     return_ACPI_STATUS (AE_OK);
497 }
498 
499 
500 /*******************************************************************************
501  *
502  * FUNCTION:    AcpiDsMethodDataDeleteValue
503  *
504  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
505  *                                    ACPI_REFCLASS_ARG
506  *              Index               - Which localVar or argument to delete
507  *              WalkState           - Current walk state object
508  *
509  * RETURN:      None
510  *
511  * DESCRIPTION: Delete the entry at Opcode:Index.  Inserts
512  *              a null into the stack slot after the object is deleted.
513  *
514  ******************************************************************************/
515 
516 static void
517 AcpiDsMethodDataDeleteValue (
518     UINT8                   Type,
519     UINT32                  Index,
520     ACPI_WALK_STATE         *WalkState)
521 {
522     ACPI_STATUS             Status;
523     ACPI_NAMESPACE_NODE     *Node;
524     ACPI_OPERAND_OBJECT     *Object;
525 
526 
527     ACPI_FUNCTION_TRACE (DsMethodDataDeleteValue);
528 
529 
530     /* Get the namespace node for the arg/local */
531 
532     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
533     if (ACPI_FAILURE (Status))
534     {
535         return_VOID;
536     }
537 
538     /* Get the associated object */
539 
540     Object = AcpiNsGetAttachedObject (Node);
541 
542     /*
543      * Undefine the Arg or Local by setting its descriptor
544      * pointer to NULL. Locals/Args can contain both
545      * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
546      */
547     Node->Object = NULL;
548 
549     if ((Object) &&
550         (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_OPERAND))
551     {
552         /*
553          * There is a valid object.
554          * Decrement the reference count by one to balance the
555          * increment when the object was stored.
556          */
557         AcpiUtRemoveReference (Object);
558     }
559 
560     return_VOID;
561 }
562 
563 
564 /*******************************************************************************
565  *
566  * FUNCTION:    AcpiDsStoreObjectToLocal
567  *
568  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
569  *                                    ACPI_REFCLASS_ARG
570  *              Index               - Which Local or Arg to set
571  *              ObjDesc             - Value to be stored
572  *              WalkState           - Current walk state
573  *
574  * RETURN:      Status
575  *
576  * DESCRIPTION: Store a value in an Arg or Local.  The ObjDesc is installed
577  *              as the new value for the Arg or Local and the reference count
578  *              for ObjDesc is incremented.
579  *
580  ******************************************************************************/
581 
582 ACPI_STATUS
583 AcpiDsStoreObjectToLocal (
584     UINT8                   Type,
585     UINT32                  Index,
586     ACPI_OPERAND_OBJECT     *ObjDesc,
587     ACPI_WALK_STATE         *WalkState)
588 {
589     ACPI_STATUS             Status;
590     ACPI_NAMESPACE_NODE     *Node;
591     ACPI_OPERAND_OBJECT     *CurrentObjDesc;
592     ACPI_OPERAND_OBJECT     *NewObjDesc;
593 
594 
595     ACPI_FUNCTION_TRACE (DsStoreObjectToLocal);
596     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n",
597         Type, Index, ObjDesc));
598 
599     /* Parameter validation */
600 
601     if (!ObjDesc)
602     {
603         return_ACPI_STATUS (AE_BAD_PARAMETER);
604     }
605 
606     /* Get the namespace node for the arg/local */
607 
608     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
609     if (ACPI_FAILURE (Status))
610     {
611         return_ACPI_STATUS (Status);
612     }
613 
614     CurrentObjDesc = AcpiNsGetAttachedObject (Node);
615     if (CurrentObjDesc == ObjDesc)
616     {
617         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
618             ObjDesc));
619         return_ACPI_STATUS (Status);
620     }
621 
622     /*
623      * If the reference count on the object is more than one, we must
624      * take a copy of the object before we store.  A reference count
625      * of exactly 1 means that the object was just created during the
626      * evaluation of an expression, and we can safely use it since it
627      * is not used anywhere else.
628      */
629     NewObjDesc = ObjDesc;
630     if (ObjDesc->Common.ReferenceCount > 1)
631     {
632         Status = AcpiUtCopyIobjectToIobject (ObjDesc, &NewObjDesc, WalkState);
633         if (ACPI_FAILURE (Status))
634         {
635             return_ACPI_STATUS (Status);
636         }
637     }
638 
639     /*
640      * If there is an object already in this slot, we either
641      * have to delete it, or if this is an argument and there
642      * is an object reference stored there, we have to do
643      * an indirect store!
644      */
645     if (CurrentObjDesc)
646     {
647         /*
648          * Check for an indirect store if an argument
649          * contains an object reference (stored as an Node).
650          * We don't allow this automatic dereferencing for
651          * locals, since a store to a local should overwrite
652          * anything there, including an object reference.
653          *
654          * If both Arg0 and Local0 contain RefOf (Local4):
655          *
656          * Store (1, Arg0)             - Causes indirect store to local4
657          * Store (1, Local0)           - Stores 1 in local0, overwriting
658          *                                  the reference to local4
659          * Store (1, DeRefof (Local0)) - Causes indirect store to local4
660          *
661          * Weird, but true.
662          */
663         if (Type == ACPI_REFCLASS_ARG)
664         {
665             /*
666              * If we have a valid reference object that came from RefOf(),
667              * do the indirect store
668              */
669             if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) == ACPI_DESC_TYPE_OPERAND) &&
670                 (CurrentObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
671                 (CurrentObjDesc->Reference.Class == ACPI_REFCLASS_REFOF))
672             {
673                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
674                         "Arg (%p) is an ObjRef(Node), storing in node %p\n",
675                         NewObjDesc, CurrentObjDesc));
676 
677                 /*
678                  * Store this object to the Node (perform the indirect store)
679                  * NOTE: No implicit conversion is performed, as per the ACPI
680                  * specification rules on storing to Locals/Args.
681                  */
682                 Status = AcpiExStoreObjectToNode (NewObjDesc,
683                             CurrentObjDesc->Reference.Object, WalkState,
684                             ACPI_NO_IMPLICIT_CONVERSION);
685 
686                 /* Remove local reference if we copied the object above */
687 
688                 if (NewObjDesc != ObjDesc)
689                 {
690                     AcpiUtRemoveReference (NewObjDesc);
691                 }
692                 return_ACPI_STATUS (Status);
693             }
694         }
695 
696         /* Delete the existing object before storing the new one */
697 
698         AcpiDsMethodDataDeleteValue (Type, Index, WalkState);
699     }
700 
701     /*
702      * Install the Obj descriptor (*NewObjDesc) into
703      * the descriptor for the Arg or Local.
704      * (increments the object reference count by one)
705      */
706     Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState);
707 
708     /* Remove local reference if we copied the object above */
709 
710     if (NewObjDesc != ObjDesc)
711     {
712         AcpiUtRemoveReference (NewObjDesc);
713     }
714 
715     return_ACPI_STATUS (Status);
716 }
717 
718 
719 #ifdef ACPI_OBSOLETE_FUNCTIONS
720 /*******************************************************************************
721  *
722  * FUNCTION:    AcpiDsMethodDataGetType
723  *
724  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
725  *              Index               - Which Local or Arg whose type to get
726  *              WalkState           - Current walk state object
727  *
728  * RETURN:      Data type of current value of the selected Arg or Local
729  *
730  * DESCRIPTION: Get the type of the object stored in the Local or Arg
731  *
732  ******************************************************************************/
733 
734 ACPI_OBJECT_TYPE
735 AcpiDsMethodDataGetType (
736     UINT16                  Opcode,
737     UINT32                  Index,
738     ACPI_WALK_STATE         *WalkState)
739 {
740     ACPI_STATUS             Status;
741     ACPI_NAMESPACE_NODE     *Node;
742     ACPI_OPERAND_OBJECT     *Object;
743 
744 
745     ACPI_FUNCTION_TRACE (DsMethodDataGetType);
746 
747 
748     /* Get the namespace node for the arg/local */
749 
750     Status = AcpiDsMethodDataGetNode (Opcode, Index, WalkState, &Node);
751     if (ACPI_FAILURE (Status))
752     {
753         return_VALUE ((ACPI_TYPE_NOT_FOUND));
754     }
755 
756     /* Get the object */
757 
758     Object = AcpiNsGetAttachedObject (Node);
759     if (!Object)
760     {
761         /* Uninitialized local/arg, return TYPE_ANY */
762 
763         return_VALUE (ACPI_TYPE_ANY);
764     }
765 
766     /* Get the object type */
767 
768     return_VALUE (Object->Type);
769 }
770 #endif
771 
772 
773