diff options
| -rw-r--r-- | drivers/hid/uhid.c | 28 | ||||
| -rw-r--r-- | include/uapi/linux/uhid.h | 23 |
2 files changed, 35 insertions, 16 deletions
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 2d2025a027fe..8f5e46b1bb46 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c | |||
| @@ -124,8 +124,8 @@ static int uhid_hid_parse(struct hid_device *hid) | |||
| 124 | return hid_parse_report(hid, uhid->rd_data, uhid->rd_size); | 124 | return hid_parse_report(hid, uhid->rd_data, uhid->rd_size); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum, | 127 | static int uhid_hid_get_report(struct hid_device *hid, unsigned char rnum, |
| 128 | __u8 *buf, size_t count, unsigned char rtype) | 128 | __u8 *buf, size_t count, unsigned char rtype) |
| 129 | { | 129 | { |
| 130 | struct uhid_device *uhid = hid->driver_data; | 130 | struct uhid_device *uhid = hid->driver_data; |
| 131 | __u8 report_type; | 131 | __u8 report_type; |
| @@ -133,7 +133,7 @@ static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum, | |||
| 133 | unsigned long flags; | 133 | unsigned long flags; |
| 134 | int ret; | 134 | int ret; |
| 135 | size_t uninitialized_var(len); | 135 | size_t uninitialized_var(len); |
| 136 | struct uhid_feature_answer_req *req; | 136 | struct uhid_get_report_reply_req *req; |
| 137 | 137 | ||
| 138 | if (!uhid->running) | 138 | if (!uhid->running) |
| 139 | return -EIO; | 139 | return -EIO; |
| @@ -163,10 +163,10 @@ static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum, | |||
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | spin_lock_irqsave(&uhid->qlock, flags); | 165 | spin_lock_irqsave(&uhid->qlock, flags); |
| 166 | ev->type = UHID_FEATURE; | 166 | ev->type = UHID_GET_REPORT; |
| 167 | ev->u.feature.id = ++uhid->report_id; | 167 | ev->u.get_report.id = ++uhid->report_id; |
| 168 | ev->u.feature.rnum = rnum; | 168 | ev->u.get_report.rnum = rnum; |
| 169 | ev->u.feature.rtype = report_type; | 169 | ev->u.get_report.rtype = report_type; |
| 170 | 170 | ||
| 171 | uhid->report_running = true; | 171 | uhid->report_running = true; |
| 172 | uhid_queue(uhid, ev); | 172 | uhid_queue(uhid, ev); |
| @@ -182,7 +182,7 @@ static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum, | |||
| 182 | ret = -ERESTARTSYS; | 182 | ret = -ERESTARTSYS; |
| 183 | } else { | 183 | } else { |
| 184 | spin_lock_irqsave(&uhid->qlock, flags); | 184 | spin_lock_irqsave(&uhid->qlock, flags); |
| 185 | req = &uhid->report_buf.u.feature_answer; | 185 | req = &uhid->report_buf.u.get_report_reply; |
| 186 | 186 | ||
| 187 | if (req->err) { | 187 | if (req->err) { |
| 188 | ret = -EIO; | 188 | ret = -EIO; |
| @@ -253,7 +253,7 @@ static int uhid_raw_request(struct hid_device *hid, unsigned char reportnum, | |||
| 253 | { | 253 | { |
| 254 | switch (reqtype) { | 254 | switch (reqtype) { |
| 255 | case HID_REQ_GET_REPORT: | 255 | case HID_REQ_GET_REPORT: |
| 256 | return uhid_hid_get_raw(hid, reportnum, buf, len, rtype); | 256 | return uhid_hid_get_report(hid, reportnum, buf, len, rtype); |
| 257 | case HID_REQ_SET_REPORT: | 257 | case HID_REQ_SET_REPORT: |
| 258 | /* TODO: implement proper SET_REPORT functionality */ | 258 | /* TODO: implement proper SET_REPORT functionality */ |
| 259 | return -ENOSYS; | 259 | return -ENOSYS; |
| @@ -487,8 +487,8 @@ static int uhid_dev_input2(struct uhid_device *uhid, struct uhid_event *ev) | |||
| 487 | return 0; | 487 | return 0; |
| 488 | } | 488 | } |
| 489 | 489 | ||
| 490 | static int uhid_dev_feature_answer(struct uhid_device *uhid, | 490 | static int uhid_dev_get_report_reply(struct uhid_device *uhid, |
| 491 | struct uhid_event *ev) | 491 | struct uhid_event *ev) |
| 492 | { | 492 | { |
| 493 | unsigned long flags; | 493 | unsigned long flags; |
| 494 | 494 | ||
| @@ -498,7 +498,7 @@ static int uhid_dev_feature_answer(struct uhid_device *uhid, | |||
| 498 | spin_lock_irqsave(&uhid->qlock, flags); | 498 | spin_lock_irqsave(&uhid->qlock, flags); |
| 499 | 499 | ||
| 500 | /* id for old report; drop it silently */ | 500 | /* id for old report; drop it silently */ |
| 501 | if (uhid->report_id != ev->u.feature_answer.id) | 501 | if (uhid->report_id != ev->u.get_report_reply.id) |
| 502 | goto unlock; | 502 | goto unlock; |
| 503 | if (!uhid->report_running) | 503 | if (!uhid->report_running) |
| 504 | goto unlock; | 504 | goto unlock; |
| @@ -634,8 +634,8 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer, | |||
| 634 | case UHID_INPUT2: | 634 | case UHID_INPUT2: |
| 635 | ret = uhid_dev_input2(uhid, &uhid->input_buf); | 635 | ret = uhid_dev_input2(uhid, &uhid->input_buf); |
| 636 | break; | 636 | break; |
| 637 | case UHID_FEATURE_ANSWER: | 637 | case UHID_GET_REPORT_REPLY: |
| 638 | ret = uhid_dev_feature_answer(uhid, &uhid->input_buf); | 638 | ret = uhid_dev_get_report_reply(uhid, &uhid->input_buf); |
| 639 | break; | 639 | break; |
| 640 | default: | 640 | default: |
| 641 | ret = -EOPNOTSUPP; | 641 | ret = -EOPNOTSUPP; |
diff --git a/include/uapi/linux/uhid.h b/include/uapi/linux/uhid.h index 1e3b09c191cd..0a08f2bbe642 100644 --- a/include/uapi/linux/uhid.h +++ b/include/uapi/linux/uhid.h | |||
| @@ -33,8 +33,10 @@ enum uhid_event_type { | |||
| 33 | UHID_OUTPUT, | 33 | UHID_OUTPUT, |
| 34 | UHID_OUTPUT_EV, /* obsolete! */ | 34 | UHID_OUTPUT_EV, /* obsolete! */ |
| 35 | UHID_INPUT, | 35 | UHID_INPUT, |
| 36 | UHID_FEATURE, | 36 | UHID_FEATURE, /* obsolete! use UHID_GET_REPORT */ |
| 37 | UHID_FEATURE_ANSWER, | 37 | UHID_GET_REPORT = UHID_FEATURE, |
| 38 | UHID_FEATURE_ANSWER, /* obsolete! use UHID_GET_REPORT_REPLY */ | ||
| 39 | UHID_GET_REPORT_REPLY = UHID_FEATURE_ANSWER, | ||
| 38 | UHID_CREATE2, | 40 | UHID_CREATE2, |
| 39 | UHID_INPUT2, | 41 | UHID_INPUT2, |
| 40 | }; | 42 | }; |
| @@ -98,12 +100,20 @@ struct uhid_output_ev_req { | |||
| 98 | __s32 value; | 100 | __s32 value; |
| 99 | } __attribute__((__packed__)); | 101 | } __attribute__((__packed__)); |
| 100 | 102 | ||
| 103 | /* Obsolete! Kernel uses ABI compatible UHID_GET_REPORT. */ | ||
| 101 | struct uhid_feature_req { | 104 | struct uhid_feature_req { |
| 102 | __u32 id; | 105 | __u32 id; |
| 103 | __u8 rnum; | 106 | __u8 rnum; |
| 104 | __u8 rtype; | 107 | __u8 rtype; |
| 105 | } __attribute__((__packed__)); | 108 | } __attribute__((__packed__)); |
| 106 | 109 | ||
| 110 | struct uhid_get_report_req { | ||
| 111 | __u32 id; | ||
| 112 | __u8 rnum; | ||
| 113 | __u8 rtype; | ||
| 114 | } __attribute__((__packed__)); | ||
| 115 | |||
| 116 | /* Obsolete! Use ABI compatible UHID_GET_REPORT_REPLY. */ | ||
| 107 | struct uhid_feature_answer_req { | 117 | struct uhid_feature_answer_req { |
| 108 | __u32 id; | 118 | __u32 id; |
| 109 | __u16 err; | 119 | __u16 err; |
| @@ -111,6 +121,13 @@ struct uhid_feature_answer_req { | |||
| 111 | __u8 data[UHID_DATA_MAX]; | 121 | __u8 data[UHID_DATA_MAX]; |
| 112 | } __attribute__((__packed__)); | 122 | } __attribute__((__packed__)); |
| 113 | 123 | ||
| 124 | struct uhid_get_report_reply_req { | ||
| 125 | __u32 id; | ||
| 126 | __u16 err; | ||
| 127 | __u16 size; | ||
| 128 | __u8 data[UHID_DATA_MAX]; | ||
| 129 | } __attribute__((__packed__)); | ||
| 130 | |||
| 114 | struct uhid_event { | 131 | struct uhid_event { |
| 115 | __u32 type; | 132 | __u32 type; |
| 116 | 133 | ||
| @@ -120,7 +137,9 @@ struct uhid_event { | |||
| 120 | struct uhid_output_req output; | 137 | struct uhid_output_req output; |
| 121 | struct uhid_output_ev_req output_ev; | 138 | struct uhid_output_ev_req output_ev; |
| 122 | struct uhid_feature_req feature; | 139 | struct uhid_feature_req feature; |
| 140 | struct uhid_get_report_req get_report; | ||
| 123 | struct uhid_feature_answer_req feature_answer; | 141 | struct uhid_feature_answer_req feature_answer; |
| 142 | struct uhid_get_report_reply_req get_report_reply; | ||
| 124 | struct uhid_create2_req create2; | 143 | struct uhid_create2_req create2; |
| 125 | struct uhid_input2_req input2; | 144 | struct uhid_input2_req input2; |
| 126 | } u; | 145 | } u; |
