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