FreeBSD/sys/contrib/dev/acpica/components/namespace/nsxfname.c
/******************************************************************************
 *
 * FUNCTION:    AcpiGetObjectInfo
 *
 * PARAMETERS:  Handle              - Object Handle
 *              ReturnBuffer        - Where the info is returned
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Returns information about an object as gleaned from the
 *              namespace node and possibly by running several standard
 *              control methods (Such as in the case of a device.)
 *
 * For Device and Processor objects, run the Device _HID, _UID, _CID, _STA,
 * _CLS, _ADR, _SxW, and _SxD methods.
 *
 * Note: Allocates the return buffer, must be freed by the caller.
 *
 * Note: This interface is intended to be used during the initial device
 * discovery namespace traversal. Therefore, no complex methods can be
 * executed, especially those that access operation regions. Therefore, do
 * not add any additional methods that could cause problems in this area.
 * this was the fate of the _SUB method which was found to cause such
 * problems and was removed (11/2015).
 *
 ******************************************************************************/
AcpiGetObjectInfo
PARAMETERS:  Handle              - Object Handle
ReturnBuffer        - Where the info is returned

Status

Returns information about an object as gleaned from the
namespace node and possibly by running several standard
control methods (Such as in the case of a device.)

For Device and Processor objects, run the Device _HID, _UID, _CID, _STA,
_CLS, _ADR, _SxW, and _SxD methods.

Allocates the return buffer, must be freed by the caller.

This interface is intended to be used during the initial device
discovery namespace traversal. Therefore, no complex methods can be
executed, especially those that access operation regions. Therefore, do
not add any additional methods that could cause problems in this area.
this was the fate of the _SUB method which was found to cause such
problems and was removed (11/2015).
AcpiGetObjectInfo PARAMETERS : Handle - Object Handle ReturnBuffer - Where the info is returned Status Returns information about an object as gleaned from the namespace node and possibly by running several standard control methods ( Such as in the case of a device . ) For Device and Processor objects run the Device _HID _UID _CID _STA _CLS _ADR _SxW and _SxD methods . Allocates the return buffer must be freed by the caller . This interface is intended to be used during the initial device discovery namespace traversal . Therefore no complex methods can be executed especially those that access operation regions . Therefore do not add any additional methods that could cause problems in this area . this was the fate of the _SUB method which was found to cause such problems and was removed ( 11 / 2015 ) .
ACPI_STATUS
AcpiGetObjectInfo (
    ACPI_HANDLE             Handle,
    ACPI_DEVICE_INFO        **ReturnBuffer)
{
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_DEVICE_INFO        *Info;
    ACPI_PNP_DEVICE_ID_LIST *CidList = NULL;
    ACPI_PNP_DEVICE_ID      *Hid = NULL;
    ACPI_PNP_DEVICE_ID      *Uid = NULL;
    ACPI_PNP_DEVICE_ID      *Cls = NULL;
    char                    *NextIdString;
    ACPI_OBJECT_TYPE        Type;
    ACPI_NAME               Name;
    UINT8                   ParamCount= 0;
    UINT16                  Valid = 0;
    UINT32                  InfoSize;
    UINT32                  i;
    ACPI_STATUS             Status;
    if (!Handle || !ReturnBuffer)
    {
        return (AE_BAD_PARAMETER);
    }
    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }
    Node = AcpiNsValidateHandle (Handle);
    if (!Node)
    {
        (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
        return (AE_BAD_PARAMETER);
    }
    InfoSize = sizeof (ACPI_DEVICE_INFO);
    Type = Node->Type;
    Name = Node->Name.Integer;
    if (Node->Type == ACPI_TYPE_METHOD)
    {
        ParamCount = Node->Object->Method.ParamCount;
    }
    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }
    if ((Type == ACPI_TYPE_DEVICE) ||
        (Type == ACPI_TYPE_PROCESSOR))
    {
        Status = AcpiUtExecute_HID (Node, &Hid);
        if (ACPI_SUCCESS (Status))
        {
            InfoSize += Hid->Length;
            Valid |= ACPI_VALID_HID;
        }
        Status = AcpiUtExecute_UID (Node, &Uid);
        if (ACPI_SUCCESS (Status))
        {
            InfoSize += Uid->Length;
            Valid |= ACPI_VALID_UID;
        }
        Status = AcpiUtExecute_CID (Node, &CidList);
        if (ACPI_SUCCESS (Status))
        {
            InfoSize += (CidList->ListSize - sizeof (ACPI_PNP_DEVICE_ID_LIST));
            Valid |= ACPI_VALID_CID;
        }
        Status = AcpiUtExecute_CLS (Node, &Cls);
        if (ACPI_SUCCESS (Status))
        {
            InfoSize += Cls->Length;
            Valid |= ACPI_VALID_CLS;
        }
    }
    Info = ACPI_ALLOCATE_ZEROED (InfoSize);
    if (!Info)
    {
        Status = AE_NO_MEMORY;
        goto Cleanup;
    }
    if ((Type == ACPI_TYPE_DEVICE) ||
        (Type == ACPI_TYPE_PROCESSOR))
    {
        Status = AcpiUtExecute_STA (Node, &Info->CurrentStatus);
        if (ACPI_SUCCESS (Status))
        {
            Valid |= ACPI_VALID_STA;
        }
        Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node,
            &Info->Address);
        if (ACPI_SUCCESS (Status))
        {
            Valid |= ACPI_VALID_ADR;
        }
        Status = AcpiUtExecutePowerMethods (Node,
            AcpiGbl_LowestDstateNames, ACPI_NUM_SxW_METHODS,
            Info->LowestDstates);
        if (ACPI_SUCCESS (Status))
        {
            Valid |= ACPI_VALID_SXWS;
        }
        Status = AcpiUtExecutePowerMethods (Node,
            AcpiGbl_HighestDstateNames, ACPI_NUM_SxD_METHODS,
            Info->HighestDstates);
        if (ACPI_SUCCESS (Status))
        {
            Valid |= ACPI_VALID_SXDS;
        }
    }
    NextIdString = ACPI_CAST_PTR (char, Info->CompatibleIdList.Ids);
    if (CidList)
    {
        NextIdString += ((ACPI_SIZE) CidList->Count * sizeof (ACPI_PNP_DEVICE_ID));
    }
    if (Hid)
    {
        NextIdString = AcpiNsCopyDeviceId (&Info->HardwareId,
            Hid, NextIdString);
        if (AcpiUtIsPciRootBridge (Hid->String))
        {
            Info->Flags |= ACPI_PCI_ROOT_BRIDGE;
        }
    }
    if (Uid)
    {
        NextIdString = AcpiNsCopyDeviceId (&Info->UniqueId,
            Uid, NextIdString);
    }
    if (CidList)
    {
        Info->CompatibleIdList.Count = CidList->Count;
        Info->CompatibleIdList.ListSize = CidList->ListSize;
        for (i = 0; i < CidList->Count; i++)
        {
            NextIdString = AcpiNsCopyDeviceId (&Info->CompatibleIdList.Ids[i],
                &CidList->Ids[i], NextIdString);
            if (AcpiUtIsPciRootBridge (CidList->Ids[i].String))
            {
                Info->Flags |= ACPI_PCI_ROOT_BRIDGE;
            }
        }
    }
    if (Cls)
    {
        NextIdString = AcpiNsCopyDeviceId (&Info->ClassCode,
            Cls, NextIdString);
    }
    Info->InfoSize = InfoSize;
    Info->Type = Type;
    Info->Name = Name;
    Info->ParamCount = ParamCount;
    Info->Valid = Valid;
    *ReturnBuffer = Info;
    Status = AE_OK;
Cleanup:
    if (Hid)
    {
        ACPI_FREE (Hid);
    }
    if (Uid)
    {
        ACPI_FREE (Uid);
    }
    if (CidList)
    {
        ACPI_FREE (CidList);
    }
    if (Cls)
    {
        ACPI_FREE (Cls);
    }
    return (Status);
}
ACPI_STATUS AcpiGetObjectInfo ( ACPI_HANDLE Handle , ACPI_DEVICE_INFO * * ReturnBuffer ) { ACPI_NAMESPACE_NODE * Node ; ACPI_DEVICE_INFO * Info ; ACPI_PNP_DEVICE_ID_LIST * CidList = NULL ; ACPI_PNP_DEVICE_ID * Hid = NULL ; ACPI_PNP_DEVICE_ID * Uid = NULL ; ACPI_PNP_DEVICE_ID * Cls = NULL ; char * NextIdString ; ACPI_OBJECT_TYPE Type ; ACPI_NAME Name ; UINT8 ParamCount = 0 ; UINT16 Valid = 0 ; UINT32 InfoSize ; UINT32 i ; ACPI_STATUS Status ; if ( ! Handle || ! ReturnBuffer ) { return ( AE_BAD_PARAMETER ) ; } Status = AcpiUtAcquireMutex ( ACPI_MTX_NAMESPACE ) ; if ( ACPI_FAILURE ( Status ) ) { return ( Status ) ; } Node = AcpiNsValidateHandle ( Handle ) ; if ( ! Node ) { ( void ) AcpiUtReleaseMutex ( ACPI_MTX_NAMESPACE ) ; return ( AE_BAD_PARAMETER ) ; } InfoSize = sizeof ( ACPI_DEVICE_INFO ) ; Type = Node -> Type ; Name = Node -> Name . Integer ; if ( Node -> Type == ACPI_TYPE_METHOD ) { ParamCount = Node -> Object -> Method . ParamCount ; } Status = AcpiUtReleaseMutex ( ACPI_MTX_NAMESPACE ) ; if ( ACPI_FAILURE ( Status ) ) { return ( Status ) ; } if ( ( Type == ACPI_TYPE_DEVICE ) || ( Type == ACPI_TYPE_PROCESSOR ) ) { Status = AcpiUtExecute_HID ( Node , & Hid ) ; if ( ACPI_SUCCESS ( Status ) ) { InfoSize += Hid -> Length ; Valid |= ACPI_VALID_HID ; } Status = AcpiUtExecute_UID ( Node , & Uid ) ; if ( ACPI_SUCCESS ( Status ) ) { InfoSize += Uid -> Length ; Valid |= ACPI_VALID_UID ; } Status = AcpiUtExecute_CID ( Node , & CidList ) ; if ( ACPI_SUCCESS ( Status ) ) { InfoSize += ( CidList -> ListSize - sizeof ( ACPI_PNP_DEVICE_ID_LIST ) ) ; Valid |= ACPI_VALID_CID ; } Status = AcpiUtExecute_CLS ( Node , & Cls ) ; if ( ACPI_SUCCESS ( Status ) ) { InfoSize += Cls -> Length ; Valid |= ACPI_VALID_CLS ; } } Info = ACPI_ALLOCATE_ZEROED ( InfoSize ) ; if ( ! Info ) { Status = AE_NO_MEMORY ; goto Cleanup ; } if ( ( Type == ACPI_TYPE_DEVICE ) || ( Type == ACPI_TYPE_PROCESSOR ) ) { Status = AcpiUtExecute_STA ( Node , & Info -> CurrentStatus ) ; if ( ACPI_SUCCESS ( Status ) ) { Valid |= ACPI_VALID_STA ; } Status = AcpiUtEvaluateNumericObject ( METHOD_NAME__ADR , Node , & Info -> Address ) ; if ( ACPI_SUCCESS ( Status ) ) { Valid |= ACPI_VALID_ADR ; } Status = AcpiUtExecutePowerMethods ( Node , AcpiGbl_LowestDstateNames , ACPI_NUM_SxW_METHODS , Info -> LowestDstates ) ; if ( ACPI_SUCCESS ( Status ) ) { Valid |= ACPI_VALID_SXWS ; } Status = AcpiUtExecutePowerMethods ( Node , AcpiGbl_HighestDstateNames , ACPI_NUM_SxD_METHODS , Info -> HighestDstates ) ; if ( ACPI_SUCCESS ( Status ) ) { Valid |= ACPI_VALID_SXDS ; } } NextIdString = ACPI_CAST_PTR ( char , Info -> CompatibleIdList . Ids ) ; if ( CidList ) { NextIdString += ( ( ACPI_SIZE ) CidList -> Count * sizeof ( ACPI_PNP_DEVICE_ID ) ) ; } if ( Hid ) { NextIdString = AcpiNsCopyDeviceId ( & Info -> HardwareId , Hid , NextIdString ) ; if ( AcpiUtIsPciRootBridge ( Hid -> String ) ) { Info -> Flags |= ACPI_PCI_ROOT_BRIDGE ; } } if ( Uid ) { NextIdString = AcpiNsCopyDeviceId ( & Info -> UniqueId , Uid , NextIdString ) ; } if ( CidList ) { Info -> CompatibleIdList . Count = CidList -> Count ; Info -> CompatibleIdList . ListSize = CidList -> ListSize ; for ( i = 0 ; i < CidList -> Count ; i ++ ) { NextIdString = AcpiNsCopyDeviceId ( & Info -> CompatibleIdList . Ids [ i ] , & CidList -> Ids [ i ] , NextIdString ) ; if ( AcpiUtIsPciRootBridge ( CidList -> Ids [ i ] . String ) ) { Info -> Flags |= ACPI_PCI_ROOT_BRIDGE ; } } } if ( Cls ) { NextIdString = AcpiNsCopyDeviceId ( & Info -> ClassCode , Cls , NextIdString ) ; } Info -> InfoSize = InfoSize ; Info -> Type = Type ; Info -> Name = Name ; Info -> ParamCount = ParamCount ; Info -> Valid = Valid ; * ReturnBuffer = Info ; Status = AE_OK ; Cleanup : if ( Hid ) { ACPI_FREE ( Hid ) ; } if ( Uid ) { ACPI_FREE ( Uid ) ; } if ( CidList ) { ACPI_FREE ( CidList ) ; } if ( Cls ) { ACPI_FREE ( Cls ) ; } return ( Status ) ; }
FUNCTION:    AcpiGetObjectInfo
 PARAMETERS:  Handle              - Object Handle
              ReturnBuffer        - Where the info is returned
FUNCTION : AcpiGetObjectInfo PARAMETERS : Handle - Object Handle ReturnBuffer - Where the info is returned
/* Parameter validation */ /* Get the namespace node data while the namespace is locked */ /*
         * Get extra info for ACPI Device/Processor objects only:
         * Run the Device _HID, _UID, _CLS, and _CID methods.
         *
         * Note: none of these methods are required, so they may or may
         * not be present for this device. The Info->Valid bitfield is used
         * to indicate which methods were found and run successfully.
         */ /* Execute the Device._HID method */ /* Execute the Device._UID method */ /* Execute the Device._CID method */ /* Add size of CID strings and CID pointer array */ /* Execute the Device._CLS method */ /*
     * Now that we have the variable-length data, we can allocate the
     * return buffer
     */ /* Get the fixed-length data */ /*
         * Get extra info for ACPI Device/Processor objects only:
         * Run the _STA, _ADR and, SxW, and _SxD methods.
         *
         * Notes: none of these methods are required, so they may or may
         * not be present for this device. The Info->Valid bitfield is used
         * to indicate which methods were found and run successfully.
         *
         * For _STA, if the method does not exist, then (as per the ACPI
         * specification), the returned CurrentStatus flags will indicate
         * that the device is present/functional/enabled. Otherwise, the
         * CurrentStatus flags reflect the value returned from _STA.
         */ /* Execute the Device._STA method */ /* Execute the Device._ADR method */ /* Execute the Device._SxW methods */ /* Execute the Device._SxD methods */ /*
     * Create a pointer to the string area of the return buffer.
     * Point to the end of the base ACPI_DEVICE_INFO structure.
     */ /* Point past the CID PNP_DEVICE_ID array */ /*
     * Copy the HID, UID, and CIDs to the return buffer. The variable-length
     * strings are copied to the reserved area at the end of the buffer.
     *
     * For HID and CID, check if the ID is a PCI Root Bridge.
     */ /* Copy each CID */ /* Copy the fixed-length data */