diff options
| -rw-r--r-- | drivers/platform/x86/dell-wmi.c | 18 | ||||
| -rw-r--r-- | drivers/platform/x86/hp-wmi.c | 9 | ||||
| -rw-r--r-- | drivers/platform/x86/msi-wmi.c | 9 | ||||
| -rw-r--r-- | drivers/platform/x86/wmi.c | 36 | 
4 files changed, 58 insertions, 14 deletions
| diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 916ccb2b316c..1b1dddbd5744 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; @@ -323,8 +328,9 @@ 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)) { +	if (!wmi_has_guid(DELL_EVENT_GUID)) {  		printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n");  		return -ENODEV;  	} @@ -336,14 +342,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; diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 8781d8fa7a57..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; @@ -581,7 +586,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..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; @@ -236,7 +241,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(); 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)  	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) @@ -716,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   */ @@ -725,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; @@ -747,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; | 
