diff options
author | Thomas Renninger <trenn@suse.de> | 2010-05-03 09:30:15 -0400 |
---|---|---|
committer | Matthew Garrett <mjg@redhat.com> | 2010-05-20 09:46:15 -0400 |
commit | fc3155b2c6419a442c6f8b34a3bf31f8efe0fe33 (patch) | |
tree | 5e95c022dbb2770fa06d78c6042fc7445c9093df /drivers | |
parent | 7ab52521f2d850e922f33e5586a47e6c83ec6f11 (diff) |
X86 platform wmi: Introduce debug param to log all WMI events
To give people easily an idea what could be WMI driven on their system.
Introduces:
wmi.debug=[01]
Tested on an acer:
ACPI: WMI: DEBUG Event INTEGER_TYPE - 65535
Situation where a driver registers for specific event and debug
handler gets overridden and set again if the registering driver gets
unloaded again is untested, but should work.
Signed-off-by: Thomas Renninger <trenn@suse.de>
CC: platform-driver-x86@vger.kernel.org
CC: mjg59@srcf.ucam.org
CC: corentin.chary@gmail.com
Signed-off-by: Carlos Corbacho <carlos@strangeworlds.co.uk>
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/platform/x86/wmi.c | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 17df134a6f03..e820f4cddb61 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c | |||
@@ -81,6 +81,11 @@ static struct wmi_block wmi_blocks; | |||
81 | #define ACPI_WMI_STRING 0x4 /* GUID takes & returns a string */ | 81 | #define ACPI_WMI_STRING 0x4 /* GUID takes & returns a string */ |
82 | #define ACPI_WMI_EVENT 0x8 /* GUID is an event */ | 82 | #define ACPI_WMI_EVENT 0x8 /* GUID is an event */ |
83 | 83 | ||
84 | static int debug_event; | ||
85 | module_param(debug_event, bool, 0444); | ||
86 | MODULE_PARM_DESC(debug_event, | ||
87 | "Log WMI Events [0/1]"); | ||
88 | |||
84 | static int acpi_wmi_remove(struct acpi_device *device, int type); | 89 | static int acpi_wmi_remove(struct acpi_device *device, int type); |
85 | static int acpi_wmi_add(struct acpi_device *device); | 90 | static int acpi_wmi_add(struct acpi_device *device); |
86 | static void acpi_wmi_notify(struct acpi_device *device, u32 event); | 91 | static void acpi_wmi_notify(struct acpi_device *device, u32 event); |
@@ -477,6 +482,37 @@ const struct acpi_buffer *in) | |||
477 | } | 482 | } |
478 | EXPORT_SYMBOL_GPL(wmi_set_block); | 483 | EXPORT_SYMBOL_GPL(wmi_set_block); |
479 | 484 | ||
485 | static void wmi_notify_debug(u32 value, void *context) | ||
486 | { | ||
487 | struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
488 | union acpi_object *obj; | ||
489 | |||
490 | wmi_get_event_data(value, &response); | ||
491 | |||
492 | obj = (union acpi_object *)response.pointer; | ||
493 | |||
494 | if (!obj) | ||
495 | return; | ||
496 | |||
497 | printk(KERN_INFO PREFIX "DEBUG Event "); | ||
498 | switch(obj->type) { | ||
499 | case ACPI_TYPE_BUFFER: | ||
500 | printk("BUFFER_TYPE - length %d\n", obj->buffer.length); | ||
501 | break; | ||
502 | case ACPI_TYPE_STRING: | ||
503 | printk("STRING_TYPE - %s\n", obj->string.pointer); | ||
504 | break; | ||
505 | case ACPI_TYPE_INTEGER: | ||
506 | printk("INTEGER_TYPE - %llu\n", obj->integer.value); | ||
507 | break; | ||
508 | case ACPI_TYPE_PACKAGE: | ||
509 | printk("PACKAGE_TYPE - %d elements\n", obj->package.count); | ||
510 | break; | ||
511 | default: | ||
512 | printk("object type 0x%X\n", obj->type); | ||
513 | } | ||
514 | } | ||
515 | |||
480 | /** | 516 | /** |
481 | * wmi_install_notify_handler - Register handler for WMI events | 517 | * wmi_install_notify_handler - Register handler for WMI events |
482 | * @handler: Function to handle notifications | 518 | * @handler: Function to handle notifications |
@@ -496,7 +532,7 @@ wmi_notify_handler handler, void *data) | |||
496 | if (!find_guid(guid, &block)) | 532 | if (!find_guid(guid, &block)) |
497 | return AE_NOT_EXIST; | 533 | return AE_NOT_EXIST; |
498 | 534 | ||
499 | if (block->handler) | 535 | if (block->handler && block->handler != wmi_notify_debug) |
500 | return AE_ALREADY_ACQUIRED; | 536 | return AE_ALREADY_ACQUIRED; |
501 | 537 | ||
502 | block->handler = handler; | 538 | block->handler = handler; |
@@ -516,7 +552,7 @@ EXPORT_SYMBOL_GPL(wmi_install_notify_handler); | |||
516 | acpi_status wmi_remove_notify_handler(const char *guid) | 552 | acpi_status wmi_remove_notify_handler(const char *guid) |
517 | { | 553 | { |
518 | struct wmi_block *block; | 554 | struct wmi_block *block; |
519 | acpi_status status; | 555 | acpi_status status = AE_OK; |
520 | 556 | ||
521 | if (!guid) | 557 | if (!guid) |
522 | return AE_BAD_PARAMETER; | 558 | return AE_BAD_PARAMETER; |
@@ -524,14 +560,16 @@ acpi_status wmi_remove_notify_handler(const char *guid) | |||
524 | if (!find_guid(guid, &block)) | 560 | if (!find_guid(guid, &block)) |
525 | return AE_NOT_EXIST; | 561 | return AE_NOT_EXIST; |
526 | 562 | ||
527 | if (!block->handler) | 563 | if (!block->handler || block->handler == wmi_notify_debug) |
528 | return AE_NULL_ENTRY; | 564 | return AE_NULL_ENTRY; |
529 | 565 | ||
530 | status = wmi_method_enable(block, 0); | 566 | if (debug_event) { |
531 | 567 | block->handler = wmi_notify_debug; | |
532 | block->handler = NULL; | 568 | } else { |
533 | block->handler_data = NULL; | 569 | status = wmi_method_enable(block, 0); |
534 | 570 | block->handler = NULL; | |
571 | block->handler_data = NULL; | ||
572 | } | ||
535 | return status; | 573 | return status; |
536 | } | 574 | } |
537 | EXPORT_SYMBOL_GPL(wmi_remove_notify_handler); | 575 | EXPORT_SYMBOL_GPL(wmi_remove_notify_handler); |
@@ -780,6 +818,10 @@ static __init acpi_status parse_wdg(acpi_handle handle) | |||
780 | 818 | ||
781 | wblock->gblock = gblock[i]; | 819 | wblock->gblock = gblock[i]; |
782 | wblock->handle = handle; | 820 | wblock->handle = handle; |
821 | if (debug_event) { | ||
822 | wblock->handler = wmi_notify_debug; | ||
823 | status = wmi_method_enable(wblock, 1); | ||
824 | } | ||
783 | list_add_tail(&wblock->list, &wmi_blocks.list); | 825 | list_add_tail(&wblock->list, &wmi_blocks.list); |
784 | } | 826 | } |
785 | 827 | ||