HID: uhid: implement feature requests
HID standard allows sending a feature request to the device which is
answered by an HID report. uhid implements this by sending a UHID_FEATURE
event to user-space which then must answer with UHID_FEATURE_ANSWER. If it
doesn't do this in a timely manner, the request is discarded silently.
We serialize the feature requests, that is, there is always only a single
active feature-request sent to user-space, other requests have to wait.
HIDP and USB-HID do it the same way.
Because we discard feature-requests silently, we must make sure to match
a response to the corresponding request. We use sequence-IDs for this so
user-space must copy the ID from the request into the answer.
Feature-answers are ignored if they do not contain the same ID as the
currently pending feature request.
Internally, we must make sure that feature-requests are synchronized with
UHID_DESTROY and close() events. We must not dead-lock when closing the
HID device, either, so we have to use separate locks.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
diff --git a/include/linux/uhid.h b/include/linux/uhid.h
index 2c97255..9c6974f 100644
--- a/include/linux/uhid.h
+++ b/include/linux/uhid.h
@@ -32,6 +32,8 @@
UHID_OUTPUT,
UHID_OUTPUT_EV,
UHID_INPUT,
+ UHID_FEATURE,
+ UHID_FEATURE_ANSWER,
};
struct uhid_create_req {
@@ -73,6 +75,19 @@
__s32 value;
} __attribute__((__packed__));
+struct uhid_feature_req {
+ __u32 id;
+ __u8 rnum;
+ __u8 rtype;
+} __attribute__((__packed__));
+
+struct uhid_feature_answer_req {
+ __u32 id;
+ __u16 err;
+ __u16 size;
+ __u8 data[UHID_DATA_MAX];
+};
+
struct uhid_event {
__u32 type;
@@ -81,6 +96,8 @@
struct uhid_input_req input;
struct uhid_output_req output;
struct uhid_output_ev_req output_ev;
+ struct uhid_feature_req feature;
+ struct uhid_feature_answer_req feature_answer;
} u;
} __attribute__((__packed__));