Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/drivers/acpica/dsmthdat.c need to be fixed.

0001 /*******************************************************************************
0002  *
0003  * Module Name: dsmthdat - control method arguments and local variables
0004  *
0005  ******************************************************************************/
0006 
0007 /******************************************************************************
0008  *
0009  * 1. Copyright Notice
0010  *
0011  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
0012  * All rights reserved.
0013  *
0014  * 2. License
0015  *
0016  * 2.1. This is your license from Intel Corp. under its intellectual property
0017  * rights.  You may have additional license terms from the party that provided
0018  * you this software, covering your right to use that party's intellectual
0019  * property rights.
0020  *
0021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0022  * copy of the source code appearing in this file ("Covered Code") an
0023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0024  * base code distributed originally by Intel ("Original Intel Code") to copy,
0025  * make derivatives, distribute, use and display any portion of the Covered
0026  * Code in any form, with the right to sublicense such rights; and
0027  *
0028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0029  * license (with the right to sublicense), under only those claims of Intel
0030  * patents that are infringed by the Original Intel Code, to make, use, sell,
0031  * offer to sell, and import the Covered Code and derivative works thereof
0032  * solely to the minimum extent necessary to exercise the above copyright
0033  * license, and in no event shall the patent license extend to any additions
0034  * to or modifications of the Original Intel Code.  No other license or right
0035  * is granted directly or by implication, estoppel or otherwise;
0036  *
0037  * The above copyright and patent license is granted only if the following
0038  * conditions are met:
0039  *
0040  * 3. Conditions
0041  *
0042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0043  * Redistribution of source code of any substantial portion of the Covered
0044  * Code or modification with rights to further distribute source must include
0045  * the above Copyright Notice, the above License, this list of Conditions,
0046  * and the following Disclaimer and Export Compliance provision.  In addition,
0047  * Licensee must cause all Covered Code to which Licensee contributes to
0048  * contain a file documenting the changes Licensee made to create that Covered
0049  * Code and the date of any change.  Licensee must include in that file the
0050  * documentation of any changes made by any predecessor Licensee.  Licensee
0051  * must include a prominent statement that the modification is derived,
0052  * directly or indirectly, from Original Intel Code.
0053  *
0054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0055  * Redistribution of source code of any substantial portion of the Covered
0056  * Code or modification without rights to further distribute source must
0057  * include the following Disclaimer and Export Compliance provision in the
0058  * documentation and/or other materials provided with distribution.  In
0059  * addition, Licensee may not authorize further sublicense of source of any
0060  * portion of the Covered Code, and must include terms to the effect that the
0061  * license from Licensee to its licensee is limited to the intellectual
0062  * property embodied in the software Licensee provides to its licensee, and
0063  * not to intellectual property embodied in modifications its licensee may
0064  * make.
0065  *
0066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0067  * substantial portion of the Covered Code or modification must reproduce the
0068  * above Copyright Notice, and the following Disclaimer and Export Compliance
0069  * provision in the documentation and/or other materials provided with the
0070  * distribution.
0071  *
0072  * 3.4. Intel retains all right, title, and interest in and to the Original
0073  * Intel Code.
0074  *
0075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0076  * Intel shall be used in advertising or otherwise to promote the sale, use or
0077  * other dealings in products derived from or relating to the Covered Code
0078  * without prior written authorization from Intel.
0079  *
0080  * 4. Disclaimer and Export Compliance
0081  *
0082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0083  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
0085  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
0086  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
0087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0088  * PARTICULAR PURPOSE.
0089  *
0090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
0096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0097  * LIMITED REMEDY.
0098  *
0099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0100  * software or system incorporating such software without first obtaining any
0101  * required license or other approval from the U. S. Department of Commerce or
0102  * any other agency or department of the United States Government.  In the
0103  * event Licensee exports any such software from the United States or
0104  * re-exports any such software from a foreign destination, Licensee shall
0105  * ensure that the distribution and export/re-export of the software is in
0106  * compliance with all laws, regulations, orders, or other restrictions of the
0107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0108  * any of its subsidiaries will export/re-export any technical data, process,
0109  * software, or service, directly or indirectly, to any country for which the
0110  * United States government or any agency thereof requires an export license,
0111  * other governmental approval, or letter of assurance, without first obtaining
0112  * such license, approval or letter.
0113  *
0114  *****************************************************************************/
0115 
0116 #define __DSMTHDAT_C__
0117 
0118 #include "acpi.h"
0119 #include "accommon.h"
0120 #include "acdispat.h"
0121 #include "acnamesp.h"
0122 #include "acinterp.h"
0123 
0124 
0125 #define _COMPONENT          ACPI_DISPATCHER
0126         ACPI_MODULE_NAME    ("dsmthdat")
0127 
0128 /* Local prototypes */
0129 
0130 static void
0131 AcpiDsMethodDataDeleteValue (
0132     UINT8                   Type,
0133     UINT32                  Index,
0134     ACPI_WALK_STATE         *WalkState);
0135 
0136 static ACPI_STATUS
0137 AcpiDsMethodDataSetValue (
0138     UINT8                   Type,
0139     UINT32                  Index,
0140     ACPI_OPERAND_OBJECT     *Object,
0141     ACPI_WALK_STATE         *WalkState);
0142 
0143 #ifdef ACPI_OBSOLETE_FUNCTIONS
0144 ACPI_OBJECT_TYPE
0145 AcpiDsMethodDataGetType (
0146     UINT16                  Opcode,
0147     UINT32                  Index,
0148     ACPI_WALK_STATE         *WalkState);
0149 #endif
0150 
0151 
0152 /*******************************************************************************
0153  *
0154  * FUNCTION:    AcpiDsMethodDataInit
0155  *
0156  * PARAMETERS:  WalkState           - Current walk state object
0157  *
0158  * RETURN:      Status
0159  *
0160  * DESCRIPTION: Initialize the data structures that hold the method's arguments
0161  *              and locals.  The data struct is an array of namespace nodes for
0162  *              each - this allows RefOf and DeRefOf to work properly for these
0163  *              special data types.
0164  *
0165  * NOTES:       WalkState fields are initialized to zero by the
0166  *              ACPI_ALLOCATE_ZEROED().
0167  *
0168  *              A pseudo-Namespace Node is assigned to each argument and local
0169  *              so that RefOf() can return a pointer to the Node.
0170  *
0171  ******************************************************************************/
0172 
0173 void
0174 AcpiDsMethodDataInit (
0175     ACPI_WALK_STATE         *WalkState)
0176 {
0177     UINT32                  i;
0178 
0179 
0180     ACPI_FUNCTION_TRACE (DsMethodDataInit);
0181 
0182 
0183     /* Init the method arguments */
0184 
0185     for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
0186     {
0187         ACPI_MOVE_32_TO_32 (&WalkState->Arguments[i].Name, NAMEOF_ARG_NTE);
0188         WalkState->Arguments[i].Name.Integer |= (i << 24);
0189         WalkState->Arguments[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
0190         WalkState->Arguments[i].Type = ACPI_TYPE_ANY;
0191         WalkState->Arguments[i].Flags =
0192             ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG;
0193     }
0194 
0195     /* Init the method locals */
0196 
0197     for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
0198     {
0199         ACPI_MOVE_32_TO_32 (&WalkState->LocalVariables[i].Name, NAMEOF_LOCAL_NTE);
0200 
0201         WalkState->LocalVariables[i].Name.Integer |= (i << 24);
0202         WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
0203         WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY;
0204         WalkState->LocalVariables[i].Flags =
0205             ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL;
0206     }
0207 
0208     return_VOID;
0209 }
0210 
0211 
0212 /*******************************************************************************
0213  *
0214  * FUNCTION:    AcpiDsMethodDataDeleteAll
0215  *
0216  * PARAMETERS:  WalkState           - Current walk state object
0217  *
0218  * RETURN:      None
0219  *
0220  * DESCRIPTION: Delete method locals and arguments.  Arguments are only
0221  *              deleted if this method was called from another method.
0222  *
0223  ******************************************************************************/
0224 
0225 void
0226 AcpiDsMethodDataDeleteAll (
0227     ACPI_WALK_STATE         *WalkState)
0228 {
0229     UINT32                  Index;
0230 
0231 
0232     ACPI_FUNCTION_TRACE (DsMethodDataDeleteAll);
0233 
0234 
0235     /* Detach the locals */
0236 
0237     for (Index = 0; Index < ACPI_METHOD_NUM_LOCALS; Index++)
0238     {
0239         if (WalkState->LocalVariables[Index].Object)
0240         {
0241             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%p\n",
0242                     Index, WalkState->LocalVariables[Index].Object));
0243 
0244             /* Detach object (if present) and remove a reference */
0245 
0246             AcpiNsDetachObject (&WalkState->LocalVariables[Index]);
0247         }
0248     }
0249 
0250     /* Detach the arguments */
0251 
0252     for (Index = 0; Index < ACPI_METHOD_NUM_ARGS; Index++)
0253     {
0254         if (WalkState->Arguments[Index].Object)
0255         {
0256             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%p\n",
0257                     Index, WalkState->Arguments[Index].Object));
0258 
0259             /* Detach object (if present) and remove a reference */
0260 
0261             AcpiNsDetachObject (&WalkState->Arguments[Index]);
0262         }
0263     }
0264 
0265     return_VOID;
0266 }
0267 
0268 
0269 /*******************************************************************************
0270  *
0271  * FUNCTION:    AcpiDsMethodDataInitArgs
0272  *
0273  * PARAMETERS:  *Params         - Pointer to a parameter list for the method
0274  *              MaxParamCount   - The arg count for this method
0275  *              WalkState       - Current walk state object
0276  *
0277  * RETURN:      Status
0278  *
0279  * DESCRIPTION: Initialize arguments for a method.  The parameter list is a list
0280  *              of ACPI operand objects, either null terminated or whose length
0281  *              is defined by MaxParamCount.
0282  *
0283  ******************************************************************************/
0284 
0285 ACPI_STATUS
0286 AcpiDsMethodDataInitArgs (
0287     ACPI_OPERAND_OBJECT     **Params,
0288     UINT32                  MaxParamCount,
0289     ACPI_WALK_STATE         *WalkState)
0290 {
0291     ACPI_STATUS             Status;
0292     UINT32                  Index = 0;
0293 
0294 
0295     ACPI_FUNCTION_TRACE_PTR (DsMethodDataInitArgs, Params);
0296 
0297 
0298     if (!Params)
0299     {
0300         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
0301         return_ACPI_STATUS (AE_OK);
0302     }
0303 
0304     /* Copy passed parameters into the new method stack frame */
0305 
0306     while ((Index < ACPI_METHOD_NUM_ARGS) &&
0307            (Index < MaxParamCount)        &&
0308             Params[Index])
0309     {
0310         /*
0311          * A valid parameter.
0312          * Store the argument in the method/walk descriptor.
0313          * Do not copy the arg in order to implement call by reference
0314          */
0315         Status = AcpiDsMethodDataSetValue (ACPI_REFCLASS_ARG, Index,
0316                     Params[Index], WalkState);
0317         if (ACPI_FAILURE (Status))
0318         {
0319             return_ACPI_STATUS (Status);
0320         }
0321 
0322         Index++;
0323     }
0324 
0325     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", Index));
0326     return_ACPI_STATUS (AE_OK);
0327 }
0328 
0329 
0330 /*******************************************************************************
0331  *
0332  * FUNCTION:    AcpiDsMethodDataGetNode
0333  *
0334  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
0335  *                                    ACPI_REFCLASS_ARG
0336  *              Index               - Which Local or Arg whose type to get
0337  *              WalkState           - Current walk state object
0338  *              Node                - Where the node is returned.
0339  *
0340  * RETURN:      Status and node
0341  *
0342  * DESCRIPTION: Get the Node associated with a local or arg.
0343  *
0344  ******************************************************************************/
0345 
0346 ACPI_STATUS
0347 AcpiDsMethodDataGetNode (
0348     UINT8                   Type,
0349     UINT32                  Index,
0350     ACPI_WALK_STATE         *WalkState,
0351     ACPI_NAMESPACE_NODE     **Node)
0352 {
0353     ACPI_FUNCTION_TRACE (DsMethodDataGetNode);
0354 
0355 
0356     /*
0357      * Method Locals and Arguments are supported
0358      */
0359     switch (Type)
0360     {
0361     case ACPI_REFCLASS_LOCAL:
0362 
0363         if (Index > ACPI_METHOD_MAX_LOCAL)
0364         {
0365             ACPI_ERROR ((AE_INFO,
0366                 "Local index %d is invalid (max %d)",
0367                 Index, ACPI_METHOD_MAX_LOCAL));
0368             return_ACPI_STATUS (AE_AML_INVALID_INDEX);
0369         }
0370 
0371         /* Return a pointer to the pseudo-node */
0372 
0373         *Node = &WalkState->LocalVariables[Index];
0374         break;
0375 
0376     case ACPI_REFCLASS_ARG:
0377 
0378         if (Index > ACPI_METHOD_MAX_ARG)
0379         {
0380             ACPI_ERROR ((AE_INFO,
0381                 "Arg index %d is invalid (max %d)",
0382                 Index, ACPI_METHOD_MAX_ARG));
0383             return_ACPI_STATUS (AE_AML_INVALID_INDEX);
0384         }
0385 
0386         /* Return a pointer to the pseudo-node */
0387 
0388         *Node = &WalkState->Arguments[Index];
0389         break;
0390 
0391     default:
0392         ACPI_ERROR ((AE_INFO, "Type %d is invalid", Type));
0393         return_ACPI_STATUS (AE_TYPE);
0394     }
0395 
0396     return_ACPI_STATUS (AE_OK);
0397 }
0398 
0399 
0400 /*******************************************************************************
0401  *
0402  * FUNCTION:    AcpiDsMethodDataSetValue
0403  *
0404  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
0405  *                                    ACPI_REFCLASS_ARG
0406  *              Index               - Which Local or Arg to get
0407  *              Object              - Object to be inserted into the stack entry
0408  *              WalkState           - Current walk state object
0409  *
0410  * RETURN:      Status
0411  *
0412  * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
0413  *              Note: There is no "implicit conversion" for locals.
0414  *
0415  ******************************************************************************/
0416 
0417 static ACPI_STATUS
0418 AcpiDsMethodDataSetValue (
0419     UINT8                   Type,
0420     UINT32                  Index,
0421     ACPI_OPERAND_OBJECT     *Object,
0422     ACPI_WALK_STATE         *WalkState)
0423 {
0424     ACPI_STATUS             Status;
0425     ACPI_NAMESPACE_NODE     *Node;
0426 
0427 
0428     ACPI_FUNCTION_TRACE (DsMethodDataSetValue);
0429 
0430 
0431     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
0432         "NewObj %p Type %2.2X, Refs=%d [%s]\n", Object,
0433         Type, Object->Common.ReferenceCount,
0434         AcpiUtGetTypeName (Object->Common.Type)));
0435 
0436     /* Get the namespace node for the arg/local */
0437 
0438     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
0439     if (ACPI_FAILURE (Status))
0440     {
0441         return_ACPI_STATUS (Status);
0442     }
0443 
0444     /*
0445      * Increment ref count so object can't be deleted while installed.
0446      * NOTE: We do not copy the object in order to preserve the call by
0447      * reference semantics of ACPI Control Method invocation.
0448      * (See ACPI Specification 2.0C)
0449      */
0450     AcpiUtAddReference (Object);
0451 
0452     /* Install the object */
0453 
0454     Node->Object = Object;
0455     return_ACPI_STATUS (Status);
0456 }
0457 
0458 
0459 /*******************************************************************************
0460  *
0461  * FUNCTION:    AcpiDsMethodDataGetValue
0462  *
0463  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
0464  *                                    ACPI_REFCLASS_ARG
0465  *              Index               - Which localVar or argument to get
0466  *              WalkState           - Current walk state object
0467  *              DestDesc            - Where Arg or Local value is returned
0468  *
0469  * RETURN:      Status
0470  *
0471  * DESCRIPTION: Retrieve value of selected Arg or Local for this method
0472  *              Used only in AcpiExResolveToValue().
0473  *
0474  ******************************************************************************/
0475 
0476 ACPI_STATUS
0477 AcpiDsMethodDataGetValue (
0478     UINT8                   Type,
0479     UINT32                  Index,
0480     ACPI_WALK_STATE         *WalkState,
0481     ACPI_OPERAND_OBJECT     **DestDesc)
0482 {
0483     ACPI_STATUS             Status;
0484     ACPI_NAMESPACE_NODE     *Node;
0485     ACPI_OPERAND_OBJECT     *Object;
0486 
0487 
0488     ACPI_FUNCTION_TRACE (DsMethodDataGetValue);
0489 
0490 
0491     /* Validate the object descriptor */
0492 
0493     if (!DestDesc)
0494     {
0495         ACPI_ERROR ((AE_INFO, "Null object descriptor pointer"));
0496         return_ACPI_STATUS (AE_BAD_PARAMETER);
0497     }
0498 
0499     /* Get the namespace node for the arg/local */
0500 
0501     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
0502     if (ACPI_FAILURE (Status))
0503     {
0504         return_ACPI_STATUS (Status);
0505     }
0506 
0507     /* Get the object from the node */
0508 
0509     Object = Node->Object;
0510 
0511     /* Examine the returned object, it must be valid. */
0512 
0513     if (!Object)
0514     {
0515         /*
0516          * Index points to uninitialized object.
0517          * This means that either 1) The expected argument was
0518          * not passed to the method, or 2) A local variable
0519          * was referenced by the method (via the ASL)
0520          * before it was initialized.  Either case is an error.
0521          */
0522 
0523         /* If slack enabled, init the LocalX/ArgX to an Integer of value zero */
0524 
0525         if (AcpiGbl_EnableInterpreterSlack)
0526         {
0527             Object = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
0528             if (!Object)
0529             {
0530                 return_ACPI_STATUS (AE_NO_MEMORY);
0531             }
0532 
0533             Object->Integer.Value = 0;
0534             Node->Object = Object;
0535         }
0536 
0537         /* Otherwise, return the error */
0538 
0539         else switch (Type)
0540         {
0541         case ACPI_REFCLASS_ARG:
0542 
0543             ACPI_ERROR ((AE_INFO,
0544                 "Uninitialized Arg[%d] at node %p",
0545                 Index, Node));
0546 
0547             return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
0548 
0549         case ACPI_REFCLASS_LOCAL:
0550 
0551             ACPI_ERROR ((AE_INFO,
0552                 "Uninitialized Local[%d] at node %p", Index, Node));
0553 
0554             return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
0555 
0556         default:
0557 
0558             ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: %X", Type));
0559             return_ACPI_STATUS (AE_AML_INTERNAL);
0560         }
0561     }
0562 
0563     /*
0564      * The Index points to an initialized and valid object.
0565      * Return an additional reference to the object
0566      */
0567     *DestDesc = Object;
0568     AcpiUtAddReference (Object);
0569 
0570     return_ACPI_STATUS (AE_OK);
0571 }
0572 
0573 
0574 /*******************************************************************************
0575  *
0576  * FUNCTION:    AcpiDsMethodDataDeleteValue
0577  *
0578  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
0579  *                                    ACPI_REFCLASS_ARG
0580  *              Index               - Which localVar or argument to delete
0581  *              WalkState           - Current walk state object
0582  *
0583  * RETURN:      None
0584  *
0585  * DESCRIPTION: Delete the entry at Opcode:Index.  Inserts
0586  *              a null into the stack slot after the object is deleted.
0587  *
0588  ******************************************************************************/
0589 
0590 static void
0591 AcpiDsMethodDataDeleteValue (
0592     UINT8                   Type,
0593     UINT32                  Index,
0594     ACPI_WALK_STATE         *WalkState)
0595 {
0596     ACPI_STATUS             Status;
0597     ACPI_NAMESPACE_NODE     *Node;
0598     ACPI_OPERAND_OBJECT     *Object;
0599 
0600 
0601     ACPI_FUNCTION_TRACE (DsMethodDataDeleteValue);
0602 
0603 
0604     /* Get the namespace node for the arg/local */
0605 
0606     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
0607     if (ACPI_FAILURE (Status))
0608     {
0609         return_VOID;
0610     }
0611 
0612     /* Get the associated object */
0613 
0614     Object = AcpiNsGetAttachedObject (Node);
0615 
0616     /*
0617      * Undefine the Arg or Local by setting its descriptor
0618      * pointer to NULL. Locals/Args can contain both
0619      * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
0620      */
0621     Node->Object = NULL;
0622 
0623     if ((Object) &&
0624         (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_OPERAND))
0625     {
0626         /*
0627          * There is a valid object.
0628          * Decrement the reference count by one to balance the
0629          * increment when the object was stored.
0630          */
0631         AcpiUtRemoveReference (Object);
0632     }
0633 
0634     return_VOID;
0635 }
0636 
0637 
0638 /*******************************************************************************
0639  *
0640  * FUNCTION:    AcpiDsStoreObjectToLocal
0641  *
0642  * PARAMETERS:  Type                - Either ACPI_REFCLASS_LOCAL or
0643  *                                    ACPI_REFCLASS_ARG
0644  *              Index               - Which Local or Arg to set
0645  *              ObjDesc             - Value to be stored
0646  *              WalkState           - Current walk state
0647  *
0648  * RETURN:      Status
0649  *
0650  * DESCRIPTION: Store a value in an Arg or Local.  The ObjDesc is installed
0651  *              as the new value for the Arg or Local and the reference count
0652  *              for ObjDesc is incremented.
0653  *
0654  ******************************************************************************/
0655 
0656 ACPI_STATUS
0657 AcpiDsStoreObjectToLocal (
0658     UINT8                   Type,
0659     UINT32                  Index,
0660     ACPI_OPERAND_OBJECT     *ObjDesc,
0661     ACPI_WALK_STATE         *WalkState)
0662 {
0663     ACPI_STATUS             Status;
0664     ACPI_NAMESPACE_NODE     *Node;
0665     ACPI_OPERAND_OBJECT     *CurrentObjDesc;
0666     ACPI_OPERAND_OBJECT     *NewObjDesc;
0667 
0668 
0669     ACPI_FUNCTION_TRACE (DsStoreObjectToLocal);
0670     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%d Obj=%p\n",
0671         Type, Index, ObjDesc));
0672 
0673     /* Parameter validation */
0674 
0675     if (!ObjDesc)
0676     {
0677         return_ACPI_STATUS (AE_BAD_PARAMETER);
0678     }
0679 
0680     /* Get the namespace node for the arg/local */
0681 
0682     Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
0683     if (ACPI_FAILURE (Status))
0684     {
0685         return_ACPI_STATUS (Status);
0686     }
0687 
0688     CurrentObjDesc = AcpiNsGetAttachedObject (Node);
0689     if (CurrentObjDesc == ObjDesc)
0690     {
0691         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
0692             ObjDesc));
0693         return_ACPI_STATUS (Status);
0694     }
0695 
0696     /*
0697      * If the reference count on the object is more than one, we must
0698      * take a copy of the object before we store.  A reference count
0699      * of exactly 1 means that the object was just created during the
0700      * evaluation of an expression, and we can safely use it since it
0701      * is not used anywhere else.
0702      */
0703     NewObjDesc = ObjDesc;
0704     if (ObjDesc->Common.ReferenceCount > 1)
0705     {
0706         Status = AcpiUtCopyIobjectToIobject (ObjDesc, &NewObjDesc, WalkState);
0707         if (ACPI_FAILURE (Status))
0708         {
0709             return_ACPI_STATUS (Status);
0710         }
0711     }
0712 
0713     /*
0714      * If there is an object already in this slot, we either
0715      * have to delete it, or if this is an argument and there
0716      * is an object reference stored there, we have to do
0717      * an indirect store!
0718      */
0719     if (CurrentObjDesc)
0720     {
0721         /*
0722          * Check for an indirect store if an argument
0723          * contains an object reference (stored as an Node).
0724          * We don't allow this automatic dereferencing for
0725          * locals, since a store to a local should overwrite
0726          * anything there, including an object reference.
0727          *
0728          * If both Arg0 and Local0 contain RefOf (Local4):
0729          *
0730          * Store (1, Arg0)             - Causes indirect store to local4
0731          * Store (1, Local0)           - Stores 1 in local0, overwriting
0732          *                                  the reference to local4
0733          * Store (1, DeRefof (Local0)) - Causes indirect store to local4
0734          *
0735          * Weird, but true.
0736          */
0737         if (Type == ACPI_REFCLASS_ARG)
0738         {
0739             /*
0740              * If we have a valid reference object that came from RefOf(),
0741              * do the indirect store
0742              */
0743             if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) == ACPI_DESC_TYPE_OPERAND) &&
0744                 (CurrentObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
0745                 (CurrentObjDesc->Reference.Class == ACPI_REFCLASS_REFOF))
0746             {
0747                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
0748                         "Arg (%p) is an ObjRef(Node), storing in node %p\n",
0749                         NewObjDesc, CurrentObjDesc));
0750 
0751                 /*
0752                  * Store this object to the Node (perform the indirect store)
0753                  * NOTE: No implicit conversion is performed, as per the ACPI
0754                  * specification rules on storing to Locals/Args.
0755                  */
0756                 Status = AcpiExStoreObjectToNode (NewObjDesc,
0757                             CurrentObjDesc->Reference.Object, WalkState,
0758                             ACPI_NO_IMPLICIT_CONVERSION);
0759 
0760                 /* Remove local reference if we copied the object above */
0761 
0762                 if (NewObjDesc != ObjDesc)
0763                 {
0764                     AcpiUtRemoveReference (NewObjDesc);
0765                 }
0766                 return_ACPI_STATUS (Status);
0767             }
0768         }
0769 
0770         /* Delete the existing object before storing the new one */
0771 
0772         AcpiDsMethodDataDeleteValue (Type, Index, WalkState);
0773     }
0774 
0775     /*
0776      * Install the Obj descriptor (*NewObjDesc) into
0777      * the descriptor for the Arg or Local.
0778      * (increments the object reference count by one)
0779      */
0780     Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState);
0781 
0782     /* Remove local reference if we copied the object above */
0783 
0784     if (NewObjDesc != ObjDesc)
0785     {
0786         AcpiUtRemoveReference (NewObjDesc);
0787     }
0788 
0789     return_ACPI_STATUS (Status);
0790 }
0791 
0792 
0793 #ifdef ACPI_OBSOLETE_FUNCTIONS
0794 /*******************************************************************************
0795  *
0796  * FUNCTION:    AcpiDsMethodDataGetType
0797  *
0798  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
0799  *              Index               - Which Local or Arg whose type to get
0800  *              WalkState           - Current walk state object
0801  *
0802  * RETURN:      Data type of current value of the selected Arg or Local
0803  *
0804  * DESCRIPTION: Get the type of the object stored in the Local or Arg
0805  *
0806  ******************************************************************************/
0807 
0808 ACPI_OBJECT_TYPE
0809 AcpiDsMethodDataGetType (
0810     UINT16                  Opcode,
0811     UINT32                  Index,
0812     ACPI_WALK_STATE         *WalkState)
0813 {
0814     ACPI_STATUS             Status;
0815     ACPI_NAMESPACE_NODE     *Node;
0816     ACPI_OPERAND_OBJECT     *Object;
0817 
0818 
0819     ACPI_FUNCTION_TRACE (DsMethodDataGetType);
0820 
0821 
0822     /* Get the namespace node for the arg/local */
0823 
0824     Status = AcpiDsMethodDataGetNode (Opcode, Index, WalkState, &Node);
0825     if (ACPI_FAILURE (Status))
0826     {
0827         return_VALUE ((ACPI_TYPE_NOT_FOUND));
0828     }
0829 
0830     /* Get the object */
0831 
0832     Object = AcpiNsGetAttachedObject (Node);
0833     if (!Object)
0834     {
0835         /* Uninitialized local/arg, return TYPE_ANY */
0836 
0837         return_VALUE (ACPI_TYPE_ANY);
0838     }
0839 
0840     /* Get the object type */
0841 
0842     return_VALUE (Object->Type);
0843 }
0844 #endif
0845 
0846