diff options
author | Carlos Corbacho <carlos@strangeworlds.co.uk> | 2009-12-26 14:14:59 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-12-30 02:49:04 -0500 |
commit | d1f9e4970742bb1e22d07b01bd44f9c357d25c42 (patch) | |
tree | 406b175b19179938a84f3c45b40c23c47936b603 /drivers/platform | |
parent | 7a9568f536754623738110a314ff33286cdbb17d (diff) |
ACPI: WMI: Survive BIOS with duplicate GUIDs
It would appear that in BIOS's with nVidia hooks, the GUID
05901221-D566-11D1-B2F0-00A0C9062910 is duplicated. For now, the simplest
solution is to just ignore any duplicate GUIDs. These particular hooks are not
currently supported/ used in the kernel, so whoever does that can figure out
what the 'right' solution should be (if there's a better one).
http://bugzilla.kernel.org/show_bug.cgi?id=14846
Signed-off-by: Carlos Corbacho <carlos@strangeworlds.co.uk>
Reported-by: Larry Finger <Larry.Finger@lwfinger.net>
Reported-by: Oldřich Jedlička <oldium.pro@seznam.cz>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/x86/wmi.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index cc9ad740bda1..b104302fea0a 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c | |||
@@ -714,6 +714,22 @@ static int wmi_class_init(void) | |||
714 | return ret; | 714 | return ret; |
715 | } | 715 | } |
716 | 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 | |||
717 | /* | 733 | /* |
718 | * Parse the _WDG method for the GUID data blocks | 734 | * Parse the _WDG method for the GUID data blocks |
719 | */ | 735 | */ |
@@ -723,6 +739,7 @@ static __init acpi_status parse_wdg(acpi_handle handle) | |||
723 | union acpi_object *obj; | 739 | union acpi_object *obj; |
724 | struct guid_block *gblock; | 740 | struct guid_block *gblock; |
725 | struct wmi_block *wblock; | 741 | struct wmi_block *wblock; |
742 | char guid_string[37]; | ||
726 | acpi_status status; | 743 | acpi_status status; |
727 | u32 i, total; | 744 | u32 i, total; |
728 | 745 | ||
@@ -745,6 +762,19 @@ static __init acpi_status parse_wdg(acpi_handle handle) | |||
745 | memcpy(gblock, obj->buffer.pointer, obj->buffer.length); | 762 | memcpy(gblock, obj->buffer.pointer, obj->buffer.length); |
746 | 763 | ||
747 | 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 | } | ||
748 | wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL); | 778 | wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL); |
749 | if (!wblock) | 779 | if (!wblock) |
750 | return AE_NO_MEMORY; | 780 | return AE_NO_MEMORY; |