예제 #1
0
파일: evrgnini.c 프로젝트: 2asoft/freebsd
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);
}
예제 #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);
}
예제 #3
0
파일: nsxfeval.c 프로젝트: AmirAbrams/haiku
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);
}
예제 #4
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_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);
}
예제 #5
0
파일: nsxfname.c 프로젝트: samueldotj/AceOS
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);
}
예제 #6
0
파일: nsxfname.c 프로젝트: MarginC/kame
ACPI_STATUS
AcpiGetObjectInfo (
    ACPI_HANDLE             Handle,
    ACPI_DEVICE_INFO        *Info)
{
    ACPI_DEVICE_ID          Hid;
    ACPI_DEVICE_ID          Uid;
    ACPI_STATUS             Status;
    UINT32                  DeviceStatus = 0;
    ACPI_INTEGER            Address = 0;
    ACPI_NAMESPACE_NODE     *Node;


    /* Ensure that ACPI has been initialized */

    ACPI_IS_INITIALIZATION_COMPLETE (Status);
    if (ACPI_FAILURE (Status))
    {
        return (Status);
    }

    /* Parameter validation */

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

    AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);

    Node = AcpiNsConvertHandleToEntry (Handle);
    if (!Node)
    {
        AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
        return (AE_BAD_PARAMETER);
    }

    Info->Type      = Node->Type;
    Info->Name      = Node->Name;

    AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);

    /*
     * If not a device, we are all done.
     */
    if (Info->Type != ACPI_TYPE_DEVICE)
    {
        return (AE_OK);
    }


    /*
     * Get extra info for ACPI devices only.  Run the
     * _HID, _UID, _STA, and _ADR methods.  Note: none
     * of these methods are required, so they may or may
     * not be present.  The Info->Valid bits are used
     * to indicate which methods ran successfully.
     */
    Info->Valid = 0;

    /* Execute the _HID method and save the result */

    Status = AcpiUtExecute_HID (Node, &Hid);
    if (ACPI_SUCCESS (Status))
    {
        STRNCPY (Info->HardwareId, Hid.Buffer, sizeof(Info->HardwareId));

        Info->Valid |= ACPI_VALID_HID;
    }

    /* Execute the _UID method and save the result */

    Status = AcpiUtExecute_UID (Node, &Uid);
    if (ACPI_SUCCESS (Status))
    {
        STRCPY (Info->UniqueId, Uid.Buffer);

        Info->Valid |= ACPI_VALID_UID;
    }

    /*
     * Execute the _STA method and save the result
     * _STA is not always present
     */
    Status = AcpiUtExecute_STA (Node, &DeviceStatus);
    if (ACPI_SUCCESS (Status))
    {
        Info->CurrentStatus = DeviceStatus;
        Info->Valid |= ACPI_VALID_STA;
    }

    /*
     * Execute the _ADR method and save result if successful
     * _ADR is not always present
     */
    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
                                            Node, &Address);

    if (ACPI_SUCCESS (Status))
    {
        Info->Address = Address;
        Info->Valid |= ACPI_VALID_ADR;
    }

    return (AE_OK);
}
예제 #7
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);
}
예제 #8
0
ACPI_STATUS
AcpiEvPciConfigRegionSetup (
    ACPI_HANDLE             Handle,
    UINT32                  Function,
    void                    *HandlerContext,
    void                    **RegionContext)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_INTEGER            Temp;
    ACPI_PCI_ID             *PciId = *RegionContext;
    ACPI_OPERAND_OBJECT     *HandlerObj;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_OPERAND_OBJECT     *RegionObj = (ACPI_OPERAND_OBJECT  *) Handle;
    ACPI_DEVICE_ID          ObjectHID;


    ACPI_FUNCTION_TRACE ("EvPciConfigRegionSetup");


    HandlerObj = RegionObj->Region.AddrHandler;
    if (!HandlerObj)
    {
        /*
         * No installed handler. This shouldn't happen because the dispatch
         * routine checks before we get here, but we check again just in case.
         */
        ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
            "Attempting to init a region %p, with no handler\n", RegionObj));
        return_ACPI_STATUS (AE_NOT_EXIST);
    }

    if (Function == ACPI_REGION_DEACTIVATE)
    {
        if (PciId)
        {
            ACPI_MEM_FREE (PciId);
            *RegionContext = NULL;
        }

        return_ACPI_STATUS (Status);
    }

    /* Create a new context */

    PciId = ACPI_MEM_CALLOCATE (sizeof (ACPI_PCI_ID));
    if (!PciId)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /*
     * For PCI Config space access, we have to pass the segment, bus,
     * device and function numbers.  This routine must acquire those.
     */

    /*
     * First get device and function numbers from the _ADR object
     * in the parent's scope.
     */
    Node = AcpiNsGetParentNode (RegionObj->Region.Node);

    /* Evaluate the _ADR object */

    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &Temp);

    /*
     * The default is zero, and since the allocation above zeroed
     * the data, just do nothing on failure.
     */
    if (ACPI_SUCCESS (Status))
    {
        PciId->Device   = ACPI_HIWORD (ACPI_LODWORD (Temp));
        PciId->Function = ACPI_LOWORD (ACPI_LODWORD (Temp));
    }

    /*
     * Get the _SEG and _BBN values from the device upon which the handler
     * is installed.
     *
     * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
     * This is the device the handler has been registered to handle.
     */

    /*
     * If the AddrHandler.Node is still pointing to the root, we need
     * to scan upward for a PCI Root bridge and re-associate the OpRegion
     * handlers with that device.
     */
    if (HandlerObj->AddrHandler.Node == AcpiGbl_RootNode)
    {
        /*
         * Node is currently the parent object
         */
        while (Node != AcpiGbl_RootNode)
        {
            Status = AcpiUtExecute_HID (Node, &ObjectHID);
            if (ACPI_SUCCESS (Status))
            {
                /* Got a valid _HID, check if this is a PCI root */

                if (!(ACPI_STRNCMP (ObjectHID.Buffer, PCI_ROOT_HID_STRING,
                                    sizeof (PCI_ROOT_HID_STRING))))
                {
                    /* Install a handler for this PCI root bridge */

                    Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) Node,
                                        ACPI_ADR_SPACE_PCI_CONFIG,
                                        ACPI_DEFAULT_HANDLER, NULL, NULL);
                    if (ACPI_FAILURE (Status))
                    {
                        ACPI_REPORT_ERROR (("Could not install PciConfig handler for %4.4s, %s\n",
                            Node->Name.Ascii, AcpiFormatException (Status)));
                    }
                    break;
                }
            }

            Node = AcpiNsGetParentNode (Node);
        }
    }
    else
    {
        Node = HandlerObj->AddrHandler.Node;
    }

    /*
     * The PCI segment number comes from the _SEG method
     */
    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG, Node, &Temp);
    if (ACPI_SUCCESS (Status))
    {
        PciId->Segment = ACPI_LOWORD (Temp);
    }

    /*
     * The PCI bus number comes from the _BBN method
     */
    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN, Node, &Temp);
    if (ACPI_SUCCESS (Status))
    {
        PciId->Bus = ACPI_LOWORD (Temp);
    }

    /*
     * Complete this device's PciId
     */
    AcpiOsDerivePciId (Node, RegionObj->Region.Node, &PciId);

    *RegionContext = PciId;
    return_ACPI_STATUS (AE_OK);
}