@@ -45,6 +45,13 @@ static int hid_ignore_special_drivers = 0;
module_param_named(ignore_special_drivers, hid_ignore_special_drivers, int, 0600);
MODULE_PARM_DESC(ignore_special_drivers, "Ignore any special drivers and handle all devices by generic driver");
+/* Quirks specified at module load time */
+static char *quirks_param[MAX_USBHID_BOOT_QUIRKS];
+module_param_array_named(quirks, quirks_param, charp, NULL, 0444);
+MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
+ " quirks=BUS:vendorID:productID:quirks"
+ " where BUS, vendorID, productID, and quirks are all in"
+ " 0x-prefixed hex");
/*
* Register a new report for a device.
*/
@@ -2951,6 +2958,10 @@ static int __init hid_init(void)
{
int ret;
+ ret = hid_quirks_bus_init(quirks_param, MAX_USBHID_BOOT_QUIRKS);
+ if (ret)
+ goto usbhid_quirks_init_fail;
+
ret = bus_register(&hid_bus_type);
if (ret) {
pr_err("can't register hid bus\n");
@@ -2972,6 +2983,8 @@ static int __init hid_init(void)
bus_unregister(&hid_bus_type);
err:
return ret;
+usbhid_quirks_init_fail:
+ return ret;
}
static void __exit hid_exit(void)
@@ -1182,6 +1182,39 @@ static void hid_remove_all_dquirks(__u16 bus)
}
+
+/**
+ * hid_quirks_bus_init - apply HID quirks specified at module load time
+ * @quirks_param: array of quirks strings (bus:vendor:product:quirks)
+ * @count: number of quirks to check
+ */
+int hid_quirks_bus_init(char **quirks_param, int count)
+{
+ struct hid_device_id id = { 0 };
+ int n = 0, m;
+ unsigned short int bus, vendor, product;
+ u32 quirks;
+
+ for (; n < count && quirks_param[n]; n++) {
+
+ m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%hx:0x%x",
+ &bus, &vendor, &product, &quirks);
+
+ id.bus = (__u16)bus;
+ id.vendor = (__u16)vendor;
+ id.product = (__u16)product;
+
+ if (m != 4 ||
+ hid_modify_dquirk(&id, quirks) != 0) {
+ pr_warn("Could not parse HID quirk module param %s\n",
+ quirks_param[n]);
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(hid_quirks_bus_init);
+
/**
* hid_quirks_init - apply HID quirks specified at module load time
* @quirks_param: array of quirks strings (vendor:product:quirks)
@@ -1178,6 +1178,7 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *
/* HID quirks API */
unsigned long hid_lookup_quirk(const struct hid_device *hdev);
+int hid_quirks_bus_init(char **quirks_param, int count);
int hid_quirks_init(char **quirks_param, __u16 bus, int count);
void hid_quirks_exit(__u16 bus);
Before this patch it was possible to specify quirks using run-time parameters, but only for the usbhid module. This patch introduces a quirks parameter for hid-core allowing to specify quirks as hid.quirks=BUS:vendorID:productID:quirks Signed-off-by: Marco Morandini <marco.morandini@polimi.it> --- I don't know if this is a good idea or not. If it was for me, I'd get rid of the usbhid parameters and of the duplicated hid_quirks_init, forcing everyone to specify the bus, but I fear this could be a regression for user space. drivers/hid/hid-core.c | 13 +++++++++++++ drivers/hid/hid-quirks.c | 33 +++++++++++++++++++++++++++++++++ include/linux/hid.h | 1 + 3 files changed, 47 insertions(+)