xref: /linux/drivers/hid/hid-roccat-kone.c (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Roccat Kone driver for Linux
4  *
5  * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
6  */
7 
8 /*
9  */
10 
11 /*
12  * Roccat Kone is a gamer mouse which consists of a mouse part and a keyboard
13  * part. The keyboard part enables the mouse to execute stored macros with mixed
14  * key- and button-events.
15  *
16  * TODO implement on-the-fly polling-rate change
17  *      The windows driver has the ability to change the polling rate of the
18  *      device on the press of a mousebutton.
19  *      Is it possible to remove and reinstall the urb in raw-event- or any
20  *      other handler, or to defer this action to be executed somewhere else?
21  *
22  * TODO is it possible to overwrite group for sysfs attributes via udev?
23  */
24 
25 #include <linux/device.h>
26 #include <linux/input.h>
27 #include <linux/hid.h>
28 #include <linux/module.h>
29 #include <linux/slab.h>
30 #include <linux/hid-roccat.h>
31 #include "hid-ids.h"
32 #include "hid-roccat-common.h"
33 #include "hid-roccat-kone.h"
34 
35 static uint profile_numbers[5] = {0, 1, 2, 3, 4};
36 
37 static void kone_profile_activated(struct kone_device *kone, uint new_profile)
38 {
39 	if (new_profile < 1 || new_profile > ARRAY_SIZE(kone->profiles))
40 		new_profile = 1;
41 	kone->actual_profile = new_profile;
42 	kone->actual_dpi = kone->profiles[new_profile - 1].startup_dpi;
43 }
44 
45 static void kone_profile_report(struct kone_device *kone, uint new_profile)
46 {
47 	struct kone_roccat_report roccat_report;
48 
49 	roccat_report.event = kone_mouse_event_switch_profile;
50 	roccat_report.value = new_profile;
51 	roccat_report.key = 0;
52 	roccat_report_event(kone->chrdev_minor, (uint8_t *)&roccat_report);
53 }
54 
55 static int kone_receive(struct usb_device *usb_dev, uint usb_command,
56 		void *data, uint size)
57 {
58 	char *buf;
59 	int len;
60 
61 	buf = kmalloc(size, GFP_KERNEL);
62 	if (buf == NULL)
63 		return -ENOMEM;
64 
65 	len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
66 			HID_REQ_GET_REPORT,
67 			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
68 			usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
69 
70 	memcpy(data, buf, size);
71 	kfree(buf);
72 	return ((len < 0) ? len : ((len != size) ? -EIO : 0));
73 }
74 
75 static int kone_send(struct usb_device *usb_dev, uint usb_command,
76 		void const *data, uint size)
77 {
78 	char *buf;
79 	int len;
80 
81 	buf = kmemdup(data, size, GFP_KERNEL);
82 	if (buf == NULL)
83 		return -ENOMEM;
84 
85 	len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
86 			HID_REQ_SET_REPORT,
87 			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
88 			usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
89 
90 	kfree(buf);
91 	return ((len < 0) ? len : ((len != size) ? -EIO : 0));
92 }
93 
94 static void kone_set_settings_checksum(struct kone_settings *settings)
95 {
96 	uint16_t checksum = 0;
97 	unsigned char *address = (unsigned char *)settings;
98 	int i;
99 
100 	for (i = 0; i < sizeof(struct kone_settings) - 2; ++i, ++address)
101 		checksum += *address;
102 	settings->checksum = cpu_to_le16(checksum);
103 }
104 
105 /*
106  * Checks success after writing data to mouse
107  * On success returns 0
108  * On failure returns errno
109  */
110 static int kone_check_write(struct usb_device *usb_dev)
111 {
112 	int retval;
113 	uint8_t data;
114 
115 	do {
116 		/*
117 		 * Mouse needs 50 msecs until it says ok, but there are
118 		 * 30 more msecs needed for next write to work.
119 		 */
120 		msleep(80);
121 
122 		retval = kone_receive(usb_dev,
123 				kone_command_confirm_write, &data, 1);
124 		if (retval)
125 			return retval;
126 
127 		/*
128 		 * value of 3 seems to mean something like
129 		 * "not finished yet, but it looks good"
130 		 * So check again after a moment.
131 		 */
132 	} while (data == 3);
133 
134 	if (data == 1) /* everything alright */
135 		return 0;
136 
137 	/* unknown answer */
138 	dev_err(&usb_dev->dev, "got retval %d when checking write\n", data);
139 	return -EIO;
140 }
141 
142 /*
143  * Reads settings from mouse and stores it in @buf
144  * On success returns 0
145  * On failure returns errno
146  */
147 static int kone_get_settings(struct usb_device *usb_dev,
148 		struct kone_settings *buf)
149 {
150 	return kone_receive(usb_dev, kone_command_settings, buf,
151 			sizeof(struct kone_settings));
152 }
153 
154 /*
155  * Writes settings from @buf to mouse
156  * On success returns 0
157  * On failure returns errno
158  */
159 static int kone_set_settings(struct usb_device *usb_dev,
160 		struct kone_settings const *settings)
161 {
162 	int retval;
163 
164 	retval = kone_send(usb_dev, kone_command_settings,
165 			settings, sizeof(struct kone_settings));
166 	if (retval)
167 		return retval;
168 	return kone_check_write(usb_dev);
169 }
170 
171 /*
172  * Reads profile data from mouse and stores it in @buf
173  * @number: profile number to read
174  * On success returns 0
175  * On failure returns errno
176  */
177 static int kone_get_profile(struct usb_device *usb_dev,
178 		struct kone_profile *buf, int number)
179 {
180 	int len;
181 
182 	if (number < 1 || number > 5)
183 		return -EINVAL;
184 
185 	len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
186 			USB_REQ_CLEAR_FEATURE,
187 			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
188 			kone_command_profile, number, buf,
189 			sizeof(struct kone_profile), USB_CTRL_SET_TIMEOUT);
190 
191 	if (len != sizeof(struct kone_profile))
192 		return -EIO;
193 
194 	return 0;
195 }
196 
197 /*
198  * Writes profile data to mouse.
199  * @number: profile number to write
200  * On success returns 0
201  * On failure returns errno
202  */
203 static int kone_set_profile(struct usb_device *usb_dev,
204 		struct kone_profile const *profile, int number)
205 {
206 	int len;
207 
208 	if (number < 1 || number > 5)
209 		return -EINVAL;
210 
211 	len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
212 			USB_REQ_SET_CONFIGURATION,
213 			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
214 			kone_command_profile, number, (void *)profile,
215 			sizeof(struct kone_profile),
216 			USB_CTRL_SET_TIMEOUT);
217 
218 	if (len != sizeof(struct kone_profile))
219 		return len;
220 
221 	if (kone_check_write(usb_dev))
222 		return -EIO;
223 
224 	return 0;
225 }
226 
227 /*
228  * Reads value of "fast-clip-weight" and stores it in @result
229  * On success returns 0
230  * On failure returns errno
231  */
232 static int kone_get_weight(struct usb_device *usb_dev, int *result)
233 {
234 	int retval;
235 	uint8_t data;
236 
237 	retval = kone_receive(usb_dev, kone_command_weight, &data, 1);
238 
239 	if (retval)
240 		return retval;
241 
242 	*result = (int)data;
243 	return 0;
244 }
245 
246 /*
247  * Reads firmware_version of mouse and stores it in @result
248  * On success returns 0
249  * On failure returns errno
250  */
251 static int kone_get_firmware_version(struct usb_device *usb_dev, int *result)
252 {
253 	int retval;
254 	uint16_t data;
255 
256 	retval = kone_receive(usb_dev, kone_command_firmware_version,
257 			&data, 2);
258 	if (retval)
259 		return retval;
260 
261 	*result = le16_to_cpu(data);
262 	return 0;
263 }
264 
265 static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj,
266 		const struct bin_attribute *attr, char *buf,
267 		loff_t off, size_t count) {
268 	struct device *dev = kobj_to_dev(kobj)->parent->parent;
269 	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
270 
271 	if (off >= sizeof(struct kone_settings))
272 		return 0;
273 
274 	if (off + count > sizeof(struct kone_settings))
275 		count = sizeof(struct kone_settings) - off;
276 
277 	mutex_lock(&kone->kone_lock);
278 	memcpy(buf, ((char const *)&kone->settings) + off, count);
279 	mutex_unlock(&kone->kone_lock);
280 
281 	return count;
282 }
283 
284 /*
285  * Writing settings automatically activates startup_profile.
286  * This function keeps values in kone_device up to date and assumes that in
287  * case of error the old data is still valid
288  */
289 static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj,
290 		const struct bin_attribute *attr, char *buf,
291 		loff_t off, size_t count) {
292 	struct device *dev = kobj_to_dev(kobj)->parent->parent;
293 	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
294 	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
295 	int retval = 0, difference, old_profile;
296 	struct kone_settings *settings = (struct kone_settings *)buf;
297 
298 	/* I need to get my data in one piece */
299 	if (off != 0 || count != sizeof(struct kone_settings))
300 		return -EINVAL;
301 
302 	mutex_lock(&kone->kone_lock);
303 	difference = memcmp(settings, &kone->settings,
304 			    sizeof(struct kone_settings));
305 	if (difference) {
306 		if (settings->startup_profile < 1 ||
307 		    settings->startup_profile > 5) {
308 			retval = -EINVAL;
309 			goto unlock;
310 		}
311 
312 		retval = kone_set_settings(usb_dev, settings);
313 		if (retval)
314 			goto unlock;
315 
316 		old_profile = kone->settings.startup_profile;
317 		memcpy(&kone->settings, settings, sizeof(struct kone_settings));
318 
319 		kone_profile_activated(kone, kone->settings.startup_profile);
320 
321 		if (kone->settings.startup_profile != old_profile)
322 			kone_profile_report(kone, kone->settings.startup_profile);
323 	}
324 unlock:
325 	mutex_unlock(&kone->kone_lock);
326 
327 	if (retval)
328 		return retval;
329 
330 	return sizeof(struct kone_settings);
331 }
332 static const BIN_ATTR(settings, 0660, kone_sysfs_read_settings,
333 		      kone_sysfs_write_settings, sizeof(struct kone_settings));
334 
335 static ssize_t kone_sysfs_read_profilex(struct file *fp,
336 		struct kobject *kobj, const struct bin_attribute *attr,
337 		char *buf, loff_t off, size_t count) {
338 	struct device *dev = kobj_to_dev(kobj)->parent->parent;
339 	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
340 
341 	if (off >= sizeof(struct kone_profile))
342 		return 0;
343 
344 	if (off + count > sizeof(struct kone_profile))
345 		count = sizeof(struct kone_profile) - off;
346 
347 	mutex_lock(&kone->kone_lock);
348 	memcpy(buf, ((char const *)&kone->profiles[*(uint *)(attr->private)]) + off, count);
349 	mutex_unlock(&kone->kone_lock);
350 
351 	return count;
352 }
353 
354 /* Writes data only if different to stored data */
355 static ssize_t kone_sysfs_write_profilex(struct file *fp,
356 		struct kobject *kobj, const struct bin_attribute *attr,
357 		char *buf, loff_t off, size_t count) {
358 	struct device *dev = kobj_to_dev(kobj)->parent->parent;
359 	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
360 	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
361 	struct kone_profile *profile;
362 	int retval = 0, difference;
363 
364 	/* I need to get my data in one piece */
365 	if (off != 0 || count != sizeof(struct kone_profile))
366 		return -EINVAL;
367 
368 	profile = &kone->profiles[*(uint *)(attr->private)];
369 
370 	mutex_lock(&kone->kone_lock);
371 	difference = memcmp(buf, profile, sizeof(struct kone_profile));
372 	if (difference) {
373 		retval = kone_set_profile(usb_dev,
374 				(struct kone_profile const *)buf,
375 				*(uint *)(attr->private) + 1);
376 		if (!retval)
377 			memcpy(profile, buf, sizeof(struct kone_profile));
378 	}
379 	mutex_unlock(&kone->kone_lock);
380 
381 	if (retval)
382 		return retval;
383 
384 	return sizeof(struct kone_profile);
385 }
386 #define PROFILE_ATTR(number)					\
387 static const struct bin_attribute bin_attr_profile##number = {	\
388 	.attr = { .name = "profile" #number, .mode = 0660 },	\
389 	.size = sizeof(struct kone_profile),			\
390 	.read = kone_sysfs_read_profilex,			\
391 	.write = kone_sysfs_write_profilex,			\
392 	.private = &profile_numbers[number-1],			\
393 }
394 PROFILE_ATTR(1);
395 PROFILE_ATTR(2);
396 PROFILE_ATTR(3);
397 PROFILE_ATTR(4);
398 PROFILE_ATTR(5);
399 
400 static ssize_t kone_sysfs_show_actual_profile(struct device *dev,
401 		struct device_attribute *attr, char *buf)
402 {
403 	struct kone_device *kone =
404 			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
405 	return sysfs_emit(buf, "%d\n", kone->actual_profile);
406 }
407 static DEVICE_ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL);
408 
409 static ssize_t kone_sysfs_show_actual_dpi(struct device *dev,
410 		struct device_attribute *attr, char *buf)
411 {
412 	struct kone_device *kone =
413 			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
414 	return sysfs_emit(buf, "%d\n", kone->actual_dpi);
415 }
416 static DEVICE_ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL);
417 
418 /* weight is read each time, since we don't get informed when it's changed */
419 static ssize_t kone_sysfs_show_weight(struct device *dev,
420 		struct device_attribute *attr, char *buf)
421 {
422 	struct kone_device *kone;
423 	struct usb_device *usb_dev;
424 	int weight = 0;
425 	int retval;
426 
427 	dev = dev->parent->parent;
428 	kone = hid_get_drvdata(dev_get_drvdata(dev));
429 	usb_dev = interface_to_usbdev(to_usb_interface(dev));
430 
431 	mutex_lock(&kone->kone_lock);
432 	retval = kone_get_weight(usb_dev, &weight);
433 	mutex_unlock(&kone->kone_lock);
434 
435 	if (retval)
436 		return retval;
437 	return sysfs_emit(buf, "%d\n", weight);
438 }
439 static DEVICE_ATTR(weight, 0440, kone_sysfs_show_weight, NULL);
440 
441 static ssize_t kone_sysfs_show_firmware_version(struct device *dev,
442 		struct device_attribute *attr, char *buf)
443 {
444 	struct kone_device *kone =
445 			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
446 	return sysfs_emit(buf, "%d\n", kone->firmware_version);
447 }
448 static DEVICE_ATTR(firmware_version, 0440, kone_sysfs_show_firmware_version,
449 		   NULL);
450 
451 static ssize_t kone_sysfs_show_tcu(struct device *dev,
452 		struct device_attribute *attr, char *buf)
453 {
454 	struct kone_device *kone =
455 			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
456 	return sysfs_emit(buf, "%d\n", kone->settings.tcu);
457 }
458 
459 static int kone_tcu_command(struct usb_device *usb_dev, int number)
460 {
461 	unsigned char value;
462 
463 	value = number;
464 	return kone_send(usb_dev, kone_command_calibrate, &value, 1);
465 }
466 
467 /*
468  * Calibrating the tcu is the only action that changes settings data inside the
469  * mouse, so this data needs to be reread
470  */
471 static ssize_t kone_sysfs_set_tcu(struct device *dev,
472 		struct device_attribute *attr, char const *buf, size_t size)
473 {
474 	struct kone_device *kone;
475 	struct usb_device *usb_dev;
476 	int retval;
477 	unsigned long state;
478 
479 	dev = dev->parent->parent;
480 	kone = hid_get_drvdata(dev_get_drvdata(dev));
481 	usb_dev = interface_to_usbdev(to_usb_interface(dev));
482 
483 	retval = kstrtoul(buf, 10, &state);
484 	if (retval)
485 		return retval;
486 
487 	if (state != 0 && state != 1)
488 		return -EINVAL;
489 
490 	mutex_lock(&kone->kone_lock);
491 
492 	if (state == 1) { /* state activate */
493 		retval = kone_tcu_command(usb_dev, 1);
494 		if (retval)
495 			goto exit_unlock;
496 		retval = kone_tcu_command(usb_dev, 2);
497 		if (retval)
498 			goto exit_unlock;
499 		ssleep(5); /* tcu needs this time for calibration */
500 		retval = kone_tcu_command(usb_dev, 3);
501 		if (retval)
502 			goto exit_unlock;
503 		retval = kone_tcu_command(usb_dev, 0);
504 		if (retval)
505 			goto exit_unlock;
506 		retval = kone_tcu_command(usb_dev, 4);
507 		if (retval)
508 			goto exit_unlock;
509 		/*
510 		 * Kone needs this time to settle things.
511 		 * Reading settings too early will result in invalid data.
512 		 * Roccat's driver waits 1 sec, maybe this time could be
513 		 * shortened.
514 		 */
515 		ssleep(1);
516 	}
517 
518 	/* calibration changes values in settings, so reread */
519 	retval = kone_get_settings(usb_dev, &kone->settings);
520 	if (retval)
521 		goto exit_no_settings;
522 
523 	/* only write settings back if activation state is different */
524 	if (kone->settings.tcu != state) {
525 		kone->settings.tcu = state;
526 		kone_set_settings_checksum(&kone->settings);
527 
528 		retval = kone_set_settings(usb_dev, &kone->settings);
529 		if (retval) {
530 			dev_err(&usb_dev->dev, "couldn't set tcu state\n");
531 			/*
532 			 * try to reread valid settings into buffer overwriting
533 			 * first error code
534 			 */
535 			retval = kone_get_settings(usb_dev, &kone->settings);
536 			if (retval)
537 				goto exit_no_settings;
538 			goto exit_unlock;
539 		}
540 		/* calibration resets profile */
541 		kone_profile_activated(kone, kone->settings.startup_profile);
542 	}
543 
544 	retval = size;
545 exit_no_settings:
546 	dev_err(&usb_dev->dev, "couldn't read settings\n");
547 exit_unlock:
548 	mutex_unlock(&kone->kone_lock);
549 	return retval;
550 }
551 static DEVICE_ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu);
552 
553 static ssize_t kone_sysfs_show_startup_profile(struct device *dev,
554 		struct device_attribute *attr, char *buf)
555 {
556 	struct kone_device *kone =
557 			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
558 	return sysfs_emit(buf, "%d\n", kone->settings.startup_profile);
559 }
560 
561 static ssize_t kone_sysfs_set_startup_profile(struct device *dev,
562 		struct device_attribute *attr, char const *buf, size_t size)
563 {
564 	struct kone_device *kone;
565 	struct usb_device *usb_dev;
566 	int retval;
567 	unsigned long new_startup_profile;
568 
569 	dev = dev->parent->parent;
570 	kone = hid_get_drvdata(dev_get_drvdata(dev));
571 	usb_dev = interface_to_usbdev(to_usb_interface(dev));
572 
573 	retval = kstrtoul(buf, 10, &new_startup_profile);
574 	if (retval)
575 		return retval;
576 
577 	if (new_startup_profile  < 1 || new_startup_profile > 5)
578 		return -EINVAL;
579 
580 	mutex_lock(&kone->kone_lock);
581 
582 	kone->settings.startup_profile = new_startup_profile;
583 	kone_set_settings_checksum(&kone->settings);
584 
585 	retval = kone_set_settings(usb_dev, &kone->settings);
586 	if (retval) {
587 		mutex_unlock(&kone->kone_lock);
588 		return retval;
589 	}
590 
591 	/* changing the startup profile immediately activates this profile */
592 	kone_profile_activated(kone, new_startup_profile);
593 	kone_profile_report(kone, new_startup_profile);
594 
595 	mutex_unlock(&kone->kone_lock);
596 	return size;
597 }
598 static DEVICE_ATTR(startup_profile, 0660, kone_sysfs_show_startup_profile,
599 		   kone_sysfs_set_startup_profile);
600 
601 static struct attribute *kone_attrs[] = {
602 	/*
603 	 * Read actual dpi settings.
604 	 * Returns raw value for further processing. Refer to enum
605 	 * kone_polling_rates to get real value.
606 	 */
607 	&dev_attr_actual_dpi.attr,
608 	&dev_attr_actual_profile.attr,
609 
610 	/*
611 	 * The mouse can be equipped with one of four supplied weights from 5
612 	 * to 20 grams which are recognized and its value can be read out.
613 	 * This returns the raw value reported by the mouse for easy evaluation
614 	 * by software. Refer to enum kone_weights to get corresponding real
615 	 * weight.
616 	 */
617 	&dev_attr_weight.attr,
618 
619 	/*
620 	 * Prints firmware version stored in mouse as integer.
621 	 * The raw value reported by the mouse is returned for easy evaluation,
622 	 * to get the real version number the decimal point has to be shifted 2
623 	 * positions to the left. E.g. a value of 138 means 1.38.
624 	 */
625 	&dev_attr_firmware_version.attr,
626 
627 	/*
628 	 * Prints state of Tracking Control Unit as number where 0 = off and
629 	 * 1 = on. Writing 0 deactivates tcu and writing 1 calibrates and
630 	 * activates the tcu
631 	 */
632 	&dev_attr_tcu.attr,
633 
634 	/* Prints and takes the number of the profile the mouse starts with */
635 	&dev_attr_startup_profile.attr,
636 	NULL,
637 };
638 
639 static const struct bin_attribute *const kone_bin_attributes[] = {
640 	&bin_attr_settings,
641 	&bin_attr_profile1,
642 	&bin_attr_profile2,
643 	&bin_attr_profile3,
644 	&bin_attr_profile4,
645 	&bin_attr_profile5,
646 	NULL,
647 };
648 
649 static const struct attribute_group kone_group = {
650 	.attrs = kone_attrs,
651 	.bin_attrs = kone_bin_attributes,
652 };
653 
654 static const struct attribute_group *kone_groups[] = {
655 	&kone_group,
656 	NULL,
657 };
658 
659 /* kone_class is used for creating sysfs attributes via roccat char device */
660 static const struct class kone_class = {
661 	.name = "kone",
662 	.dev_groups = kone_groups,
663 };
664 
665 static int kone_init_kone_device_struct(struct usb_device *usb_dev,
666 		struct kone_device *kone)
667 {
668 	uint i;
669 	int retval;
670 
671 	mutex_init(&kone->kone_lock);
672 
673 	for (i = 0; i < 5; ++i) {
674 		retval = kone_get_profile(usb_dev, &kone->profiles[i], i + 1);
675 		if (retval)
676 			return retval;
677 	}
678 
679 	retval = kone_get_settings(usb_dev, &kone->settings);
680 	if (retval)
681 		return retval;
682 
683 	retval = kone_get_firmware_version(usb_dev, &kone->firmware_version);
684 	if (retval)
685 		return retval;
686 
687 	kone_profile_activated(kone, kone->settings.startup_profile);
688 
689 	return 0;
690 }
691 
692 /*
693  * Since IGNORE_MOUSE quirk moved to hid-apple, there is no way to bind only to
694  * mousepart if usb_hid is compiled into the kernel and kone is compiled as
695  * module.
696  * Secial behaviour is bound only to mousepart since only mouseevents contain
697  * additional notifications.
698  */
699 static int kone_init_specials(struct hid_device *hdev)
700 {
701 	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
702 	struct usb_device *usb_dev = interface_to_usbdev(intf);
703 	struct kone_device *kone;
704 	int retval;
705 
706 	if (intf->cur_altsetting->desc.bInterfaceProtocol
707 			== USB_INTERFACE_PROTOCOL_MOUSE) {
708 
709 		kone = kzalloc_obj(*kone);
710 		if (!kone)
711 			return -ENOMEM;
712 		hid_set_drvdata(hdev, kone);
713 
714 		retval = kone_init_kone_device_struct(usb_dev, kone);
715 		if (retval) {
716 			hid_err(hdev, "couldn't init struct kone_device\n");
717 			goto exit_free;
718 		}
719 
720 		retval = roccat_connect(&kone_class, hdev,
721 					sizeof(struct kone_roccat_report));
722 		if (retval < 0) {
723 			hid_err(hdev, "couldn't init char dev\n");
724 			/* be tolerant about not getting chrdev */
725 		} else {
726 			kone->roccat_claimed = 1;
727 			kone->chrdev_minor = retval;
728 		}
729 	} else {
730 		hid_set_drvdata(hdev, NULL);
731 	}
732 
733 	return 0;
734 exit_free:
735 	kfree(kone);
736 	return retval;
737 }
738 
739 static void kone_remove_specials(struct hid_device *hdev)
740 {
741 	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
742 	struct kone_device *kone;
743 
744 	if (intf->cur_altsetting->desc.bInterfaceProtocol
745 			== USB_INTERFACE_PROTOCOL_MOUSE) {
746 		kone = hid_get_drvdata(hdev);
747 		if (kone->roccat_claimed)
748 			roccat_disconnect(kone->chrdev_minor);
749 		kfree(hid_get_drvdata(hdev));
750 	}
751 }
752 
753 static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id)
754 {
755 	int retval;
756 
757 	if (!hid_is_usb(hdev))
758 		return -EINVAL;
759 
760 	retval = hid_parse(hdev);
761 	if (retval) {
762 		hid_err(hdev, "parse failed\n");
763 		goto exit;
764 	}
765 
766 	retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
767 	if (retval) {
768 		hid_err(hdev, "hw start failed\n");
769 		goto exit;
770 	}
771 
772 	retval = kone_init_specials(hdev);
773 	if (retval) {
774 		hid_err(hdev, "couldn't install mouse\n");
775 		goto exit_stop;
776 	}
777 
778 	return 0;
779 
780 exit_stop:
781 	hid_hw_stop(hdev);
782 exit:
783 	return retval;
784 }
785 
786 static void kone_remove(struct hid_device *hdev)
787 {
788 	kone_remove_specials(hdev);
789 	hid_hw_stop(hdev);
790 }
791 
792 /* handle special events and keep actual profile and dpi values up to date */
793 static void kone_keep_values_up_to_date(struct kone_device *kone,
794 		struct kone_mouse_event const *event)
795 {
796 	switch (event->event) {
797 	case kone_mouse_event_switch_profile:
798 		if (event->value >= 1 &&
799 		    event->value <= ARRAY_SIZE(kone->profiles))
800 			kone->actual_dpi =
801 				kone->profiles[event->value - 1].startup_dpi;
802 		fallthrough;
803 	case kone_mouse_event_osd_profile:
804 		kone->actual_profile = event->value;
805 		break;
806 	case kone_mouse_event_switch_dpi:
807 	case kone_mouse_event_osd_dpi:
808 		kone->actual_dpi = event->value;
809 		break;
810 	}
811 }
812 
813 static void kone_report_to_chrdev(struct kone_device const *kone,
814 		struct kone_mouse_event const *event)
815 {
816 	struct kone_roccat_report roccat_report;
817 
818 	switch (event->event) {
819 	case kone_mouse_event_switch_profile:
820 	case kone_mouse_event_switch_dpi:
821 	case kone_mouse_event_osd_profile:
822 	case kone_mouse_event_osd_dpi:
823 		roccat_report.event = event->event;
824 		roccat_report.value = event->value;
825 		roccat_report.key = 0;
826 		roccat_report_event(kone->chrdev_minor,
827 				(uint8_t *)&roccat_report);
828 		break;
829 	case kone_mouse_event_call_overlong_macro:
830 	case kone_mouse_event_multimedia:
831 		if (event->value == kone_keystroke_action_press) {
832 			roccat_report.event = event->event;
833 			roccat_report.value = kone->actual_profile;
834 			roccat_report.key = event->macro_key;
835 			roccat_report_event(kone->chrdev_minor,
836 					(uint8_t *)&roccat_report);
837 		}
838 		break;
839 	}
840 
841 }
842 
843 /*
844  * Is called for keyboard- and mousepart.
845  * Only mousepart gets informations about special events in its extended event
846  * structure.
847  */
848 static int kone_raw_event(struct hid_device *hdev, struct hid_report *report,
849 		u8 *data, int size)
850 {
851 	struct kone_device *kone = hid_get_drvdata(hdev);
852 	struct kone_mouse_event *event = (struct kone_mouse_event *)data;
853 
854 	/* keyboard events are always processed by default handler */
855 	if (size != sizeof(struct kone_mouse_event))
856 		return 0;
857 
858 	if (kone == NULL)
859 		return 0;
860 
861 	/*
862 	 * Firmware 1.38 introduced new behaviour for tilt and special buttons.
863 	 * Pressed button is reported in each movement event.
864 	 * Workaround sends only one event per press.
865 	 */
866 	if (memcmp(&kone->last_mouse_event.tilt, &event->tilt, 5))
867 		memcpy(&kone->last_mouse_event, event,
868 				sizeof(struct kone_mouse_event));
869 	else
870 		memset(&event->wipe, 0, sizeof(event->wipe));
871 
872 	kone_keep_values_up_to_date(kone, event);
873 
874 	if (kone->roccat_claimed)
875 		kone_report_to_chrdev(kone, event);
876 
877 	return 0; /* always do further processing */
878 }
879 
880 static const struct hid_device_id kone_devices[] = {
881 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
882 	{ }
883 };
884 
885 MODULE_DEVICE_TABLE(hid, kone_devices);
886 
887 static struct hid_driver kone_driver = {
888 		.name = "kone",
889 		.id_table = kone_devices,
890 		.probe = kone_probe,
891 		.remove = kone_remove,
892 		.raw_event = kone_raw_event
893 };
894 
895 static int __init kone_init(void)
896 {
897 	int retval;
898 
899 	/* class name has to be same as driver name */
900 	retval = class_register(&kone_class);
901 	if (retval)
902 		return retval;
903 
904 	retval = hid_register_driver(&kone_driver);
905 	if (retval)
906 		class_unregister(&kone_class);
907 	return retval;
908 }
909 
910 static void __exit kone_exit(void)
911 {
912 	hid_unregister_driver(&kone_driver);
913 	class_unregister(&kone_class);
914 }
915 
916 module_init(kone_init);
917 module_exit(kone_exit);
918 
919 MODULE_AUTHOR("Stefan Achatz");
920 MODULE_DESCRIPTION("USB Roccat Kone driver");
921 MODULE_LICENSE("GPL v2");
922 
923 #if IS_ENABLED(CONFIG_HID_ROCCAT_KONE_KUNIT_TEST)
924 #include <kunit/test.h>
925 
926 /*
927  * Regression test for the out-of-bounds read in
928  * kone_keep_values_up_to_date(): a malicious USB device sends a
929  * "switch profile" HID event (event == kone_mouse_event_switch_profile)
930  * with an attacker-chosen value in 0..255, which is used unbounded as
931  * profiles[value - 1].  On an unpatched kernel the attack case triggers a
932  * KASAN slab-out-of-bounds read; the fix must leave actual_dpi unchanged.
933  */
934 static void kone_profile_index_oob_test(struct kunit *test)
935 {
936 	struct kone_device *kone;
937 	struct kone_mouse_event ev = {};
938 	/*
939 	 * Allocate only up to the end of profiles[] so that any index past
940 	 * the 5-element array is IMMEDIATELY out of bounds and lands in the
941 	 * KASAN redzone (a far over-read would hit unrelated valid memory and
942 	 * escape KASAN).
943 	 */
944 	size_t sz = offsetof(struct kone_device, profiles) +
945 		    sizeof(kone->profiles);
946 
947 	kone = kunit_kzalloc(test, sz, GFP_KERNEL);
948 	KUNIT_ASSERT_NOT_NULL(test, kone);
949 	kone->profiles[0].startup_dpi = 0x42;
950 
951 	/* benign control: a valid in-range value drives the SAME path and
952 	 * must succeed (proves the trigger reaches the real code).
953 	 */
954 	ev.event = kone_mouse_event_switch_profile;
955 	ev.value = 1;
956 	kone_keep_values_up_to_date(kone, &ev);
957 	KUNIT_EXPECT_EQ(test, kone->actual_dpi, 0x42);
958 
959 	/* attack: value == ARRAY_SIZE(profiles) + 1 reads profiles[5], one
960 	 * element past the array end -> KASAN slab-out-of-bounds read on an
961 	 * unpatched kernel. The fix must reject it (actual_dpi unchanged).
962 	 */
963 	ev.value = ARRAY_SIZE(kone->profiles) + 1;
964 	kone_keep_values_up_to_date(kone, &ev);
965 	KUNIT_EXPECT_EQ(test, kone->actual_dpi, 0x42);
966 }
967 
968 static struct kunit_case kone_test_cases[] = {
969 	KUNIT_CASE(kone_profile_index_oob_test),
970 	{}
971 };
972 
973 static struct kunit_suite kone_test_suite = {
974 	.name = "hid-roccat-kone",
975 	.test_cases = kone_test_cases,
976 };
977 kunit_test_suite(kone_test_suite);
978 #endif /* CONFIG_HID_ROCCAT_KONE_KUNIT_TEST */
979