Пример #1
0
void
AcpiDbSendNotify (
    char                    *Name,
    UINT32                  Value)
{
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_STATUS             Status;


    /* Translate name to an Named object */

    Node = AcpiDbConvertToNode (Name);
    if (!Node)
    {
        return;
    }

    /* Dispatch the notify if legal */

    if (AcpiEvIsNotifyObject (Node))
    {
        Status = AcpiEvQueueNotifyRequest (Node, Value);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not queue notify\n");
        }
    }
    else
    {
        AcpiOsPrintf (
            "Named object [%4.4s] Type %s, must be Device/Thermal/Processor type\n",
            AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type));
    }
}
Пример #2
0
ACPI_STATUS
AcpiExOpcode_2A_0T_0R (
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
    ACPI_NAMESPACE_NODE     *Node;
    UINT32                  Value;
    ACPI_STATUS             Status = AE_OK;


    ACPI_FUNCTION_TRACE_STR (ExOpcode_2A_0T_0R,
            AcpiPsGetOpcodeName (WalkState->Opcode));


    /* Examine the opcode */

    switch (WalkState->Opcode)
    {
    case AML_NOTIFY_OP:         /* Notify (NotifyObject, NotifyValue) */

        /* The first operand is a namespace node */

        Node = (ACPI_NAMESPACE_NODE *) Operand[0];

        /* Second value is the notify value */

        Value = (UINT32) Operand[1]->Integer.Value;

        /* Are notifies allowed on this object? */

        if (!AcpiEvIsNotifyObject (Node))
        {
            ACPI_ERROR ((AE_INFO,
                "Unexpected notify object type [%s]",
                AcpiUtGetTypeName (Node->Type)));

            Status = AE_AML_OPERAND_TYPE;
            break;
        }

        /*
         * Dispatch the notify to the appropriate handler
         * NOTE: the request is queued for execution after this method
         * completes. The notify handlers are NOT invoked synchronously
         * from this thread -- because handlers may in turn run other
         * control methods.
         */
        Status = AcpiEvQueueNotifyRequest (Node, Value);
        break;


    default:

        ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
            WalkState->Opcode));
        Status = AE_AML_BAD_OPCODE;
    }

    return_ACPI_STATUS (Status);
}
Пример #3
0
void
AcpiDbSendNotify (
    char                    *Name,
    UINT32                  Value)
{
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_STATUS             Status;


    /* Translate name to an Named object */

    Node = AcpiDbConvertToNode (Name);
    if (!Node)
    {
        return;
    }

    /* Decode Named object type */

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

         /* Send the notify */

        Status = AcpiEvQueueNotifyRequest (Node, Value);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not queue notify\n");
        }
        break;

    default:
        AcpiOsPrintf ("Named object is not a device or a thermal object\n");
        break;
    }
}
Пример #4
0
static void ACPI_SYSTEM_XFACE
AcpiEvAsynchExecuteGpeMethod (
    void                    *Context)
{
    ACPI_GPE_EVENT_INFO     *GpeEventInfo = Context;
    ACPI_STATUS             Status = AE_OK;
    ACPI_EVALUATE_INFO      *Info;
    ACPI_GPE_NOTIFY_INFO    *Notify;


    ACPI_FUNCTION_TRACE (EvAsynchExecuteGpeMethod);


    /* Do the correct dispatch - normal method or implicit notify */

    switch (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags))
    {
    case ACPI_GPE_DISPATCH_NOTIFY:
        /*
         * Implicit notify.
         * Dispatch a DEVICE_WAKE notify to the appropriate handler.
         * NOTE: the request is queued for execution after this method
         * completes. The notify handlers are NOT invoked synchronously
         * from this thread -- because handlers may in turn run other
         * control methods.
         *
         * June 2012: Expand implicit notify mechanism to support
         * notifies on multiple device objects.
         */
        Notify = GpeEventInfo->Dispatch.NotifyList;
        while (ACPI_SUCCESS (Status) && Notify)
        {
            Status = AcpiEvQueueNotifyRequest (
                Notify->DeviceNode, ACPI_NOTIFY_DEVICE_WAKE);

            Notify = Notify->Next;
        }
        break;

    case ACPI_GPE_DISPATCH_METHOD:

        /* Allocate the evaluation information block */

        Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
        if (!Info)
        {
            Status = AE_NO_MEMORY;
        }
        else
        {
            /*
             * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the
             * _Lxx/_Exx control method that corresponds to this GPE
             */
            Info->PrefixNode = GpeEventInfo->Dispatch.MethodNode;
            Info->Flags = ACPI_IGNORE_RETURN_VALUE;

            Status = AcpiNsEvaluate (Info);
            ACPI_FREE (Info);
        }

        if (ACPI_FAILURE (Status))
        {
            ACPI_EXCEPTION ((AE_INFO, Status,
                "while evaluating GPE method [%4.4s]",
                AcpiUtGetNodeName (GpeEventInfo->Dispatch.MethodNode)));
        }
        break;

    default:

        goto ErrorExit; /* Should never happen */
    }

    /* Defer enabling of GPE until all notify handlers are done */

    Status = AcpiOsExecute (OSL_NOTIFY_HANDLER,
        AcpiEvAsynchEnableGpe, GpeEventInfo);
    if (ACPI_SUCCESS (Status))
    {
        return_VOID;
    }

ErrorExit:
    AcpiEvAsynchEnableGpe (GpeEventInfo);
    return_VOID;
}
Пример #5
0
static void ACPI_SYSTEM_XFACE
AcpiEvAsynchExecuteGpeMethod (
    void                    *Context)
{
    ACPI_GPE_EVENT_INFO     *GpeEventInfo = Context;
    ACPI_STATUS             Status;
    ACPI_GPE_EVENT_INFO     *LocalGpeEventInfo;
    ACPI_EVALUATE_INFO      *Info;
    ACPI_GPE_NOTIFY_INFO    *Notify;


    ACPI_FUNCTION_TRACE (EvAsynchExecuteGpeMethod);


    /* Allocate a local GPE block */

    LocalGpeEventInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_EVENT_INFO));
    if (!LocalGpeEventInfo)
    {
        ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
            "while handling a GPE"));
        return_VOID;
    }

    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    if (ACPI_FAILURE (Status))
    {
        ACPI_FREE (LocalGpeEventInfo);
        return_VOID;
    }

    /* Must revalidate the GpeNumber/GpeBlock */

    if (!AcpiEvValidGpeEvent (GpeEventInfo))
    {
        Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
        ACPI_FREE (LocalGpeEventInfo);
        return_VOID;
    }

    /*
     * Take a snapshot of the GPE info for this level - we copy the info to
     * prevent a race condition with RemoveHandler/RemoveBlock.
     */
    ACPI_MEMCPY (LocalGpeEventInfo, GpeEventInfo,
        sizeof (ACPI_GPE_EVENT_INFO));

    Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    if (ACPI_FAILURE (Status))
    {
        ACPI_FREE (LocalGpeEventInfo);
        return_VOID;
    }

    /* Do the correct dispatch - normal method or implicit notify */

    switch (LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
    {
    case ACPI_GPE_DISPATCH_NOTIFY:
        /*
         * Implicit notify.
         * Dispatch a DEVICE_WAKE notify to the appropriate handler.
         * NOTE: the request is queued for execution after this method
         * completes. The notify handlers are NOT invoked synchronously
         * from this thread -- because handlers may in turn run other
         * control methods.
         *
         * June 2012: Expand implicit notify mechanism to support
         * notifies on multiple device objects.
         */
        Notify = LocalGpeEventInfo->Dispatch.NotifyList;
        while (ACPI_SUCCESS (Status) && Notify)
        {
            Status = AcpiEvQueueNotifyRequest (Notify->DeviceNode,
                        ACPI_NOTIFY_DEVICE_WAKE);

            Notify = Notify->Next;
        }
        break;

    case ACPI_GPE_DISPATCH_METHOD:

        /* Allocate the evaluation information block */

        Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
        if (!Info)
        {
            Status = AE_NO_MEMORY;
        }
        else
        {
            /*
             * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the
             * _Lxx/_Exx control method that corresponds to this GPE
             */
            Info->PrefixNode = LocalGpeEventInfo->Dispatch.MethodNode;
            Info->Flags = ACPI_IGNORE_RETURN_VALUE;

            Status = AcpiNsEvaluate (Info);
            ACPI_FREE (Info);
        }

        if (ACPI_FAILURE (Status))
        {
            ACPI_EXCEPTION ((AE_INFO, Status,
                "while evaluating GPE method [%4.4s]",
                AcpiUtGetNodeName (LocalGpeEventInfo->Dispatch.MethodNode)));
        }
        break;

    default:

        return_VOID; /* Should never happen */
    }

    /* Defer enabling of GPE until all notify handlers are done */

    Status = AcpiOsExecute (OSL_NOTIFY_HANDLER,
                AcpiEvAsynchEnableGpe, LocalGpeEventInfo);
    if (ACPI_FAILURE (Status))
    {
        ACPI_FREE (LocalGpeEventInfo);
    }
    return_VOID;
}
Пример #6
0
ACPI_STATUS
AcpiExOpcode_2A_0T_0R (
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
    ACPI_NAMESPACE_NODE     *Node;
    UINT32                  Value;
    ACPI_STATUS             Status = AE_OK;


    ACPI_FUNCTION_TRACE_STR (ExOpcode_2A_0T_0R,
            AcpiPsGetOpcodeName (WalkState->Opcode));


    /* Examine the opcode */

    switch (WalkState->Opcode)
    {
    case AML_NOTIFY_OP:         /* Notify (NotifyObject, NotifyValue) */

        /* The first operand is a namespace node */

        Node = (ACPI_NAMESPACE_NODE *) Operand[0];

        /* Second value is the notify value */

        Value = (UINT32) Operand[1]->Integer.Value;

        /* Are notifies allowed on this object? */

        if (!AcpiEvIsNotifyObject (Node))
        {
            ACPI_ERROR ((AE_INFO,
                "Unexpected notify object type [%s]",
                AcpiUtGetTypeName (Node->Type)));

            Status = AE_AML_OPERAND_TYPE;
            break;
        }

#ifdef ACPI_GPE_NOTIFY_CHECK
        /*
         * GPE method wake/notify check.  Here, we want to ensure that we
         * don't receive any "DeviceWake" Notifies from a GPE _Lxx or _Exx
         * GPE method during system runtime.  If we do, the GPE is marked
         * as "wake-only" and disabled.
         *
         * 1) Is the Notify() value == DeviceWake?
         * 2) Is this a GPE deferred method?  (An _Lxx or _Exx method)
         * 3) Did the original GPE happen at system runtime?
         *    (versus during wake)
         *
         * If all three cases are true, this is a wake-only GPE that should
         * be disabled at runtime.
         */
        if (Value == 2)     /* DeviceWake */
        {
            Status = AcpiEvCheckForWakeOnlyGpe (WalkState->GpeEventInfo);
            if (ACPI_FAILURE (Status))
            {
                /* AE_WAKE_ONLY_GPE only error, means ignore this notify */

                return_ACPI_STATUS (AE_OK)
            }
        }
#endif

        /*
         * Dispatch the notify to the appropriate handler
         * NOTE: the request is queued for execution after this method
         * completes.  The notify handlers are NOT invoked synchronously
         * from this thread -- because handlers may in turn run other
         * control methods.
         */
        Status = AcpiEvQueueNotifyRequest (Node, Value);
        break;


    default:

        ACPI_ERROR ((AE_INFO, "Unknown AML opcode %X",
            WalkState->Opcode));
        Status = AE_AML_BAD_OPCODE;
    }