示例#1
0
static ACPI_STATUS
AcpiEvRegRun (
    ACPI_HANDLE             ObjHandle,
    UINT32                  Level,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_STATUS             Status;
    ACPI_REG_WALK_INFO      *Info;


    Info = ACPI_CAST_PTR (ACPI_REG_WALK_INFO, Context);

    /* Convert and validate the device handle */

    Node = AcpiNsValidateHandle (ObjHandle);
    if (!Node)
    {
        return (AE_BAD_PARAMETER);
    }

    /*
     * We only care about regions.and objects that are allowed to have address
     * space handlers
     */
    if ((Node->Type != ACPI_TYPE_REGION) &&
        (Node != AcpiGbl_RootNode))
    {
        return (AE_OK);
    }

    /* Check for an existing internal object */

    ObjDesc = AcpiNsGetAttachedObject (Node);
    if (!ObjDesc)
    {
        /* No object, just exit */

        return (AE_OK);
    }

    /* Object is a Region */

    if (ObjDesc->Region.SpaceId != Info->SpaceId)
    {
        /* This region is for a different address space, just ignore it */

        return (AE_OK);
    }

    Info->RegRunCount++;
    Status = AcpiEvExecuteRegMethod (ObjDesc, ACPI_REG_CONNECT);
    return (Status);
}
示例#2
0
ACPI_STATUS
AcpiEvAttachRegion (
    ACPI_OPERAND_OBJECT     *HandlerObj,
    ACPI_OPERAND_OBJECT     *RegionObj,
    BOOLEAN                 AcpiNsIsLocked)
{
    ACPI_STATUS             Status;
    ACPI_STATUS             Status2;


    ACPI_FUNCTION_TRACE ("EvAttachRegion");


    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
        "Adding Region %p to address handler %p [%s]\n",
        RegionObj, HandlerObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId)));


    /*
     * Link this region to the front of the handler's list
     */
    RegionObj->Region.Next = HandlerObj->AddrHandler.RegionList;
    HandlerObj->AddrHandler.RegionList = RegionObj;

    /*
     * Set the region's handler
     */
    RegionObj->Region.AddrHandler = HandlerObj;

    /*
     * Tell all users that this region is usable by running the _REG
     * method
     */
    if (AcpiNsIsLocked)
    {
        Status2 = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
        if (ACPI_FAILURE (Status2))
        {
            return_ACPI_STATUS (Status2);
        }
    }

    Status = AcpiEvExecuteRegMethod (RegionObj, 1);

    if (AcpiNsIsLocked)
    {
        Status2 = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
        if (ACPI_FAILURE (Status2))
        {
            return_ACPI_STATUS (Status2);
        }
    }

    return_ACPI_STATUS (Status);
}
示例#3
0
void
AcpiEvDetachRegion(
    ACPI_OPERAND_OBJECT     *RegionObj,
    BOOLEAN                 AcpiNsIsLocked)
{
    ACPI_OPERAND_OBJECT     *HandlerObj;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_OPERAND_OBJECT     *StartDesc;
    ACPI_OPERAND_OBJECT     **LastObjPtr;
    ACPI_ADR_SPACE_SETUP    RegionSetup;
    void                    **RegionContext;
    ACPI_OPERAND_OBJECT     *RegionObj2;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (EvDetachRegion);


    RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
    if (!RegionObj2)
    {
        return_VOID;
    }
    RegionContext = &RegionObj2->Extra.RegionContext;

    /* Get the address handler from the region object */

    HandlerObj = RegionObj->Region.Handler;
    if (!HandlerObj)
    {
        /* This region has no handler, all done */

        return_VOID;
    }

    /* Find this region in the handler's list */

    ObjDesc = HandlerObj->AddressSpace.RegionList;
    StartDesc = ObjDesc;
    LastObjPtr = &HandlerObj->AddressSpace.RegionList;

    while (ObjDesc)
    {
        /* Is this the correct Region? */

        if (ObjDesc == RegionObj)
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
                "Removing Region %p from address handler %p\n",
                RegionObj, HandlerObj));

            /* This is it, remove it from the handler's list */

            *LastObjPtr = ObjDesc->Region.Next;
            ObjDesc->Region.Next = NULL;        /* Must clear field */

            if (AcpiNsIsLocked)
            {
                Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
                if (ACPI_FAILURE (Status))
                {
                    return_VOID;
                }
            }

            /* Now stop region accesses by executing the _REG method */

            Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_DISCONNECT);
            if (ACPI_FAILURE (Status))
            {
                ACPI_EXCEPTION ((AE_INFO, Status, "from region _REG, [%s]",
                    AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
            }

            if (AcpiNsIsLocked)
            {
                Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
                if (ACPI_FAILURE (Status))
                {
                    return_VOID;
                }
            }

            /*
             * If the region has been activated, call the setup handler with
             * the deactivate notification
             */
            if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
            {
                RegionSetup = HandlerObj->AddressSpace.Setup;
                Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE,
                    HandlerObj->AddressSpace.Context, RegionContext);

                /*
                 * RegionContext should have been released by the deactivate
                 * operation. We don't need access to it anymore here.
                 */
                if (RegionContext)
                {
                    *RegionContext = NULL;
                }

                /* Init routine may fail, Just ignore errors */

                if (ACPI_FAILURE (Status))
                {
                    ACPI_EXCEPTION ((AE_INFO, Status,
                        "from region handler - deactivate, [%s]",
                        AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
                }

                RegionObj->Region.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
            }

            /*
             * Remove handler reference in the region
             *
             * NOTE: this doesn't mean that the region goes away, the region
             * is just inaccessible as indicated to the _REG method
             *
             * If the region is on the handler's list, this must be the
             * region's handler
             */
            RegionObj->Region.Handler = NULL;
            AcpiUtRemoveReference (HandlerObj);

            return_VOID;
        }

        /* Walk the linked list of handlers */

        LastObjPtr = &ObjDesc->Region.Next;
        ObjDesc = ObjDesc->Region.Next;

        /* Prevent infinite loop if list is corrupted */

        if (ObjDesc == StartDesc)
        {
            ACPI_ERROR ((AE_INFO,
                "Circular handler list in region object %p",
                RegionObj));
            return_VOID;
        }
    }

    /* If we get here, the region was not in the handler's region list */

    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
        "Cannot remove region %p from address handler %p\n",
        RegionObj, HandlerObj));

    return_VOID;
}
示例#4
0
文件: evrgnini.c 项目: 2asoft/freebsd
ACPI_STATUS
AcpiEvInitializeRegion (
    ACPI_OPERAND_OBJECT     *RegionObj,
    BOOLEAN                 AcpiNsLocked)
{
    ACPI_OPERAND_OBJECT     *HandlerObj;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_ADR_SPACE_TYPE     SpaceId;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE_U32 (EvInitializeRegion, AcpiNsLocked);


    if (!RegionObj)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED)
    {
        return_ACPI_STATUS (AE_OK);
    }

    RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;

    Node = RegionObj->Region.Node->Parent;
    SpaceId = RegionObj->Region.SpaceId;

    /*
     * The following loop depends upon the root Node having no parent
     * ie: AcpiGbl_RootNode->Parent being set to NULL
     */
    while (Node)
    {
        /* Check to see if a handler exists */

        HandlerObj = NULL;
        ObjDesc = AcpiNsGetAttachedObject (Node);
        if (ObjDesc)
        {
            /* Can only be a handler if the object exists */

            switch (Node->Type)
            {
            case ACPI_TYPE_DEVICE:
            case ACPI_TYPE_PROCESSOR:
            case ACPI_TYPE_THERMAL:

                HandlerObj = ObjDesc->CommonNotify.Handler;
                break;

            case ACPI_TYPE_METHOD:
                /*
                 * If we are executing module level code, the original
                 * Node's object was replaced by this Method object and we
                 * saved the handler in the method object.
                 *
                 * See AcpiNsExecModuleCode
                 */
                if (ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL)
                {
                    HandlerObj = ObjDesc->Method.Dispatch.Handler;
                }
                break;

            default:

                /* Ignore other objects */

                break;
            }

            HandlerObj = AcpiEvFindRegionHandler (SpaceId, HandlerObj);
            if (HandlerObj)
            {
                /* Found correct handler */

                ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
                    "Found handler %p for region %p in obj %p\n",
                    HandlerObj, RegionObj, ObjDesc));

                Status = AcpiEvAttachRegion (HandlerObj, RegionObj,
                    AcpiNsLocked);

                /*
                 * Tell all users that this region is usable by
                 * running the _REG method
                 */
                if (AcpiNsLocked)
                {
                    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
                    if (ACPI_FAILURE (Status))
                    {
                        return_ACPI_STATUS (Status);
                    }
                }

                Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT);

                if (AcpiNsLocked)
                {
                    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
                    if (ACPI_FAILURE (Status))
                    {
                        return_ACPI_STATUS (Status);
                    }
                }

                return_ACPI_STATUS (AE_OK);
            }
        }

        /* This node does not have the handler we need; Pop up one level */

        Node = Node->Parent;
    }

    /* If we get here, there is no handler for this region */

    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
        "No handler for RegionType %s(%X) (RegionObj %p)\n",
        AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));

    return_ACPI_STATUS (AE_NOT_EXIST);
}
ACPI_STATUS
AcpiEvInitializeRegion (
    ACPI_OPERAND_OBJECT     *RegionObj,
    BOOLEAN                 AcpiNsLocked)
{
    ACPI_OPERAND_OBJECT     *HandlerObj;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_ADR_SPACE_TYPE     SpaceId;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_STATUS             Status;
    ACPI_NAMESPACE_NODE     *MethodNode;
    ACPI_NAME               *RegNamePtr = (ACPI_NAME *) METHOD_NAME__REG;
    ACPI_OPERAND_OBJECT     *RegionObj2;


    ACPI_FUNCTION_TRACE_U32 (EvInitializeRegion, AcpiNsLocked);


    if (!RegionObj)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED)
    {
        return_ACPI_STATUS (AE_OK);
    }

    RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
    if (!RegionObj2)
    {
        return_ACPI_STATUS (AE_NOT_EXIST);
    }

    Node = AcpiNsGetParentNode (RegionObj->Region.Node);
    SpaceId = RegionObj->Region.SpaceId;

    /* Setup defaults */

    RegionObj->Region.Handler = NULL;
    RegionObj2->Extra.Method_REG = NULL;
    RegionObj->Common.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
    RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;

    /* Find any "_REG" method associated with this region definition */

    Status = AcpiNsSearchOneScope (
                *RegNamePtr, Node, ACPI_TYPE_METHOD, &MethodNode);
    if (ACPI_SUCCESS (Status))
    {
        /*
         * The _REG method is optional and there can be only one per region
         * definition. This will be executed when the handler is attached
         * or removed
         */
        RegionObj2->Extra.Method_REG = MethodNode;
    }

    /*
     * The following loop depends upon the root Node having no parent
     * ie: AcpiGbl_RootNode->ParentEntry being set to NULL
     */
    while (Node)
    {
        /* Check to see if a handler exists */

        HandlerObj = NULL;
        ObjDesc = AcpiNsGetAttachedObject (Node);
        if (ObjDesc)
        {
            /* Can only be a handler if the object exists */

            switch (Node->Type)
            {
            case ACPI_TYPE_DEVICE:

                HandlerObj = ObjDesc->Device.Handler;
                break;

            case ACPI_TYPE_PROCESSOR:

                HandlerObj = ObjDesc->Processor.Handler;
                break;

            case ACPI_TYPE_THERMAL:

                HandlerObj = ObjDesc->ThermalZone.Handler;
                break;

            default:
                /* Ignore other objects */
                break;
            }

            while (HandlerObj)
            {
                /* Is this handler of the correct type? */

                if (HandlerObj->AddressSpace.SpaceId == SpaceId)
                {
                    /* Found correct handler */

                    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
                        "Found handler %p for region %p in obj %p\n",
                        HandlerObj, RegionObj, ObjDesc));

                    Status = AcpiEvAttachRegion (HandlerObj, RegionObj,
                                AcpiNsLocked);

                    /*
                     * Tell all users that this region is usable by
                     * running the _REG method
                     */
                    if (AcpiNsLocked)
                    {
                        Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
                        if (ACPI_FAILURE (Status))
                        {
                            return_ACPI_STATUS (Status);
                        }
                    }

                    Status = AcpiEvExecuteRegMethod (RegionObj, 1);

                    if (AcpiNsLocked)
                    {
                        Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
                        if (ACPI_FAILURE (Status))
                        {
                            return_ACPI_STATUS (Status);
                        }
                    }

                    return_ACPI_STATUS (AE_OK);
                }

                /* Try next handler in the list */

                HandlerObj = HandlerObj->AddressSpace.Next;
            }
        }

        /* This node does not have the handler we need; Pop up one level */

        Node = AcpiNsGetParentNode (Node);
    }

    /* If we get here, there is no handler for this region */

    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
        "No handler for RegionType %s(%X) (RegionObj %p)\n",
        AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));

    return_ACPI_STATUS (AE_NOT_EXIST);
}
示例#6
0
void
AcpiEvDetachRegion(
    ACPI_OPERAND_OBJECT     *RegionObj,
    BOOLEAN                 AcpiNsIsLocked)
{
    ACPI_OPERAND_OBJECT     *HandlerObj;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_OPERAND_OBJECT     **LastObjPtr;
    ACPI_ADR_SPACE_SETUP    RegionSetup;
    void                    *RegionContext;
    ACPI_OPERAND_OBJECT     *RegionObj2;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE ("EvDetachRegion");


    RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
    if (!RegionObj2)
    {
        return_VOID;
    }
    RegionContext = RegionObj2->Extra.RegionContext;

    /*
     *  Get the address handler from the region object
     */
    HandlerObj = RegionObj->Region.AddrHandler;
    if (!HandlerObj)
    {
        /*
         *  This region has no handler, all done
         */
        return_VOID;
    }


    /*
     *  Find this region in the handler's list
     */
    ObjDesc = HandlerObj->AddrHandler.RegionList;
    LastObjPtr = &HandlerObj->AddrHandler.RegionList;

    while (ObjDesc)
    {
        /*
         *  See if this is the one
         */
        if (ObjDesc == RegionObj)
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
                "Removing Region %p from address handler %p\n",
                RegionObj, HandlerObj));
            /*
             *  This is it, remove it from the handler's list
             */
            *LastObjPtr = ObjDesc->Region.Next;
            ObjDesc->Region.Next = NULL;            /* Must clear field */

            if (AcpiNsIsLocked)
            {
                Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
                if (ACPI_FAILURE (Status))
                {
                    return_VOID;
                }
            }

            /*
             *  Now stop region accesses by executing the _REG method
             */
            Status = AcpiEvExecuteRegMethod (RegionObj, 0);
            if (ACPI_FAILURE (Status))
            {
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region _REG, [%s]\n",
                    AcpiFormatException (Status),
                    AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
            }

            if (AcpiNsIsLocked)
            {
                Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
                if (ACPI_FAILURE (Status))
                {
                    return_VOID;
                }
            }

            /*
             *  Call the setup handler with the deactivate notification
             */
            RegionSetup = HandlerObj->AddrHandler.Setup;
            Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE,
                            HandlerObj->AddrHandler.Context, &RegionContext);

            /*
             *  Init routine may fail, Just ignore errors
             */
            if (ACPI_FAILURE (Status))
            {
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region init, [%s]\n",
                    AcpiFormatException (Status),
                    AcpiUtGetRegionName (RegionObj->Region.SpaceId)));
            }

            RegionObj->Region.Flags &= ~(AOPOBJ_SETUP_COMPLETE);

            /*
             *  Remove handler reference in the region
             *
             *  NOTE: this doesn't mean that the region goes away
             *  The region is just inaccessible as indicated to
             *  the _REG method
             *
             *  If the region is on the handler's list
             *  this better be the region's handler
             */
            RegionObj->Region.AddrHandler = NULL;

            return_VOID;

        } /* found the right handler */

        /*
         *  Move through the linked list of handlers
         */
        LastObjPtr = &ObjDesc->Region.Next;
        ObjDesc = ObjDesc->Region.Next;
    }

    /*
     *  If we get here, the region was not in the handler's region list
     */
    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
        "Cannot remove region %p from address handler %p\n",
        RegionObj, HandlerObj));

    return_VOID;
}
示例#7
0
文件: evrgnini.c 项目: looncraz/haiku
ACPI_STATUS
AcpiEvInitializeRegion (
    ACPI_OPERAND_OBJECT     *RegionObj)
{
    ACPI_OPERAND_OBJECT     *HandlerObj;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_ADR_SPACE_TYPE     SpaceId;
    ACPI_NAMESPACE_NODE     *Node;


    ACPI_FUNCTION_TRACE (EvInitializeRegion);


    if (!RegionObj)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED)
    {
        return_ACPI_STATUS (AE_OK);
    }

    RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;

    Node = RegionObj->Region.Node->Parent;
    SpaceId = RegionObj->Region.SpaceId;

    /*
     * The following loop depends upon the root Node having no parent
     * ie: AcpiGbl_RootNode->Parent being set to NULL
     */
    while (Node)
    {
        /* Check to see if a handler exists */

        HandlerObj = NULL;
        ObjDesc = AcpiNsGetAttachedObject (Node);
        if (ObjDesc)
        {
            /* Can only be a handler if the object exists */

            switch (Node->Type)
            {
            case ACPI_TYPE_DEVICE:
            case ACPI_TYPE_PROCESSOR:
            case ACPI_TYPE_THERMAL:

                HandlerObj = ObjDesc->CommonNotify.Handler;
                break;

            case ACPI_TYPE_METHOD:
                /*
                 * If we are executing module level code, the original
                 * Node's object was replaced by this Method object and we
                 * saved the handler in the method object.
                 *
                 * Note: Only used for the legacy MLC support. Will
                 * be removed in the future.
                 *
                 * See AcpiNsExecModuleCode
                 */
                if (!AcpiGbl_ExecuteTablesAsMethods &&
                    ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL)
                {
                    HandlerObj = ObjDesc->Method.Dispatch.Handler;
                }
                break;

            default:

                /* Ignore other objects */

                break;
            }

            HandlerObj = AcpiEvFindRegionHandler (SpaceId, HandlerObj);
            if (HandlerObj)
            {
                /* Found correct handler */

                ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
                    "Found handler %p for region %p in obj %p\n",
                    HandlerObj, RegionObj, ObjDesc));

                (void) AcpiEvAttachRegion (HandlerObj, RegionObj, FALSE);

                /*
                 * Tell all users that this region is usable by
                 * running the _REG method
                 */
                AcpiExExitInterpreter ();
                (void) AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT);
                AcpiExEnterInterpreter ();
                return_ACPI_STATUS (AE_OK);
            }
        }

        /* This node does not have the handler we need; Pop up one level */

        Node = Node->Parent;
    }

    /*
     * If we get here, there is no handler for this region. This is not
     * fatal because many regions get created before a handler is installed
     * for said region.
     */
    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
        "No handler for RegionType %s(%X) (RegionObj %p)\n",
        AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));

    return_ACPI_STATUS (AE_OK);
}