Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

HID: uhid: Add UHID_CREATE2 + UHID_INPUT2

UHID_CREATE2:
HID report descriptor data (rd_data) is an array in struct uhid_create2_req,
instead of a pointer. Enables use from languages that don't support pointers,
e.g. Python.

UHID_INPUT2:
Data array is the last field of struct uhid_input2_req. Enables userspace to
write only the required bytes to kernel (ev.type + ev.u.input2.size + the part
of the data array that matters), instead of the entire struct uhid_input2_req.

Note:
UHID_CREATE2 increases the total size of struct uhid_event slightly, thus
increasing the size of messages that are queued for userspace. However, this
won't affect the userspace processing of these events.

[Jiri Kosina <jkosina@suse.cz>: adjust to hid_get_raw_report() and
hid_output_raw_report() API changes]

Signed-off-by: Petri Gynther <pgynther@google.com>
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

authored by

Petri Gynther and committed by
Jiri Kosina
4522643a c3d77fab

+112
+11
Documentation/hid/uhid.txt
··· 93 93 event to the kernel. The payload is of type struct uhid_create_req and 94 94 contains information about your device. You can start I/O now. 95 95 96 + UHID_CREATE2: 97 + Same as UHID_CREATE, but the HID report descriptor data (rd_data) is an array 98 + inside struct uhid_create2_req, instead of a pointer to a separate array. 99 + Enables use from languages that don't support pointers, e.g. Python. 100 + 96 101 UHID_DESTROY: 97 102 This destroys the internal HID device. No further I/O will be accepted. There 98 103 may still be pending messages that you can receive with read() but no further ··· 109 104 You must send UHID_CREATE before sending input to the kernel! This event 110 105 contains a data-payload. This is the raw data that you read from your device. 111 106 The kernel will parse the HID reports and react on it. 107 + 108 + UHID_INPUT2: 109 + Same as UHID_INPUT, but the data array is the last field of uhid_input2_req. 110 + Enables userspace to write only the required bytes to kernel (ev.type + 111 + ev.u.input2.size + the part of the data array that matters), instead of 112 + the entire struct uhid_input2_req. 112 113 113 114 UHID_FEATURE_ANSWER: 114 115 If you receive a UHID_FEATURE request you must answer with this request. You
+78
drivers/hid/uhid.c
··· 428 428 return ret; 429 429 } 430 430 431 + static int uhid_dev_create2(struct uhid_device *uhid, 432 + const struct uhid_event *ev) 433 + { 434 + struct hid_device *hid; 435 + int ret; 436 + 437 + if (uhid->running) 438 + return -EALREADY; 439 + 440 + uhid->rd_size = ev->u.create2.rd_size; 441 + if (uhid->rd_size <= 0 || uhid->rd_size > HID_MAX_DESCRIPTOR_SIZE) 442 + return -EINVAL; 443 + 444 + uhid->rd_data = kmalloc(uhid->rd_size, GFP_KERNEL); 445 + if (!uhid->rd_data) 446 + return -ENOMEM; 447 + 448 + memcpy(uhid->rd_data, ev->u.create2.rd_data, uhid->rd_size); 449 + 450 + hid = hid_allocate_device(); 451 + if (IS_ERR(hid)) { 452 + ret = PTR_ERR(hid); 453 + goto err_free; 454 + } 455 + 456 + strncpy(hid->name, ev->u.create2.name, 127); 457 + hid->name[127] = 0; 458 + strncpy(hid->phys, ev->u.create2.phys, 63); 459 + hid->phys[63] = 0; 460 + strncpy(hid->uniq, ev->u.create2.uniq, 63); 461 + hid->uniq[63] = 0; 462 + 463 + hid->ll_driver = &uhid_hid_driver; 464 + hid->bus = ev->u.create2.bus; 465 + hid->vendor = ev->u.create2.vendor; 466 + hid->product = ev->u.create2.product; 467 + hid->version = ev->u.create2.version; 468 + hid->country = ev->u.create2.country; 469 + hid->driver_data = uhid; 470 + hid->dev.parent = uhid_misc.this_device; 471 + 472 + uhid->hid = hid; 473 + uhid->running = true; 474 + 475 + ret = hid_add_device(hid); 476 + if (ret) { 477 + hid_err(hid, "Cannot register HID device\n"); 478 + goto err_hid; 479 + } 480 + 481 + return 0; 482 + 483 + err_hid: 484 + hid_destroy_device(hid); 485 + uhid->hid = NULL; 486 + uhid->running = false; 487 + err_free: 488 + kfree(uhid->rd_data); 489 + return ret; 490 + } 491 + 431 492 static int uhid_dev_destroy(struct uhid_device *uhid) 432 493 { 433 494 if (!uhid->running) ··· 513 452 514 453 hid_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input.data, 515 454 min_t(size_t, ev->u.input.size, UHID_DATA_MAX), 0); 455 + 456 + return 0; 457 + } 458 + 459 + static int uhid_dev_input2(struct uhid_device *uhid, struct uhid_event *ev) 460 + { 461 + if (!uhid->running) 462 + return -EINVAL; 463 + 464 + hid_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input2.data, 465 + min_t(size_t, ev->u.input2.size, UHID_DATA_MAX), 0); 516 466 517 467 return 0; 518 468 } ··· 664 592 case UHID_CREATE: 665 593 ret = uhid_dev_create(uhid, &uhid->input_buf); 666 594 break; 595 + case UHID_CREATE2: 596 + ret = uhid_dev_create2(uhid, &uhid->input_buf); 597 + break; 667 598 case UHID_DESTROY: 668 599 ret = uhid_dev_destroy(uhid); 669 600 break; 670 601 case UHID_INPUT: 671 602 ret = uhid_dev_input(uhid, &uhid->input_buf); 603 + break; 604 + case UHID_INPUT2: 605 + ret = uhid_dev_input2(uhid, &uhid->input_buf); 672 606 break; 673 607 case UHID_FEATURE_ANSWER: 674 608 ret = uhid_dev_feature_answer(uhid, &uhid->input_buf);
+23
include/uapi/linux/uhid.h
··· 21 21 22 22 #include <linux/input.h> 23 23 #include <linux/types.h> 24 + #include <linux/hid.h> 24 25 25 26 enum uhid_event_type { 26 27 UHID_CREATE, ··· 35 34 UHID_INPUT, 36 35 UHID_FEATURE, 37 36 UHID_FEATURE_ANSWER, 37 + UHID_CREATE2, 38 + UHID_INPUT2, 38 39 }; 39 40 40 41 struct uhid_create_req { ··· 53 50 __u32 country; 54 51 } __attribute__((__packed__)); 55 52 53 + struct uhid_create2_req { 54 + __u8 name[128]; 55 + __u8 phys[64]; 56 + __u8 uniq[64]; 57 + __u16 rd_size; 58 + __u16 bus; 59 + __u32 vendor; 60 + __u32 product; 61 + __u32 version; 62 + __u32 country; 63 + __u8 rd_data[HID_MAX_DESCRIPTOR_SIZE]; 64 + } __attribute__((__packed__)); 65 + 56 66 #define UHID_DATA_MAX 4096 57 67 58 68 enum uhid_report_type { ··· 77 61 struct uhid_input_req { 78 62 __u8 data[UHID_DATA_MAX]; 79 63 __u16 size; 64 + } __attribute__((__packed__)); 65 + 66 + struct uhid_input2_req { 67 + __u16 size; 68 + __u8 data[UHID_DATA_MAX]; 80 69 } __attribute__((__packed__)); 81 70 82 71 struct uhid_output_req { ··· 121 100 struct uhid_output_ev_req output_ev; 122 101 struct uhid_feature_req feature; 123 102 struct uhid_feature_answer_req feature_answer; 103 + struct uhid_create2_req create2; 104 + struct uhid_input2_req input2; 124 105 } u; 125 106 } __attribute__((__packed__)); 126 107