aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/uhid.c28
-rw-r--r--include/uapi/linux/uhid.h23
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
127static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum, 127static 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
490static int uhid_dev_feature_answer(struct uhid_device *uhid, 490static 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. */
101struct uhid_feature_req { 104struct 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
110struct 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. */
107struct uhid_feature_answer_req { 117struct 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
124struct uhid_get_report_reply_req {
125 __u32 id;
126 __u16 err;
127 __u16 size;
128 __u8 data[UHID_DATA_MAX];
129} __attribute__((__packed__));
130
114struct uhid_event { 131struct 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;