Commit 7c43312a authored by Lv Zheng's avatar Lv Zheng Committed by Rafael J. Wysocki

ACPICA: Events: Cleanup GPE dispatcher type obtaining code

ACPICA commit 7926d5ca9452c87f866938dcea8f12e1efb58f89

There is an issue in acpi_install_gpe_handler() and acpi_remove_gpe_handler().
The code to obtain the GPE dispatcher type from the Handler->original_flags
is wrong:
    if (((Handler->original_flags & ACPI_GPE_DISPATCH_METHOD) ||
         (Handler->original_flags & ACPI_GPE_DISPATCH_NOTIFY)) &&
ACPI_GPE_DISPATCH_NOTIFY is 0x03 and ACPI_GPE_DISPATCH_METHOD is 0x02, thus
this statement is TRUE for the following dispatcher types:
    0x01 (ACPI_GPE_DISPATCH_HANDLER): not expected
    0x02 (ACPI_GPE_DISPATCH_METHOD): expected
    0x03 (ACPI_GPE_DISPATCH_NOTIFY): expected

There is no functional issue due to this because Handler->original_flags is
only set in acpi_install_gpe_handler(), and an earlier checker has excluded
the ACPI_GPE_DISPATCH_HANDLER:
    if ((gpe_event_info->Flags & ACPI_GPE_DISPATCH_MASK) ==
            ACPI_GPE_DISPATCH_HANDLER)
    {
        Status = AE_ALREADY_EXISTS;
        goto free_and_exit;
    }
    ...
    Handler->original_flags = (u8) (gpe_event_info->Flags &
        (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK));

We need to clean this up before modifying the GPE dispatcher type values.

In order to prevent such issue from happening in the future, this patch
introduces ACPI_GPE_DISPATCH_TYPE() macro to be used to obtain the GPE
dispatcher types. Lv Zheng.

Link: https://github.com/acpica/acpica/commit/7926d5caSigned-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Signed-off-by: default avatarDavid E. Box <david.e.box@linux.intel.com>
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 779ba5a3
...@@ -503,7 +503,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) ...@@ -503,7 +503,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
/* Do the correct dispatch - normal method or implicit notify */ /* Do the correct dispatch - normal method or implicit notify */
switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { switch (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)) {
case ACPI_GPE_DISPATCH_NOTIFY: case ACPI_GPE_DISPATCH_NOTIFY:
/* /*
* Implicit notify. * Implicit notify.
...@@ -707,7 +707,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, ...@@ -707,7 +707,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
* If there is neither a handler nor a method, leave the GPE * If there is neither a handler nor a method, leave the GPE
* disabled. * disabled.
*/ */
switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { switch (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)) {
case ACPI_GPE_DISPATCH_HANDLER: case ACPI_GPE_DISPATCH_HANDLER:
/* Invoke the installed handler (at interrupt level) */ /* Invoke the installed handler (at interrupt level) */
......
...@@ -474,10 +474,10 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, ...@@ -474,10 +474,10 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
* Ignore GPEs that have no corresponding _Lxx/_Exx method * Ignore GPEs that have no corresponding _Lxx/_Exx method
* and GPEs that are used to wake the system * and GPEs that are used to wake the system
*/ */
if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_NONE) ACPI_GPE_DISPATCH_NONE)
|| ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) || (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
== ACPI_GPE_DISPATCH_HANDLER) ACPI_GPE_DISPATCH_HANDLER)
|| (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
continue; continue;
} }
......
...@@ -401,7 +401,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, ...@@ -401,7 +401,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
} }
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_HANDLER) { ACPI_GPE_DISPATCH_HANDLER) {
/* If there is already a handler, ignore this GPE method */ /* If there is already a handler, ignore this GPE method */
...@@ -409,7 +409,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, ...@@ -409,7 +409,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
} }
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_METHOD) { ACPI_GPE_DISPATCH_METHOD) {
/* /*
* If there is already a method, ignore this method. But check * If there is already a method, ignore this method. But check
......
...@@ -324,7 +324,7 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, ...@@ -324,7 +324,7 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
ACPI_GPE_REGISTER_WIDTH) ACPI_GPE_REGISTER_WIDTH)
+ j]; + j];
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_HANDLER) { ACPI_GPE_DISPATCH_HANDLER) {
/* Delete an installed handler block */ /* Delete an installed handler block */
...@@ -333,10 +333,8 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, ...@@ -333,10 +333,8 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
gpe_event_info->dispatch.handler = NULL; gpe_event_info->dispatch.handler = NULL;
gpe_event_info->flags &= gpe_event_info->flags &=
~ACPI_GPE_DISPATCH_MASK; ~ACPI_GPE_DISPATCH_MASK;
} else } else if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)
if ((gpe_event_info-> == ACPI_GPE_DISPATCH_NOTIFY) {
flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_NOTIFY) {
/* Delete the implicit notification device list */ /* Delete the implicit notification device list */
......
...@@ -775,7 +775,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device, ...@@ -775,7 +775,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
/* Make sure that there isn't a handler there already */ /* Make sure that there isn't a handler there already */
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_HANDLER) { ACPI_GPE_DISPATCH_HANDLER) {
status = AE_ALREADY_EXISTS; status = AE_ALREADY_EXISTS;
goto free_and_exit; goto free_and_exit;
...@@ -793,9 +793,10 @@ acpi_install_gpe_handler(acpi_handle gpe_device, ...@@ -793,9 +793,10 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
* automatically during initialization, in which case it has to be * automatically during initialization, in which case it has to be
* disabled now to avoid spurious execution of the handler. * disabled now to avoid spurious execution of the handler.
*/ */
if (((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) || if (((ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
(handler->original_flags & ACPI_GPE_DISPATCH_NOTIFY)) && ACPI_GPE_DISPATCH_METHOD) ||
gpe_event_info->runtime_count) { (ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
ACPI_GPE_DISPATCH_NOTIFY)) && gpe_event_info->runtime_count) {
handler->originally_enabled = TRUE; handler->originally_enabled = TRUE;
(void)acpi_ev_remove_gpe_reference(gpe_event_info); (void)acpi_ev_remove_gpe_reference(gpe_event_info);
...@@ -880,7 +881,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, ...@@ -880,7 +881,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
/* Make sure that a handler is indeed installed */ /* Make sure that a handler is indeed installed */
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
ACPI_GPE_DISPATCH_HANDLER) { ACPI_GPE_DISPATCH_HANDLER) {
status = AE_NOT_EXIST; status = AE_NOT_EXIST;
goto unlock_and_exit; goto unlock_and_exit;
...@@ -910,9 +911,10 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, ...@@ -910,9 +911,10 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
* enabled, it should be enabled at this point to restore the * enabled, it should be enabled at this point to restore the
* post-initialization configuration. * post-initialization configuration.
*/ */
if (((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) || if (((ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
(handler->original_flags & ACPI_GPE_DISPATCH_NOTIFY)) && ACPI_GPE_DISPATCH_METHOD) ||
handler->originally_enabled) { (ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
ACPI_GPE_DISPATCH_NOTIFY)) && handler->originally_enabled) {
(void)acpi_ev_add_gpe_reference(gpe_event_info); (void)acpi_ev_add_gpe_reference(gpe_event_info);
} }
......
...@@ -132,7 +132,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) ...@@ -132,7 +132,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
*/ */
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (gpe_event_info) { if (gpe_event_info) {
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
ACPI_GPE_DISPATCH_NONE) { ACPI_GPE_DISPATCH_NONE) {
status = acpi_ev_add_gpe_reference(gpe_event_info); status = acpi_ev_add_gpe_reference(gpe_event_info);
} else { } else {
...@@ -313,7 +313,7 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, ...@@ -313,7 +313,7 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,
* known as an "implicit notify". Note: The GPE is assumed to be * known as an "implicit notify". Note: The GPE is assumed to be
* level-triggered (for windows compatibility). * level-triggered (for windows compatibility).
*/ */
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_NONE) { ACPI_GPE_DISPATCH_NONE) {
/* /*
* This is the first device for implicit notify on this GPE. * This is the first device for implicit notify on this GPE.
...@@ -327,7 +327,7 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, ...@@ -327,7 +327,7 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,
* If we already have an implicit notify on this GPE, add * If we already have an implicit notify on this GPE, add
* this device to the notify list. * this device to the notify list.
*/ */
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_NOTIFY) { ACPI_GPE_DISPATCH_NOTIFY) {
/* Ensure that the device is not already in the list */ /* Ensure that the device is not already in the list */
......
...@@ -225,7 +225,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, ...@@ -225,7 +225,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
/* GPE currently handled? */ /* GPE currently handled? */
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
ACPI_GPE_DISPATCH_NONE) { ACPI_GPE_DISPATCH_NONE) {
local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER; local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER;
} }
......
...@@ -757,6 +757,7 @@ typedef u32 acpi_event_status; ...@@ -757,6 +757,7 @@ typedef u32 acpi_event_status;
#define ACPI_GPE_DISPATCH_HANDLER (u8) 0x02 #define ACPI_GPE_DISPATCH_HANDLER (u8) 0x02
#define ACPI_GPE_DISPATCH_NOTIFY (u8) 0x03 #define ACPI_GPE_DISPATCH_NOTIFY (u8) 0x03
#define ACPI_GPE_DISPATCH_MASK (u8) 0x03 #define ACPI_GPE_DISPATCH_MASK (u8) 0x03
#define ACPI_GPE_DISPATCH_TYPE(flags) ((u8) ((flags) & ACPI_GPE_DISPATCH_MASK))
#define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x04 #define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x04
#define ACPI_GPE_EDGE_TRIGGERED (u8) 0x00 #define ACPI_GPE_EDGE_TRIGGERED (u8) 0x00
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment