Exemple #1
0
static BOOLEAN
AcpiEvIsPciRootBridge (
    ACPI_NAMESPACE_NODE     *Node)
{
    ACPI_STATUS             Status;
    ACPI_PNP_DEVICE_ID      *Hid;
    ACPI_PNP_DEVICE_ID_LIST *Cid;
    UINT32                  i;
    BOOLEAN                 Match;


    /* Get the _HID and check for a PCI Root Bridge */

    Status = AcpiUtExecute_HID (Node, &Hid);
    if (ACPI_FAILURE (Status))
    {
        return (FALSE);
    }

    Match = AcpiUtIsPciRootBridge (Hid->String);
    ACPI_FREE (Hid);

    if (Match)
    {
        return (TRUE);
    }

    /* The _HID did not match. Get the _CID and check for a PCI Root Bridge */

    Status = AcpiUtExecute_CID (Node, &Cid);
    if (ACPI_FAILURE (Status))
    {
        return (FALSE);
    }

    /* Check all _CIDs in the returned list */

    for (i = 0; i < Cid->Count; i++)
    {
        if (AcpiUtIsPciRootBridge (Cid->Ids[i].String))
        {
            ACPI_FREE (Cid);
            return (TRUE);
        }
    }

    ACPI_FREE (Cid);
    return (FALSE);
}
Exemple #2
0
static BOOLEAN
AcpiEvIsPciRootBridge (
    ACPI_NAMESPACE_NODE     *Node)
{
    ACPI_STATUS             Status;
    ACPI_DEVICE_ID          Hid;
    ACPI_COMPATIBLE_ID_LIST *Cid;
    ACPI_NATIVE_UINT        i;


    /*
     * Get the _HID and check for a PCI Root Bridge
     */
    Status = AcpiUtExecute_HID (Node, &Hid);
    if (ACPI_FAILURE (Status))
    {
        return (FALSE);
    }

    if (AcpiEvMatchPciRootBridge (Hid.Value))
    {
        return (TRUE);
    }

    /*
     * The _HID did not match.
     * Get the _CID and check for a PCI Root Bridge
     */
    Status = AcpiUtExecute_CID (Node, &Cid);
    if (ACPI_FAILURE (Status))
    {
        return (FALSE);
    }

    /* Check all _CIDs in the returned list */

    for (i = 0; i < Cid->Count; i++)
    {
        if (AcpiEvMatchPciRootBridge (Cid->Id[i].Value))
        {
            ACPI_FREE (Cid);
            return (TRUE);
        }
    }

    ACPI_FREE (Cid);
    return (FALSE);
}
Exemple #3
0
static ACPI_STATUS
AcpiNsGetDeviceCallback (
    ACPI_HANDLE             ObjHandle,
    UINT32                  NestingLevel,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_GET_DEVICES_INFO   *Info = Context;
    ACPI_STATUS             Status;
    ACPI_NAMESPACE_NODE     *Node;
    UINT32                  Flags;
    ACPI_PNP_DEVICE_ID      *Hid;
    ACPI_PNP_DEVICE_ID_LIST *Cid;
    UINT32                  i;
    BOOLEAN                 Found;
    int                     NoMatch;


    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    Node = AcpiNsValidateHandle (ObjHandle);
    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    if (!Node)
    {
        return (AE_BAD_PARAMETER);
    }

    /*
     * First, filter based on the device HID and CID.
     *
     * 01/2010: For this case where a specific HID is requested, we don't
     * want to run _STA until we have an actual HID match. Thus, we will
     * not unnecessarily execute _STA on devices for which the caller
     * doesn't care about. Previously, _STA was executed unconditionally
     * on all devices found here.
     *
     * A side-effect of this change is that now we will continue to search
     * for a matching HID even under device trees where the parent device
     * would have returned a _STA that indicates it is not present or
     * not functioning (thus aborting the search on that branch).
     */
    if (Info->Hid != NULL)
    {
        Status = AcpiUtExecute_HID (Node, &Hid);
        if (Status == AE_NOT_FOUND)
        {
            return (AE_OK);
        }
        else if (ACPI_FAILURE (Status))
        {
            return (AE_CTRL_DEPTH);
        }

        NoMatch = strcmp (Hid->String, Info->Hid);
        ACPI_FREE (Hid);

        if (NoMatch)
        {
            /*
             * HID does not match, attempt match within the
             * list of Compatible IDs (CIDs)
             */
            Status = AcpiUtExecute_CID (Node, &Cid);
            if (Status == AE_NOT_FOUND)
            {
                return (AE_OK);
            }
            else if (ACPI_FAILURE (Status))
            {
                return (AE_CTRL_DEPTH);
            }

            /* Walk the CID list */

            Found = FALSE;
            for (i = 0; i < Cid->Count; i++)
            {
                if (strcmp (Cid->Ids[i].String, Info->Hid) == 0)
                {
                    /* Found a matching CID */

                    Found = TRUE;
                    break;
                }
            }

            ACPI_FREE (Cid);
            if (!Found)
            {
                return (AE_OK);
            }
        }
    }

    /* Run _STA to determine if device is present */

    Status = AcpiUtExecute_STA (Node, &Flags);
    if (ACPI_FAILURE (Status))
    {
        return (AE_CTRL_DEPTH);
    }

    if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
        !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
    {
        /*
         * Don't examine the children of the device only when the
         * device is neither present nor functional. See ACPI spec,
         * description of _STA for more information.
         */
        return (AE_CTRL_DEPTH);
    }

    /* We have a valid device, invoke the user function */

    Status = Info->UserFunction (ObjHandle, NestingLevel,
        Info->Context, ReturnValue);
    return (Status);
}
static ACPI_STATUS
AcpiNsGetDeviceCallback (
    ACPI_HANDLE             ObjHandle,
    UINT32                  NestingLevel,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_GET_DEVICES_INFO   *Info = Context;
    ACPI_STATUS             Status;
    ACPI_NAMESPACE_NODE     *Node;
    UINT32                  Flags;
    ACPI_DEVICE_ID          *Hid;
    ACPI_DEVICE_ID_LIST     *Cid;
    UINT32                  i;
    BOOLEAN                 Found;
    int                     NoMatch;


    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    Node = AcpiNsValidateHandle (ObjHandle);
    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    if (!Node)
    {
        return (AE_BAD_PARAMETER);
    }

    /* Run _STA to determine if device is present */

    Status = AcpiUtExecute_STA (Node, &Flags);
    if (ACPI_FAILURE (Status))
    {
        return (AE_CTRL_DEPTH);
    }

    if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
        !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
    {
        /*
         * Don't examine the children of the device only when the
         * device is neither present nor functional. See ACPI spec,
         * description of _STA for more information.
         */
        return (AE_CTRL_DEPTH);
    }

    /* Filter based on device HID & CID */

    if (Info->Hid != NULL)
    {
        Status = AcpiUtExecute_HID (Node, &Hid);
        if (Status == AE_NOT_FOUND)
        {
            return (AE_OK);
        }
        else if (ACPI_FAILURE (Status))
        {
            return (AE_CTRL_DEPTH);
        }

        NoMatch = ACPI_STRCMP (Hid->String, Info->Hid);
        ACPI_FREE (Hid);

        if (NoMatch)
        {
            /*
             * HID does not match, attempt match within the
             * list of Compatible IDs (CIDs)
             */
            Status = AcpiUtExecute_CID (Node, &Cid);
            if (Status == AE_NOT_FOUND)
            {
                return (AE_OK);
            }
            else if (ACPI_FAILURE (Status))
            {
                return (AE_CTRL_DEPTH);
            }

            /* Walk the CID list */

            Found = FALSE;
            for (i = 0; i < Cid->Count; i++)
            {
                if (ACPI_STRCMP (Cid->Ids[i].String, Info->Hid) == 0)
                {
                    /* Found a matching CID */

                    Found = TRUE;
                    break;
                }
            }

            ACPI_FREE (Cid);
            if (!Found)
            {
                return (AE_OK);
            }
        }
    }

    /* We have a valid device, invoke the user function */

    Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context,
                ReturnValue);
    return (Status);
}
Exemple #5
0
ACPI_STATUS
AcpiGetObjectInfo (
    ACPI_HANDLE             Handle,
    ACPI_BUFFER             *Buffer)
{
    ACPI_STATUS             Status;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_DEVICE_INFO        *Info;
    ACPI_DEVICE_INFO        *ReturnInfo;
    ACPI_COMPATIBLE_ID_LIST *CidList = NULL;
    ACPI_SIZE               Size;


    /* Parameter validation */

    if (!Handle || !Buffer)
    {
        return (AE_BAD_PARAMETER);
    }

    Status = AcpiUtValidateBuffer (Buffer);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_DEVICE_INFO));
    if (!Info)
    {
        return (AE_NO_MEMORY);
    }

    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    Node = AcpiNsMapHandleToNode (Handle);
    if (!Node)
    {
        (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
        goto Cleanup;
    }

    /* Init return structure */

    Size = sizeof (ACPI_DEVICE_INFO);

    Info->Type  = Node->Type;
    Info->Name  = Node->Name.Integer;
    Info->Valid = 0;

    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    /* If not a device, we are all done */

    if (Info->Type == ACPI_TYPE_DEVICE)
    {
        /*
         * Get extra info for ACPI Devices objects only:
         * Run the Device _HID, _UID, _CID, _STA, _ADR and _SxD 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 ran successfully.
         */

        /* Execute the Device._HID method */

        Status = AcpiUtExecute_HID (Node, &Info->HardwareId);
        if (ACPI_SUCCESS (Status))
        {
            Info->Valid |= ACPI_VALID_HID;
        }

        /* Execute the Device._UID method */

        Status = AcpiUtExecute_UID (Node, &Info->UniqueId);
        if (ACPI_SUCCESS (Status))
        {
            Info->Valid |= ACPI_VALID_UID;
        }

        /* Execute the Device._CID method */

        Status = AcpiUtExecute_CID (Node, &CidList);
        if (ACPI_SUCCESS (Status))
        {
            Size += CidList->Size;
            Info->Valid |= ACPI_VALID_CID;
        }

        /* Execute the Device._STA method */

        Status = AcpiUtExecute_STA (Node, &Info->CurrentStatus);
        if (ACPI_SUCCESS (Status))
        {
            Info->Valid |= ACPI_VALID_STA;
        }

        /* Execute the Device._ADR method */

        Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node,
                        &Info->Address);
        if (ACPI_SUCCESS (Status))
        {
            Info->Valid |= ACPI_VALID_ADR;
        }

        /* Execute the Device._SxD methods */

        Status = AcpiUtExecute_Sxds (Node, Info->HighestDstates);
        if (ACPI_SUCCESS (Status))
        {
            Info->Valid |= ACPI_VALID_SXDS;
        }
    }

    /* Validate/Allocate/Clear caller buffer */

    Status = AcpiUtInitializeBuffer (Buffer, Size);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    /* Populate the return buffer */

    ReturnInfo = Buffer->Pointer;
    ACPI_MEMCPY (ReturnInfo, Info, sizeof (ACPI_DEVICE_INFO));

    if (CidList)
    {
        ACPI_MEMCPY (&ReturnInfo->CompatibilityId, CidList, CidList->Size);
    }


Cleanup:
    ACPI_FREE (Info);
    if (CidList)
    {
        ACPI_FREE (CidList);
    }
    return (Status);
}
Exemple #6
0
static ACPI_STATUS
AcpiNsGetDeviceCallback (
    ACPI_HANDLE             ObjHandle,
    UINT32                  NestingLevel,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_GET_DEVICES_INFO   *Info = Context;
    ACPI_STATUS             Status;
    ACPI_NAMESPACE_NODE     *Node;
    UINT32                  Flags;
    ACPI_DEVICE_ID          Hid;
    ACPI_COMPATIBLE_ID_LIST *Cid;
    ACPI_NATIVE_UINT        i;


    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    Node = AcpiNsMapHandleToNode (ObjHandle);
    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    if (!Node)
    {
        return (AE_BAD_PARAMETER);
    }

    /* Run _STA to determine if device is present */

    Status = AcpiUtExecute_STA (Node, &Flags);
    if (ACPI_FAILURE (Status))
    {
        return (AE_CTRL_DEPTH);
    }

    if (!(Flags & ACPI_STA_DEVICE_PRESENT))
    {
        /* Don't examine children of the device if not present */

        return (AE_CTRL_DEPTH);
    }

    /* Filter based on device HID & CID */

    if (Info->Hid != NULL)
    {
        Status = AcpiUtExecute_HID (Node, &Hid);
        if (Status == AE_NOT_FOUND)
        {
            return (AE_OK);
        }
        else if (ACPI_FAILURE (Status))
        {
            return (AE_CTRL_DEPTH);
        }

        if (ACPI_STRNCMP (Hid.Value, Info->Hid, sizeof (Hid.Value)) != 0)
        {
            /* Get the list of Compatible IDs */

            Status = AcpiUtExecute_CID (Node, &Cid);
            if (Status == AE_NOT_FOUND)
            {
                return (AE_OK);
            }
            else if (ACPI_FAILURE (Status))
            {
                return (AE_CTRL_DEPTH);
            }

            /* Walk the CID list */

            for (i = 0; i < Cid->Count; i++)
            {
                if (ACPI_STRNCMP (Cid->Id[i].Value, Info->Hid,
                                        sizeof (ACPI_COMPATIBLE_ID)) != 0)
                {
                    ACPI_FREE (Cid);
                    return (AE_OK);
                }
            }
            ACPI_FREE (Cid);
        }
    }

    Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context,
                ReturnValue);
    return (Status);
}