diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-01-25 09:52:48 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-01-25 09:52:48 -0500 |
commit | f1487fcbe47cd2bc0c71e8598bf9eb6a82dec544 (patch) | |
tree | 4c7abed6047538c13dd024a8ecffd15f31b4609a /drivers/platform/x86/wmi.c | |
parent | 84549d239ab9bb2e3a85c6efcf0e6478a38b4260 (diff) | |
parent | 40aa7030e5213a43e9e0554fd7f95534ea310bf3 (diff) |
Merge branch 'for-2.6.33' into for-2.6.34
Diffstat (limited to 'drivers/platform/x86/wmi.c')
-rw-r--r-- | drivers/platform/x86/wmi.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 9f93d6c0f510..b104302fea0a 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c | |||
@@ -492,8 +492,7 @@ wmi_notify_handler handler, void *data) | |||
492 | if (!guid || !handler) | 492 | if (!guid || !handler) |
493 | return AE_BAD_PARAMETER; | 493 | return AE_BAD_PARAMETER; |
494 | 494 | ||
495 | find_guid(guid, &block); | 495 | if (!find_guid(guid, &block)) |
496 | if (!block) | ||
497 | return AE_NOT_EXIST; | 496 | return AE_NOT_EXIST; |
498 | 497 | ||
499 | if (block->handler) | 498 | if (block->handler) |
@@ -521,8 +520,7 @@ acpi_status wmi_remove_notify_handler(const char *guid) | |||
521 | if (!guid) | 520 | if (!guid) |
522 | return AE_BAD_PARAMETER; | 521 | return AE_BAD_PARAMETER; |
523 | 522 | ||
524 | find_guid(guid, &block); | 523 | if (!find_guid(guid, &block)) |
525 | if (!block) | ||
526 | return AE_NOT_EXIST; | 524 | return AE_NOT_EXIST; |
527 | 525 | ||
528 | if (!block->handler) | 526 | if (!block->handler) |
@@ -716,6 +714,22 @@ static int wmi_class_init(void) | |||
716 | return ret; | 714 | return ret; |
717 | } | 715 | } |
718 | 716 | ||
717 | static bool guid_already_parsed(const char *guid_string) | ||
718 | { | ||
719 | struct guid_block *gblock; | ||
720 | struct wmi_block *wblock; | ||
721 | struct list_head *p; | ||
722 | |||
723 | list_for_each(p, &wmi_blocks.list) { | ||
724 | wblock = list_entry(p, struct wmi_block, list); | ||
725 | gblock = &wblock->gblock; | ||
726 | |||
727 | if (strncmp(gblock->guid, guid_string, 16) == 0) | ||
728 | return true; | ||
729 | } | ||
730 | return false; | ||
731 | } | ||
732 | |||
719 | /* | 733 | /* |
720 | * Parse the _WDG method for the GUID data blocks | 734 | * Parse the _WDG method for the GUID data blocks |
721 | */ | 735 | */ |
@@ -725,6 +739,7 @@ static __init acpi_status parse_wdg(acpi_handle handle) | |||
725 | union acpi_object *obj; | 739 | union acpi_object *obj; |
726 | struct guid_block *gblock; | 740 | struct guid_block *gblock; |
727 | struct wmi_block *wblock; | 741 | struct wmi_block *wblock; |
742 | char guid_string[37]; | ||
728 | acpi_status status; | 743 | acpi_status status; |
729 | u32 i, total; | 744 | u32 i, total; |
730 | 745 | ||
@@ -747,6 +762,19 @@ static __init acpi_status parse_wdg(acpi_handle handle) | |||
747 | memcpy(gblock, obj->buffer.pointer, obj->buffer.length); | 762 | memcpy(gblock, obj->buffer.pointer, obj->buffer.length); |
748 | 763 | ||
749 | for (i = 0; i < total; i++) { | 764 | for (i = 0; i < total; i++) { |
765 | /* | ||
766 | Some WMI devices, like those for nVidia hooks, have a | ||
767 | duplicate GUID. It's not clear what we should do in this | ||
768 | case yet, so for now, we'll just ignore the duplicate. | ||
769 | Anyone who wants to add support for that device can come | ||
770 | up with a better workaround for the mess then. | ||
771 | */ | ||
772 | if (guid_already_parsed(gblock[i].guid) == true) { | ||
773 | wmi_gtoa(gblock[i].guid, guid_string); | ||
774 | printk(KERN_INFO PREFIX "Skipping duplicate GUID %s\n", | ||
775 | guid_string); | ||
776 | continue; | ||
777 | } | ||
750 | wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL); | 778 | wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL); |
751 | if (!wblock) | 779 | if (!wblock) |
752 | return AE_NO_MEMORY; | 780 | return AE_NO_MEMORY; |