diff options
| author | David Herrmann <dh.herrmann@googlemail.com> | 2012-06-10 09:16:25 -0400 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.cz> | 2012-06-18 07:42:03 -0400 |
| commit | fcfcf0deb89ece6eb9ae23768fec1bc1718f9b7f (patch) | |
| tree | fcf86b0c55d4feea91ee00a6e59c423b6442708a /include/linux | |
| parent | 3b3baa82e4306b5160692643fab2fa322ceb94f9 (diff) | |
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>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/uhid.h | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/include/linux/uhid.h b/include/linux/uhid.h index 2c972550a624..9c6974f16966 100644 --- a/include/linux/uhid.h +++ b/include/linux/uhid.h | |||
| @@ -32,6 +32,8 @@ enum uhid_event_type { | |||
| 32 | UHID_OUTPUT, | 32 | UHID_OUTPUT, |
| 33 | UHID_OUTPUT_EV, | 33 | UHID_OUTPUT_EV, |
| 34 | UHID_INPUT, | 34 | UHID_INPUT, |
| 35 | UHID_FEATURE, | ||
| 36 | UHID_FEATURE_ANSWER, | ||
| 35 | }; | 37 | }; |
| 36 | 38 | ||
| 37 | struct uhid_create_req { | 39 | struct uhid_create_req { |
| @@ -73,6 +75,19 @@ struct uhid_output_ev_req { | |||
| 73 | __s32 value; | 75 | __s32 value; |
| 74 | } __attribute__((__packed__)); | 76 | } __attribute__((__packed__)); |
| 75 | 77 | ||
| 78 | struct uhid_feature_req { | ||
| 79 | __u32 id; | ||
| 80 | __u8 rnum; | ||
| 81 | __u8 rtype; | ||
| 82 | } __attribute__((__packed__)); | ||
| 83 | |||
| 84 | struct uhid_feature_answer_req { | ||
| 85 | __u32 id; | ||
| 86 | __u16 err; | ||
| 87 | __u16 size; | ||
| 88 | __u8 data[UHID_DATA_MAX]; | ||
| 89 | }; | ||
| 90 | |||
| 76 | struct uhid_event { | 91 | struct uhid_event { |
| 77 | __u32 type; | 92 | __u32 type; |
| 78 | 93 | ||
| @@ -81,6 +96,8 @@ struct uhid_event { | |||
| 81 | struct uhid_input_req input; | 96 | struct uhid_input_req input; |
| 82 | struct uhid_output_req output; | 97 | struct uhid_output_req output; |
| 83 | struct uhid_output_ev_req output_ev; | 98 | struct uhid_output_ev_req output_ev; |
| 99 | struct uhid_feature_req feature; | ||
| 100 | struct uhid_feature_answer_req feature_answer; | ||
| 84 | } u; | 101 | } u; |
| 85 | } __attribute__((__packed__)); | 102 | } __attribute__((__packed__)); |
| 86 | 103 | ||
