kernel/acpica/components/events/evrgnini.c
/*******************************************************************************
 *
 * FUNCTION:    AcpiEvPciConfigRegionSetup
 *
 * PARAMETERS:  Handle              - Region we are interested in
 *              Function            - Start or stop
 *              HandlerContext      - Address space handler context
 *              RegionContext       - Region specific context
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Setup a PCI_Config operation region
 *
 * MUTEX:       Assumes namespace is not locked
 *
 ******************************************************************************/
AcpiEvPciConfigRegionSetup
PARAMETERS:  Handle              - Region we are interested in
Function            - Start or stop
HandlerContext      - Address space handler context
RegionContext       - Region specific context

Status

Setup a PCI_Config operation region

Assumes namespace is not locked
AcpiEvPciConfigRegionSetup PARAMETERS : Handle - Region we are interested in Function - Start or stop HandlerContext - Address space handler context RegionContext - Region specific context Status Setup a PCI_Config operation region Assumes namespace is not locked
ACPI_STATUS
AcpiEvPciConfigRegionSetup (
    ACPI_HANDLE             Handle,
    UINT32                  Function,
    void                    *HandlerContext,
    void                    **RegionContext)
{
    ACPI_STATUS             Status = AE_OK;
    UINT64                  PciValue;
    ACPI_PCI_ID             *PciId = *RegionContext;
    ACPI_OPERAND_OBJECT     *HandlerObj;
    ACPI_NAMESPACE_NODE     *ParentNode;
    ACPI_NAMESPACE_NODE     *PciRootNode;
    ACPI_NAMESPACE_NODE     *PciDeviceNode;
    ACPI_OPERAND_OBJECT     *RegionObj = (ACPI_OPERAND_OBJECT  *) Handle;
    ACPI_FUNCTION_TRACE (EvPciConfigRegionSetup);
    HandlerObj = RegionObj->Region.Handler;
    if (!HandlerObj)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
            "Attempting to init a region %p, with no handler\n", RegionObj));
        return_ACPI_STATUS (AE_NOT_EXIST);
    }
    *RegionContext = NULL;
    if (Function == ACPI_REGION_DEACTIVATE)
    {
        if (PciId)
        {
            ACPI_FREE (PciId);
        }
        return_ACPI_STATUS (Status);
    }
    ParentNode = RegionObj->Region.Node->Parent;
    if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode)
    {
        PciRootNode = ParentNode;
        while (PciRootNode != AcpiGbl_RootNode)
        {
            if (AcpiEvIsPciRootBridge (PciRootNode))
            {
                Status = AcpiInstallAddressSpaceHandler (
                    (ACPI_HANDLE) PciRootNode,
                    ACPI_ADR_SPACE_PCI_CONFIG,
                    ACPI_DEFAULT_HANDLER, NULL, NULL);
                if (ACPI_FAILURE (Status))
                {
                    if (Status == AE_SAME_HANDLER)
                    {
                        Status = AE_OK;
                    }
                    else
                    {
                        ACPI_EXCEPTION ((AE_INFO, Status,
                            "Could not install PciConfig handler "
                            "for Root Bridge %4.4s",
                            AcpiUtGetNodeName (PciRootNode)));
                    }
                }
                break;
            }
            PciRootNode = PciRootNode->Parent;
        }
    }
    else
    {
        PciRootNode = HandlerObj->AddressSpace.Node;
    }
    if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
    {
        return_ACPI_STATUS (AE_OK);
    }
    PciId = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PCI_ID));
    if (!PciId)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }
    PciDeviceNode = RegionObj->Region.Node;
    while (PciDeviceNode && (PciDeviceNode->Type != ACPI_TYPE_DEVICE))
    {
        PciDeviceNode = PciDeviceNode->Parent;
    }
    if (!PciDeviceNode)
    {
        ACPI_FREE (PciId);
        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
    }
    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
        PciDeviceNode, &PciValue);
    if (ACPI_SUCCESS (Status))
    {
        PciId->Device   = ACPI_HIWORD (ACPI_LODWORD (PciValue));
        PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue));
    }
    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG,
        PciRootNode, &PciValue);
    if (ACPI_SUCCESS (Status))
    {
        PciId->Segment = ACPI_LOWORD (PciValue);
    }
    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN,
        PciRootNode, &PciValue);
    if (ACPI_SUCCESS (Status))
    {
        PciId->Bus = ACPI_LOWORD (PciValue);
    }
    Status = AcpiHwDerivePciId (PciId, PciRootNode, RegionObj->Region.Node);
    if (ACPI_FAILURE (Status))
    {
        ACPI_FREE (PciId);
        return_ACPI_STATUS (Status);
    }
    *RegionContext = PciId;
    return_ACPI_STATUS (AE_OK);
}
ACPI_STATUS AcpiEvPciConfigRegionSetup ( ACPI_HANDLE Handle , UINT32 Function , void * HandlerContext , void * * RegionContext ) { ACPI_STATUS Status = AE_OK ; UINT64 PciValue ; ACPI_PCI_ID * PciId = * RegionContext ; ACPI_OPERAND_OBJECT * HandlerObj ; ACPI_NAMESPACE_NODE * ParentNode ; ACPI_NAMESPACE_NODE * PciRootNode ; ACPI_NAMESPACE_NODE * PciDeviceNode ; ACPI_OPERAND_OBJECT * RegionObj = ( ACPI_OPERAND_OBJECT * ) Handle ; ACPI_FUNCTION_TRACE ( EvPciConfigRegionSetup ) ; HandlerObj = RegionObj -> Region . Handler ; if ( ! HandlerObj ) { ACPI_DEBUG_PRINT ( ( ACPI_DB_OPREGION , " \n " , RegionObj ) ) ; return_ACPI_STATUS ( AE_NOT_EXIST ) ; } * RegionContext = NULL ; if ( Function == ACPI_REGION_DEACTIVATE ) { if ( PciId ) { ACPI_FREE ( PciId ) ; } return_ACPI_STATUS ( Status ) ; } ParentNode = RegionObj -> Region . Node -> Parent ; if ( HandlerObj -> AddressSpace . Node == AcpiGbl_RootNode ) { PciRootNode = ParentNode ; while ( PciRootNode != AcpiGbl_RootNode ) { if ( AcpiEvIsPciRootBridge ( PciRootNode ) ) { Status = AcpiInstallAddressSpaceHandler ( ( ACPI_HANDLE ) PciRootNode , ACPI_ADR_SPACE_PCI_CONFIG , ACPI_DEFAULT_HANDLER , NULL , NULL ) ; if ( ACPI_FAILURE ( Status ) ) { if ( Status == AE_SAME_HANDLER ) { Status = AE_OK ; } else { ACPI_EXCEPTION ( ( AE_INFO , Status , " " " " , AcpiUtGetNodeName ( PciRootNode ) ) ) ; } } break ; } PciRootNode = PciRootNode -> Parent ; } } else { PciRootNode = HandlerObj -> AddressSpace . Node ; } if ( RegionObj -> Region . Flags & AOPOBJ_SETUP_COMPLETE ) { return_ACPI_STATUS ( AE_OK ) ; } PciId = ACPI_ALLOCATE_ZEROED ( sizeof ( ACPI_PCI_ID ) ) ; if ( ! PciId ) { return_ACPI_STATUS ( AE_NO_MEMORY ) ; } PciDeviceNode = RegionObj -> Region . Node ; while ( PciDeviceNode && ( PciDeviceNode -> Type != ACPI_TYPE_DEVICE ) ) { PciDeviceNode = PciDeviceNode -> Parent ; } if ( ! PciDeviceNode ) { ACPI_FREE ( PciId ) ; return_ACPI_STATUS ( AE_AML_OPERAND_TYPE ) ; } Status = AcpiUtEvaluateNumericObject ( METHOD_NAME__ADR , PciDeviceNode , & PciValue ) ; if ( ACPI_SUCCESS ( Status ) ) { PciId -> Device = ACPI_HIWORD ( ACPI_LODWORD ( PciValue ) ) ; PciId -> Function = ACPI_LOWORD ( ACPI_LODWORD ( PciValue ) ) ; } Status = AcpiUtEvaluateNumericObject ( METHOD_NAME__SEG , PciRootNode , & PciValue ) ; if ( ACPI_SUCCESS ( Status ) ) { PciId -> Segment = ACPI_LOWORD ( PciValue ) ; } Status = AcpiUtEvaluateNumericObject ( METHOD_NAME__BBN , PciRootNode , & PciValue ) ; if ( ACPI_SUCCESS ( Status ) ) { PciId -> Bus = ACPI_LOWORD ( PciValue ) ; } Status = AcpiHwDerivePciId ( PciId , PciRootNode , RegionObj -> Region . Node ) ; if ( ACPI_FAILURE ( Status ) ) { ACPI_FREE ( PciId ) ; return_ACPI_STATUS ( Status ) ; } * RegionContext = PciId ; return_ACPI_STATUS ( AE_OK ) ; }
FUNCTION:    AcpiEvPciConfigRegionSetup
 PARAMETERS:  Handle              - Region we are interested in
              Function            - Start or stop
              HandlerContext      - Address space handler context
              RegionContext       - Region specific context
FUNCTION : AcpiEvPciConfigRegionSetup PARAMETERS : Handle - Region we are interested in Function - Start or stop HandlerContext - Address space handler context RegionContext - Region specific context
/*
         * No installed handler. This shouldn't happen because the dispatch
         * routine checks before we get here, but we check again just in case.
         */ /*
     * 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 AddressSpace.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.
     */ /* Start search from the parent object */ /* Get the _HID/_CID in order to detect a RootBridge */ /* Install a handler for this PCI root bridge */ /*
                         * It is OK if the handler is already installed on the
                         * root bridge. Still need to return a context object
                         * for the new PCI_Config operation region, however.
                         */ /* PCI root bridge not found, use namespace root node */ /*
     * If this region is now initialized, we are done.
     * (InstallAddressSpaceHandler could have initialized it)
     */ /* Region is still not initialized. Create a new context */ /*
     * For PCI_Config space access, we need the segment, bus, device and
     * function numbers. Acquire them here.
     *
     * Find the parent device object. (This allows the operation region to be
     * within a subscope under the device, such as a control method.)
     */ /*
     * Get the PCI device and function numbers from the _ADR object
     * contained in the parent's scope.
     */ /*
     * The default is zero, and since the allocation above zeroed the data,
     * just do nothing on failure.
     */ /* The PCI segment number comes from the _SEG method */ /* The PCI bus number comes from the _BBN method */ /* Complete/update the PCI ID for this device */