USB HID: add 'quirks' module parameter
Add a 'quirks' module parameter for the usbhid module, so users can add or modify quirks at module load time. Signed-off-by: Paul Walmsley <paul@booyaka.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
		
							parent
							
								
									8cef908235
								
							
						
					
					
						commit
						876b9276b9
					
				| @ -53,6 +53,13 @@ static unsigned int hid_mousepoll_interval; | ||||
| module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); | ||||
| MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); | ||||
| 
 | ||||
| /* Quirks specified at module load time */ | ||||
| static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL }; | ||||
| module_param_array_named(quirks, quirks_param, charp, NULL, 0444); | ||||
| MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying " | ||||
| 		" quirks=vendorID:productID:quirks" | ||||
| 		" where vendorID, productID, and quirks are all in" | ||||
| 		" 0x-prefixed hex"); | ||||
| /*
 | ||||
|  * Input submission and I/O error handler. | ||||
|  */ | ||||
| @ -1072,6 +1079,9 @@ static struct usb_driver hid_driver = { | ||||
| static int __init hid_init(void) | ||||
| { | ||||
| 	int retval; | ||||
| 	retval = usbhid_quirks_init(quirks_param); | ||||
| 	if (retval) | ||||
| 		goto usbhid_quirks_init_fail; | ||||
| 	retval = hiddev_init(); | ||||
| 	if (retval) | ||||
| 		goto hiddev_init_fail; | ||||
| @ -1084,6 +1094,8 @@ static int __init hid_init(void) | ||||
| usb_register_fail: | ||||
| 	hiddev_exit(); | ||||
| hiddev_init_fail: | ||||
| 	usbhid_quirks_exit(); | ||||
| usbhid_quirks_init_fail: | ||||
| 	return retval; | ||||
| } | ||||
| 
 | ||||
| @ -1091,6 +1103,7 @@ static void __exit hid_exit(void) | ||||
| { | ||||
| 	usb_deregister(&hid_driver); | ||||
| 	hiddev_exit(); | ||||
| 	usbhid_quirks_exit(); | ||||
| } | ||||
| 
 | ||||
| module_init(hid_init); | ||||
|  | ||||
| @ -576,6 +576,44 @@ static void usbhid_remove_all_dquirks(void) | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /** 
 | ||||
|  * usbhid_quirks_init: apply USB HID quirks specified at module load time | ||||
|  */ | ||||
| int usbhid_quirks_init(char **quirks_param) | ||||
| { | ||||
| 	u16 idVendor, idProduct; | ||||
| 	u32 quirks; | ||||
| 	int n = 0, m; | ||||
| 
 | ||||
| 	for (; quirks_param[n] && n < MAX_USBHID_BOOT_QUIRKS; n++) { | ||||
| 
 | ||||
| 		m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x", | ||||
| 				&idVendor, &idProduct, &quirks); | ||||
| 
 | ||||
| 		if (m != 3 || | ||||
| 				usbhid_modify_dquirk(idVendor, idProduct, quirks) != 0) { | ||||
| 			printk(KERN_WARNING | ||||
| 					"Could not parse HID quirk module param %s\n", | ||||
| 					quirks_param[n]); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * usbhid_quirks_exit: release memory associated with dynamic_quirks | ||||
|  * | ||||
|  * Description: | ||||
|  *     Release all memory associated with dynamic quirks.  Called upon | ||||
|  *     module unload. | ||||
|  * | ||||
|  * Returns: nothing | ||||
|  */ | ||||
| void usbhid_quirks_exit(void) | ||||
| { | ||||
| 	usbhid_remove_all_dquirks(); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * usbhid_exists_squirk: return any static quirks for a USB HID device | ||||
|  | ||||
| @ -247,6 +247,11 @@ struct hid_item { | ||||
|  * HID device quirks. | ||||
|  */ | ||||
| 
 | ||||
| /* 
 | ||||
|  * Increase this if you need to configure more HID quirks at module load time | ||||
|  */ | ||||
| #define MAX_USBHID_BOOT_QUIRKS 4 | ||||
| 
 | ||||
| #define HID_QUIRK_INVERT			0x00000001 | ||||
| #define HID_QUIRK_NOTOUCH			0x00000002 | ||||
| #define HID_QUIRK_IGNORE			0x00000004 | ||||
| @ -495,8 +500,11 @@ void hid_output_report(struct hid_report *report, __u8 *data); | ||||
| void hid_free_device(struct hid_device *device); | ||||
| struct hid_device *hid_parse_report(__u8 *start, unsigned size); | ||||
| 
 | ||||
| /* HID quirks API */ | ||||
| u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); | ||||
| int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct, const u32 quirks); | ||||
| int usbhid_quirks_init(char **quirks_param); | ||||
| void usbhid_quirks_exit(void); | ||||
| 
 | ||||
| #ifdef CONFIG_HID_FF | ||||
| int hid_ff_init(struct hid_device *hid); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user