From abb631bfe271a9102fb5b05419272b7aec37a974 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 26 Dec 2009 21:51:38 -0500 Subject: dell-wmi: sys_init_module: 'dell_wmi'->init suspiciously returned 21, it should follow 0/-E convention wmi_install_notify_handler() returns an acpi_error, but dell_wmi_init() needs return a -errno style error. Tested-by: Paul Rolland Signed-off-by: Len Brown --- drivers/platform/x86/dell-wmi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 916ccb2b316c..4c7e70299d6b 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -323,6 +323,7 @@ static int __init dell_wmi_input_setup(void) static int __init dell_wmi_init(void) { int err; + acpi_status status; if (wmi_has_guid(DELL_EVENT_GUID)) { printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n"); @@ -336,14 +337,14 @@ static int __init dell_wmi_init(void) if (err) return err; - err = wmi_install_notify_handler(DELL_EVENT_GUID, + status = wmi_install_notify_handler(DELL_EVENT_GUID, dell_wmi_notify, NULL); - if (err) { + if (ACPI_FAILURE(status)) { input_unregister_device(dell_wmi_input_dev); printk(KERN_ERR "dell-wmi: Unable to register notify handler - %d\n", - err); - return err; + status); + return -ENODEV; } return 0; -- cgit v1.2.3 From f27725756be8a2c2dc65eaf70d0b52807aa2f113 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 26 Dec 2009 22:04:03 -0500 Subject: ACPI: hp-wmi, msi-wmi: clarify that wmi_install_notify_handler() returns an acpi_status Emphasize that that wmi_install_notify_handler() returns an acpi_status rather than -errno by by testing ACPI_SUCCESS(), ACPI_FAILURE(). No functional change in this patch, but this confusion caused a bug in dell-wmi. Signed-off-by: Len Brown --- drivers/platform/x86/hp-wmi.c | 2 +- drivers/platform/x86/msi-wmi.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 8781d8fa7a57..18bf74136d24 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -581,7 +581,7 @@ static int __init hp_wmi_init(void) if (wmi_has_guid(HPWMI_EVENT_GUID)) { err = wmi_install_notify_handler(HPWMI_EVENT_GUID, hp_wmi_notify, NULL); - if (!err) + if (ACPI_SUCCESS(err)) hp_wmi_input_setup(); } diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index 7f77f908bb01..f746c677adaa 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c @@ -236,7 +236,7 @@ static int __init msi_wmi_init(void) } err = wmi_install_notify_handler(MSIWMI_EVENT_GUID, msi_wmi_notify, NULL); - if (err) + if (ACPI_FAILURE(err)) return -EINVAL; err = msi_wmi_input_setup(); -- cgit v1.2.3 From fda11e61ff8a4e3a8ebbd434e46560b67cc0ca9d Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 26 Dec 2009 23:02:24 -0500 Subject: dell-wmi, hp-wmi, msi-wmi: check wmi_get_event_data() return value When acpi_evaluate_object() is passed ACPI_ALLOCATE_BUFFER, the caller must kfree the returned buffer if AE_OK is returned. The callers of wmi_get_event_data() pass ACPI_ALLOCATE_BUFFER, and thus must check its return value before accessing or kfree() on the buffer. Signed-off-by: Len Brown --- drivers/platform/x86/dell-wmi.c | 7 ++++++- drivers/platform/x86/hp-wmi.c | 7 ++++++- drivers/platform/x86/msi-wmi.c | 7 ++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 4c7e70299d6b..500af8c9ada0 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -202,8 +202,13 @@ static void dell_wmi_notify(u32 value, void *context) struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; static struct key_entry *key; union acpi_object *obj; + acpi_status status; - wmi_get_event_data(value, &response); + status = wmi_get_event_data(value, &response); + if (status != AE_OK) { + printk(KERN_INFO "dell-wmi: bad event status 0x%x\n", status); + return; + } obj = (union acpi_object *)response.pointer; diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 18bf74136d24..5b648f0c6075 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -338,8 +338,13 @@ static void hp_wmi_notify(u32 value, void *context) static struct key_entry *key; union acpi_object *obj; int eventcode; + acpi_status status; - wmi_get_event_data(value, &response); + status = wmi_get_event_data(value, &response); + if (status != AE_OK) { + printk(KERN_INFO "hp-wmi: bad event status 0x%x\n", status); + return; + } obj = (union acpi_object *)response.pointer; diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index f746c677adaa..f5f70d4c6913 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c @@ -149,8 +149,13 @@ static void msi_wmi_notify(u32 value, void *context) static struct key_entry *key; union acpi_object *obj; ktime_t cur; + acpi_status status; - wmi_get_event_data(value, &response); + status = wmi_get_event_data(value, &response); + if (status != AE_OK) { + printk(KERN_INFO DRV_PFX "bad event status 0x%x\n", status); + return; + } obj = (union acpi_object *)response.pointer; -- cgit v1.2.3 From c03b26a5a5597a59b2e247d005d5901430109a8a Mon Sep 17 00:00:00 2001 From: Paul Rolland Date: Wed, 30 Dec 2009 01:07:40 -0500 Subject: wmi: check find_guid() return value to prevent oops Signed-off-by: Paul Rolland Signed-off-by: Len Brown --- drivers/platform/x86/wmi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 9f93d6c0f510..cc9ad740bda1 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -492,8 +492,7 @@ wmi_notify_handler handler, void *data) if (!guid || !handler) return AE_BAD_PARAMETER; - find_guid(guid, &block); - if (!block) + if (!find_guid(guid, &block)) return AE_NOT_EXIST; if (block->handler) @@ -521,8 +520,7 @@ acpi_status wmi_remove_notify_handler(const char *guid) if (!guid) return AE_BAD_PARAMETER; - find_guid(guid, &block); - if (!block) + if (!find_guid(guid, &block)) return AE_NOT_EXIST; if (!block->handler) -- cgit v1.2.3 From 7a9568f536754623738110a314ff33286cdbb17d Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 25 Dec 2009 11:49:35 -0800 Subject: dell-wmi - fix condition to abort driver loading From: Dmitry Torokhov The commit 1fdd407f4e3f2ecb453954cbebb6c22491c61853 incorrectly made driver abort loading when known GUID is present when it should have done exactly the opposite. Signed-off-by: Dmitry Torokhov Signed-off-by: Len Brown --- drivers/platform/x86/dell-wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 500af8c9ada0..1b1dddbd5744 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -330,7 +330,7 @@ static int __init dell_wmi_init(void) int err; acpi_status status; - if (wmi_has_guid(DELL_EVENT_GUID)) { + if (!wmi_has_guid(DELL_EVENT_GUID)) { printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n"); return -ENODEV; } -- cgit v1.2.3 From d1f9e4970742bb1e22d07b01bd44f9c357d25c42 Mon Sep 17 00:00:00 2001 From: Carlos Corbacho Date: Sat, 26 Dec 2009 19:14:59 +0000 Subject: ACPI: WMI: Survive BIOS with duplicate GUIDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reported-by: Larry Finger Reported-by: Oldřich Jedlička Signed-off-by: Len Brown --- drivers/platform/x86/wmi.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) 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) return ret; } +static bool guid_already_parsed(const char *guid_string) +{ + struct guid_block *gblock; + struct wmi_block *wblock; + struct list_head *p; + + list_for_each(p, &wmi_blocks.list) { + wblock = list_entry(p, struct wmi_block, list); + gblock = &wblock->gblock; + + if (strncmp(gblock->guid, guid_string, 16) == 0) + return true; + } + return false; +} + /* * Parse the _WDG method for the GUID data blocks */ @@ -723,6 +739,7 @@ static __init acpi_status parse_wdg(acpi_handle handle) union acpi_object *obj; struct guid_block *gblock; struct wmi_block *wblock; + char guid_string[37]; acpi_status status; u32 i, total; @@ -745,6 +762,19 @@ static __init acpi_status parse_wdg(acpi_handle handle) memcpy(gblock, obj->buffer.pointer, obj->buffer.length); for (i = 0; i < total; i++) { + /* + Some WMI devices, like those for nVidia hooks, have a + duplicate GUID. It's not clear what we should do in this + case yet, so for now, we'll just ignore the duplicate. + Anyone who wants to add support for that device can come + up with a better workaround for the mess then. + */ + if (guid_already_parsed(gblock[i].guid) == true) { + wmi_gtoa(gblock[i].guid, guid_string); + printk(KERN_INFO PREFIX "Skipping duplicate GUID %s\n", + guid_string); + continue; + } wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL); if (!wblock) return AE_NO_MEMORY; -- cgit v1.2.3