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; |