FreeBSD/sys/contrib/dev/acpica/common/adwalk.c
/*******************************************************************************
 *
 * FUNCTION:    AcpiDmXrefDescendingOp
 *
 * PARAMETERS:  ASL_WALK_CALLBACK
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Descending handler for namespace cross reference
 *
 ******************************************************************************/


Status

Descending handler for namespace cross reference
Status Descending handler for namespace cross reference
static ACPI_STATUS
AcpiDmXrefDescendingOp (
    ACPI_PARSE_OBJECT       *Op,
    UINT32                  Level,
    void                    *Context)
{
    ACPI_OP_WALK_INFO       *Info = Context;
    const ACPI_OPCODE_INFO  *OpInfo;
    ACPI_WALK_STATE         *WalkState;
    ACPI_OBJECT_TYPE        ObjectType;
    ACPI_OBJECT_TYPE        ObjectType2;
    ACPI_STATUS             Status;
    char                    *Path = NULL;
    ACPI_PARSE_OBJECT       *NextOp;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_OPERAND_OBJECT     *Object;
    UINT32                  ParamCount = 0;
    char                    *Pathname;
    UINT16                  Flags = 0;
    WalkState = Info->WalkState;
    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    ObjectType = OpInfo->ObjectType;
    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
    if ((!(OpInfo->Flags & AML_NAMED)) &&
        (!(OpInfo->Flags & AML_CREATE)) &&
        (Op->Common.AmlOpcode != AML_INT_NAMEPATH_OP) &&
        (Op->Common.AmlOpcode != AML_NOTIFY_OP))
    {
        goto Exit;
    }
    else if (Op->Common.Parent &&
             Op->Common.Parent->Common.AmlOpcode == AML_EXTERNAL_OP)
    {
        Path = Op->Common.Value.String;
        ObjectType = (ACPI_OBJECT_TYPE) Op->Common.Next->Common.Value.Integer;
        if (ObjectType == ACPI_TYPE_METHOD)
        {
            ParamCount = (UINT32)
                Op->Common.Next->Common.Next->Common.Value.Integer;
        }
        Flags |= ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_OPCODE;
        AcpiDmAddOpToExternalList (Op, Path,
            (UINT8) ObjectType, ParamCount, Flags);
        goto Exit;
    }
    if (OpInfo->Flags & AML_NAMED)
    {
        if (Op->Common.AmlOpcode == AML_ALIAS_OP)
        {
            ObjectType = ACPI_TYPE_ANY;
            NextOp = Op->Common.Value.Arg;
            NextOp = NextOp->Common.Value.Arg;
            if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
            {
                Path = NextOp->Common.Value.String;
            }
        }
        else if (Op->Common.AmlOpcode == AML_SCOPE_OP)
        {
            Path = (char *) Op->Named.Path;
        }
    }
    else if (OpInfo->Flags & AML_CREATE)
    {
        ObjectType = ACPI_TYPE_BUFFER; 
        NextOp = Op->Common.Value.Arg;
        if (NextOp->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
        {
            Path = NextOp->Common.Value.String;
        }
    }
    else if (Op->Common.AmlOpcode == AML_NOTIFY_OP)
    {
        Path = Op->Common.Value.Arg->Asl.Value.String;
    }
    else
    {
        Path = Op->Common.Value.String;
    }
    if (!Path)
    {
        goto Exit;
    }
    Node = NULL;
    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,
        ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
        WalkState, &Node);
    if (ACPI_SUCCESS (Status) && (Node->Flags & ANOBJ_IS_EXTERNAL))
    {
        Status = AE_NOT_FOUND;
    }
    if (ACPI_FAILURE (Status))
    {
        if (Status == AE_NOT_FOUND)
        {
            if (!(Op->Asl.Parent &&
                (Op->Asl.Parent->Asl.AmlOpcode == AML_COND_REF_OF_OP)))
            {
                if (Node)
                {
                    AcpiDmAddNodeToExternalList (Node,
                        (UINT8) ObjectType, 7, Flags);
                }
                else
                {
                    AcpiDmAddOpToExternalList (Op, Path,
                        (UINT8) ObjectType, 7, Flags);
                }
            }
        }
    }
    else if (Node->OwnerId &&
            (WalkState->OwnerId != Node->OwnerId))
    {
        ObjectType2 = ObjectType;
        Object = AcpiNsGetAttachedObject (Node);
        if (Object)
        {
            ObjectType2 = Object->Common.Type;
            if (ObjectType2 == ACPI_TYPE_METHOD)
            {
                ParamCount = Object->Method.ParamCount;
            }
        }
        Pathname = AcpiNsGetExternalPathname (Node);
        if (!Pathname)
        {
            return (AE_NO_MEMORY);
        }
        AcpiDmAddNodeToExternalList (Node, (UINT8) ObjectType2,
            ParamCount, ACPI_EXT_RESOLVED_REFERENCE);
        ACPI_FREE (Pathname);
        Op->Common.Node = Node;
    }
    else
    {
        Op->Common.Node = Node;
    }
Exit:
    if (AcpiNsOpensScope (ObjectType))
    {
        if (Op->Common.Node)
        {
            Status = AcpiDsScopeStackPush (Op->Common.Node, ObjectType,
                WalkState);
            if (ACPI_FAILURE (Status))
            {
                return (Status);
            }
        }
    }
    return (AE_OK);
}
static ACPI_STATUS AcpiDmXrefDescendingOp ( ACPI_PARSE_OBJECT * Op , UINT32 Level , void * Context ) { ACPI_OP_WALK_INFO * Info = Context ; const ACPI_OPCODE_INFO * OpInfo ; ACPI_WALK_STATE * WalkState ; ACPI_OBJECT_TYPE ObjectType ; ACPI_OBJECT_TYPE ObjectType2 ; ACPI_STATUS Status ; char * Path = NULL ; ACPI_PARSE_OBJECT * NextOp ; ACPI_NAMESPACE_NODE * Node ; ACPI_OPERAND_OBJECT * Object ; UINT32 ParamCount = 0 ; char * Pathname ; UINT16 Flags = 0 ; WalkState = Info -> WalkState ; OpInfo = AcpiPsGetOpcodeInfo ( Op -> Common . AmlOpcode ) ; ObjectType = OpInfo -> ObjectType ; ObjectType = AslMapNamedOpcodeToDataType ( Op -> Asl . AmlOpcode ) ; if ( ( ! ( OpInfo -> Flags & AML_NAMED ) ) && ( ! ( OpInfo -> Flags & AML_CREATE ) ) && ( Op -> Common . AmlOpcode != AML_INT_NAMEPATH_OP ) && ( Op -> Common . AmlOpcode != AML_NOTIFY_OP ) ) { goto Exit ; } else if ( Op -> Common . Parent && Op -> Common . Parent -> Common . AmlOpcode == AML_EXTERNAL_OP ) { Path = Op -> Common . Value . String ; ObjectType = ( ACPI_OBJECT_TYPE ) Op -> Common . Next -> Common . Value . Integer ; if ( ObjectType == ACPI_TYPE_METHOD ) { ParamCount = ( UINT32 ) Op -> Common . Next -> Common . Next -> Common . Value . Integer ; } Flags |= ACPI_EXT_RESOLVED_REFERENCE | ACPI_EXT_ORIGIN_FROM_OPCODE ; AcpiDmAddOpToExternalList ( Op , Path , ( UINT8 ) ObjectType , ParamCount , Flags ) ; goto Exit ; } if ( OpInfo -> Flags & AML_NAMED ) { if ( Op -> Common . AmlOpcode == AML_ALIAS_OP ) { ObjectType = ACPI_TYPE_ANY ; NextOp = Op -> Common . Value . Arg ; NextOp = NextOp -> Common . Value . Arg ; if ( NextOp -> Common . AmlOpcode == AML_INT_NAMEPATH_OP ) { Path = NextOp -> Common . Value . String ; } } else if ( Op -> Common . AmlOpcode == AML_SCOPE_OP ) { Path = ( char * ) Op -> Named . Path ; } } else if ( OpInfo -> Flags & AML_CREATE ) { ObjectType = ACPI_TYPE_BUFFER ; NextOp = Op -> Common . Value . Arg ; if ( NextOp -> Common . AmlOpcode == AML_INT_NAMEPATH_OP ) { Path = NextOp -> Common . Value . String ; } } else if ( Op -> Common . AmlOpcode == AML_NOTIFY_OP ) { Path = Op -> Common . Value . Arg -> Asl . Value . String ; } else { Path = Op -> Common . Value . String ; } if ( ! Path ) { goto Exit ; } Node = NULL ; Status = AcpiNsLookup ( WalkState -> ScopeInfo , Path , ACPI_TYPE_ANY , ACPI_IMODE_EXECUTE , ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE , WalkState , & Node ) ; if ( ACPI_SUCCESS ( Status ) && ( Node -> Flags & ANOBJ_IS_EXTERNAL ) ) { Status = AE_NOT_FOUND ; } if ( ACPI_FAILURE ( Status ) ) { if ( Status == AE_NOT_FOUND ) { if ( ! ( Op -> Asl . Parent && ( Op -> Asl . Parent -> Asl . AmlOpcode == AML_COND_REF_OF_OP ) ) ) { if ( Node ) { AcpiDmAddNodeToExternalList ( Node , ( UINT8 ) ObjectType , 7 , Flags ) ; } else { AcpiDmAddOpToExternalList ( Op , Path , ( UINT8 ) ObjectType , 7 , Flags ) ; } } } } else if ( Node -> OwnerId && ( WalkState -> OwnerId != Node -> OwnerId ) ) { ObjectType2 = ObjectType ; Object = AcpiNsGetAttachedObject ( Node ) ; if ( Object ) { ObjectType2 = Object -> Common . Type ; if ( ObjectType2 == ACPI_TYPE_METHOD ) { ParamCount = Object -> Method . ParamCount ; } } Pathname = AcpiNsGetExternalPathname ( Node ) ; if ( ! Pathname ) { return ( AE_NO_MEMORY ) ; } AcpiDmAddNodeToExternalList ( Node , ( UINT8 ) ObjectType2 , ParamCount , ACPI_EXT_RESOLVED_REFERENCE ) ; ACPI_FREE ( Pathname ) ; Op -> Common . Node = Node ; } else { Op -> Common . Node = Node ; } Exit : if ( AcpiNsOpensScope ( ObjectType ) ) { if ( Op -> Common . Node ) { Status = AcpiDsScopeStackPush ( Op -> Common . Node , ObjectType , WalkState ) ; if ( ACPI_FAILURE ( Status ) ) { return ( Status ) ; } } } return ( AE_OK ) ; }
FUNCTION:    AcpiDmXrefDescendingOp
 PARAMETERS:  ASL_WALK_CALLBACK
FUNCTION : AcpiDmXrefDescendingOp PARAMETERS : ASL_WALK_CALLBACK
/* External() NamePath */ /* Get the NamePath from the appropriate place */ /*
         * Only these two operators (Alias, Scope) refer to an existing
         * name, it is the first argument
         */ /* Referenced Buffer Name is the first child */ /* Change from TYPE_BUFFER_FIELD */ /*
     * Lookup the name in the namespace. Name must exist at this point, or it
     * is an invalid reference.
     *
     * The namespace is also used as a lookup table for references to resource
     * descriptors and the fields within them.
     */ /* Node was created by an External() statement */ /*
             * Add this symbol as an external declaration, except if the
             * parent is a CondRefOf operator. For this operator, we do not
             * need an external, nor do we want one, since this can cause
             * disassembly problems if the symbol is actually a control
             * method.
             */ /*
     * Found the node, but check if it came from an external table.
     * Add it to external list. Note: Node->OwnerId == 0 indicates
     * one of the built-in ACPI Names (_OS_ etc.) which can safely
     * be ignored.
     */ /* Open new scope if necessary */