aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2012-07-24 07:40:06 -0400
committerJiri Kosina <jkosina@suse.cz>2012-07-24 07:40:06 -0400
commitc062c4d1de57789bf15f7641a24c429eeb8a1c6a (patch)
treedfd376034ea8458689c937dafa5e318892af82af
parent929bd380b7aec9f9553b6509af86cdba25e334b8 (diff)
parentadefb69b1b94df29ea2df05cd838c0e032b2c473 (diff)
Merge branch 'uhid' into for-linus
Conflicts: drivers/hid/Kconfig
-rw-r--r--Documentation/hid/uhid.txt169
-rw-r--r--MAINTAINERS7
-rw-r--r--drivers/hid/Kconfig21
-rw-r--r--drivers/hid/Makefile1
-rw-r--r--drivers/hid/uhid.c572
-rw-r--r--include/linux/Kbuild1
-rw-r--r--include/linux/uhid.h104
-rw-r--r--samples/uhid/Makefile10
-rw-r--r--samples/uhid/uhid-example.c381
9 files changed, 1266 insertions, 0 deletions
diff --git a/Documentation/hid/uhid.txt b/Documentation/hid/uhid.txt
new file mode 100644
index 000000000000..4627c4241ece
--- /dev/null
+++ b/Documentation/hid/uhid.txt
@@ -0,0 +1,169 @@
1 UHID - User-space I/O driver support for HID subsystem
2 ========================================================
3
4The HID subsystem needs two kinds of drivers. In this document we call them:
5
6 1. The "HID I/O Driver" is the driver that performs raw data I/O to the
7 low-level device. Internally, they register an hid_ll_driver structure with
8 the HID core. They perform device setup, read raw data from the device and
9 push it into the HID subsystem and they provide a callback so the HID
10 subsystem can send data to the device.
11
12 2. The "HID Device Driver" is the driver that parses HID reports and reacts on
13 them. There are generic drivers like "generic-usb" and "generic-bluetooth"
14 which adhere to the HID specification and provide the standardizes features.
15 But there may be special drivers and quirks for each non-standard device out
16 there. Internally, they use the hid_driver structure.
17
18Historically, the USB stack was the first subsystem to provide an HID I/O
19Driver. However, other standards like Bluetooth have adopted the HID specs and
20may provide HID I/O Drivers, too. The UHID driver allows to implement HID I/O
21Drivers in user-space and feed the data into the kernel HID-subsystem.
22
23This allows user-space to operate on the same level as USB-HID, Bluetooth-HID
24and similar. It does not provide a way to write HID Device Drivers, though. Use
25hidraw for this purpose.
26
27There is an example user-space application in ./samples/uhid/uhid-example.c
28
29The UHID API
30------------
31
32UHID is accessed through a character misc-device. The minor-number is allocated
33dynamically so you need to rely on udev (or similar) to create the device node.
34This is /dev/uhid by default.
35
36If a new device is detected by your HID I/O Driver and you want to register this
37device with the HID subsystem, then you need to open /dev/uhid once for each
38device you want to register. All further communication is done by read()'ing or
39write()'ing "struct uhid_event" objects. Non-blocking operations are supported
40by setting O_NONBLOCK.
41
42struct uhid_event {
43 __u32 type;
44 union {
45 struct uhid_create_req create;
46 struct uhid_data_req data;
47 ...
48 } u;
49};
50
51The "type" field contains the ID of the event. Depending on the ID different
52payloads are sent. You must not split a single event across multiple read()'s or
53multiple write()'s. A single event must always be sent as a whole. Furthermore,
54only a single event can be sent per read() or write(). Pending data is ignored.
55If you want to handle multiple events in a single syscall, then use vectored
56I/O with readv()/writev().
57
58The first thing you should do is sending an UHID_CREATE event. This will
59register the device. UHID will respond with an UHID_START event. You can now
60start sending data to and reading data from UHID. However, unless UHID sends the
61UHID_OPEN event, the internally attached HID Device Driver has no user attached.
62That is, you might put your device asleep unless you receive the UHID_OPEN
63event. If you receive the UHID_OPEN event, you should start I/O. If the last
64user closes the HID device, you will receive an UHID_CLOSE event. This may be
65followed by an UHID_OPEN event again and so on. There is no need to perform
66reference-counting in user-space. That is, you will never receive multiple
67UHID_OPEN events without an UHID_CLOSE event. The HID subsystem performs
68ref-counting for you.
69You may decide to ignore UHID_OPEN/UHID_CLOSE, though. I/O is allowed even
70though the device may have no users.
71
72If you want to send data to the HID subsystem, you send an HID_INPUT event with
73your raw data payload. If the kernel wants to send data to the device, you will
74read an UHID_OUTPUT or UHID_OUTPUT_EV event.
75
76If your device disconnects, you should send an UHID_DESTROY event. This will
77unregister the device. You can now send UHID_CREATE again to register a new
78device.
79If you close() the fd, the device is automatically unregistered and destroyed
80internally.
81
82write()
83-------
84write() allows you to modify the state of the device and feed input data into
85the kernel. The following types are supported: UHID_CREATE, UHID_DESTROY and
86UHID_INPUT. The kernel will parse the event immediately and if the event ID is
87not supported, it will return -EOPNOTSUPP. If the payload is invalid, then
88-EINVAL is returned, otherwise, the amount of data that was read is returned and
89the request was handled successfully.
90
91 UHID_CREATE:
92 This creates the internal HID device. No I/O is possible until you send this
93 event to the kernel. The payload is of type struct uhid_create_req and
94 contains information about your device. You can start I/O now.
95
96 UHID_DESTROY:
97 This destroys the internal HID device. No further I/O will be accepted. There
98 may still be pending messages that you can receive with read() but no further
99 UHID_INPUT events can be sent to the kernel.
100 You can create a new device by sending UHID_CREATE again. There is no need to
101 reopen the character device.
102
103 UHID_INPUT:
104 You must send UHID_CREATE before sending input to the kernel! This event
105 contains a data-payload. This is the raw data that you read from your device.
106 The kernel will parse the HID reports and react on it.
107
108 UHID_FEATURE_ANSWER:
109 If you receive a UHID_FEATURE request you must answer with this request. You
110 must copy the "id" field from the request into the answer. Set the "err" field
111 to 0 if no error occured or to EIO if an I/O error occurred.
112 If "err" is 0 then you should fill the buffer of the answer with the results
113 of the feature request and set "size" correspondingly.
114
115read()
116------
117read() will return a queued ouput report. These output reports can be of type
118UHID_START, UHID_STOP, UHID_OPEN, UHID_CLOSE, UHID_OUTPUT or UHID_OUTPUT_EV. No
119reaction is required to any of them but you should handle them according to your
120needs. Only UHID_OUTPUT and UHID_OUTPUT_EV have payloads.
121
122 UHID_START:
123 This is sent when the HID device is started. Consider this as an answer to
124 UHID_CREATE. This is always the first event that is sent.
125
126 UHID_STOP:
127 This is sent when the HID device is stopped. Consider this as an answer to
128 UHID_DESTROY.
129 If the kernel HID device driver closes the device manually (that is, you
130 didn't send UHID_DESTROY) then you should consider this device closed and send
131 an UHID_DESTROY event. You may want to reregister your device, though. This is
132 always the last message that is sent to you unless you reopen the device with
133 UHID_CREATE.
134
135 UHID_OPEN:
136 This is sent when the HID device is opened. That is, the data that the HID
137 device provides is read by some other process. You may ignore this event but
138 it is useful for power-management. As long as you haven't received this event
139 there is actually no other process that reads your data so there is no need to
140 send UHID_INPUT events to the kernel.
141
142 UHID_CLOSE:
143 This is sent when there are no more processes which read the HID data. It is
144 the counterpart of UHID_OPEN and you may as well ignore this event.
145
146 UHID_OUTPUT:
147 This is sent if the HID device driver wants to send raw data to the I/O
148 device. You should read the payload and forward it to the device. The payload
149 is of type "struct uhid_data_req".
150 This may be received even though you haven't received UHID_OPEN, yet.
151
152 UHID_OUTPUT_EV:
153 Same as UHID_OUTPUT but this contains a "struct input_event" as payload. This
154 is called for force-feedback, LED or similar events which are received through
155 an input device by the HID subsystem. You should convert this into raw reports
156 and send them to your device similar to events of type UHID_OUTPUT.
157
158 UHID_FEATURE:
159 This event is sent if the kernel driver wants to perform a feature request as
160 described in the HID specs. The report-type and report-number are available in
161 the payload.
162 The kernel serializes feature requests so there will never be two in parallel.
163 However, if you fail to respond with a UHID_FEATURE_ANSWER in a time-span of 5
164 seconds, then the requests will be dropped and a new one might be sent.
165 Therefore, the payload also contains an "id" field that identifies every
166 request.
167
168Document by:
169 David Herrmann <dh.herrmann@googlemail.com>
diff --git a/MAINTAINERS b/MAINTAINERS
index c82c343168e8..12dde1f795dd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6948,6 +6948,13 @@ S: Maintained
6948F: Documentation/filesystems/ufs.txt 6948F: Documentation/filesystems/ufs.txt
6949F: fs/ufs/ 6949F: fs/ufs/
6950 6950
6951UHID USERSPACE HID IO DRIVER:
6952M: David Herrmann <dh.herrmann@googlemail.com>
6953L: linux-input@vger.kernel.org
6954S: Maintained
6955F: drivers/hid/uhid.c
6956F: include/linux/uhid.h
6957
6951ULTRA-WIDEBAND (UWB) SUBSYSTEM: 6958ULTRA-WIDEBAND (UWB) SUBSYSTEM:
6952L: linux-usb@vger.kernel.org 6959L: linux-usb@vger.kernel.org
6953S: Orphan 6960S: Orphan
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 00445bc3019c..fbf49503508d 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -53,6 +53,27 @@ config HIDRAW
53 53
54 If unsure, say Y. 54 If unsure, say Y.
55 55
56config UHID
57 tristate "User-space I/O driver support for HID subsystem"
58 depends on HID
59 default n
60 ---help---
61 Say Y here if you want to provide HID I/O Drivers from user-space.
62 This allows to write I/O drivers in user-space and feed the data from
63 the device into the kernel. The kernel parses the HID reports, loads the
64 corresponding HID Device Driver or provides input devices on top of your
65 user-space device.
66
67 This driver cannot be used to parse HID-reports in user-space and write
68 special HID-drivers. You should use hidraw for that.
69 Instead, this driver allows to write the transport-layer driver in
70 user-space like USB-HID and Bluetooth-HID do in kernel-space.
71
72 If unsure, say N.
73
74 To compile this driver as a module, choose M here: the
75 module will be called uhid.
76
56config HID_GENERIC 77config HID_GENERIC
57 tristate "Generic HID driver" 78 tristate "Generic HID driver"
58 depends on HID 79 depends on HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 02fa93896951..f975485f88b2 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -8,6 +8,7 @@ ifdef CONFIG_DEBUG_FS
8endif 8endif
9 9
10obj-$(CONFIG_HID) += hid.o 10obj-$(CONFIG_HID) += hid.o
11obj-$(CONFIG_UHID) += uhid.o
11 12
12obj-$(CONFIG_HID_GENERIC) += hid-generic.o 13obj-$(CONFIG_HID_GENERIC) += hid-generic.o
13 14
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
new file mode 100644
index 000000000000..714cd8cc9579
--- /dev/null
+++ b/drivers/hid/uhid.c
@@ -0,0 +1,572 @@
1/*
2 * User-space I/O driver support for HID subsystem
3 * Copyright (c) 2012 David Herrmann
4 */
5
6/*
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 */
12
13#include <linux/atomic.h>
14#include <linux/device.h>
15#include <linux/fs.h>
16#include <linux/hid.h>
17#include <linux/input.h>
18#include <linux/miscdevice.h>
19#include <linux/module.h>
20#include <linux/mutex.h>
21#include <linux/poll.h>
22#include <linux/sched.h>
23#include <linux/spinlock.h>
24#include <linux/uhid.h>
25#include <linux/wait.h>
26
27#define UHID_NAME "uhid"
28#define UHID_BUFSIZE 32
29
30struct uhid_device {
31 struct mutex devlock;
32 bool running;
33
34 __u8 *rd_data;
35 uint rd_size;
36
37 struct hid_device *hid;
38 struct uhid_event input_buf;
39
40 wait_queue_head_t waitq;
41 spinlock_t qlock;
42 __u8 head;
43 __u8 tail;
44 struct uhid_event *outq[UHID_BUFSIZE];
45
46 struct mutex report_lock;
47 wait_queue_head_t report_wait;
48 atomic_t report_done;
49 atomic_t report_id;
50 struct uhid_event report_buf;
51};
52
53static struct miscdevice uhid_misc;
54
55static void uhid_queue(struct uhid_device *uhid, struct uhid_event *ev)
56{
57 __u8 newhead;
58
59 newhead = (uhid->head + 1) % UHID_BUFSIZE;
60
61 if (newhead != uhid->tail) {
62 uhid->outq[uhid->head] = ev;
63 uhid->head = newhead;
64 wake_up_interruptible(&uhid->waitq);
65 } else {
66 hid_warn(uhid->hid, "Output queue is full\n");
67 kfree(ev);
68 }
69}
70
71static int uhid_queue_event(struct uhid_device *uhid, __u32 event)
72{
73 unsigned long flags;
74 struct uhid_event *ev;
75
76 ev = kzalloc(sizeof(*ev), GFP_KERNEL);
77 if (!ev)
78 return -ENOMEM;
79
80 ev->type = event;
81
82 spin_lock_irqsave(&uhid->qlock, flags);
83 uhid_queue(uhid, ev);
84 spin_unlock_irqrestore(&uhid->qlock, flags);
85
86 return 0;
87}
88
89static int uhid_hid_start(struct hid_device *hid)
90{
91 struct uhid_device *uhid = hid->driver_data;
92
93 return uhid_queue_event(uhid, UHID_START);
94}
95
96static void uhid_hid_stop(struct hid_device *hid)
97{
98 struct uhid_device *uhid = hid->driver_data;
99
100 hid->claimed = 0;
101 uhid_queue_event(uhid, UHID_STOP);
102}
103
104static int uhid_hid_open(struct hid_device *hid)
105{
106 struct uhid_device *uhid = hid->driver_data;
107
108 return uhid_queue_event(uhid, UHID_OPEN);
109}
110
111static void uhid_hid_close(struct hid_device *hid)
112{
113 struct uhid_device *uhid = hid->driver_data;
114
115 uhid_queue_event(uhid, UHID_CLOSE);
116}
117
118static int uhid_hid_input(struct input_dev *input, unsigned int type,
119 unsigned int code, int value)
120{
121 struct hid_device *hid = input_get_drvdata(input);
122 struct uhid_device *uhid = hid->driver_data;
123 unsigned long flags;
124 struct uhid_event *ev;
125
126 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
127 if (!ev)
128 return -ENOMEM;
129
130 ev->type = UHID_OUTPUT_EV;
131 ev->u.output_ev.type = type;
132 ev->u.output_ev.code = code;
133 ev->u.output_ev.value = value;
134
135 spin_lock_irqsave(&uhid->qlock, flags);
136 uhid_queue(uhid, ev);
137 spin_unlock_irqrestore(&uhid->qlock, flags);
138
139 return 0;
140}
141
142static int uhid_hid_parse(struct hid_device *hid)
143{
144 struct uhid_device *uhid = hid->driver_data;
145
146 return hid_parse_report(hid, uhid->rd_data, uhid->rd_size);
147}
148
149static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum,
150 __u8 *buf, size_t count, unsigned char rtype)
151{
152 struct uhid_device *uhid = hid->driver_data;
153 __u8 report_type;
154 struct uhid_event *ev;
155 unsigned long flags;
156 int ret;
157 size_t uninitialized_var(len);
158 struct uhid_feature_answer_req *req;
159
160 if (!uhid->running)
161 return -EIO;
162
163 switch (rtype) {
164 case HID_FEATURE_REPORT:
165 report_type = UHID_FEATURE_REPORT;
166 break;
167 case HID_OUTPUT_REPORT:
168 report_type = UHID_OUTPUT_REPORT;
169 break;
170 case HID_INPUT_REPORT:
171 report_type = UHID_INPUT_REPORT;
172 break;
173 default:
174 return -EINVAL;
175 }
176
177 ret = mutex_lock_interruptible(&uhid->report_lock);
178 if (ret)
179 return ret;
180
181 ev = kzalloc(sizeof(*ev), GFP_KERNEL);
182 if (!ev) {
183 ret = -ENOMEM;
184 goto unlock;
185 }
186
187 spin_lock_irqsave(&uhid->qlock, flags);
188 ev->type = UHID_FEATURE;
189 ev->u.feature.id = atomic_inc_return(&uhid->report_id);
190 ev->u.feature.rnum = rnum;
191 ev->u.feature.rtype = report_type;
192
193 atomic_set(&uhid->report_done, 0);
194 uhid_queue(uhid, ev);
195 spin_unlock_irqrestore(&uhid->qlock, flags);
196
197 ret = wait_event_interruptible_timeout(uhid->report_wait,
198 atomic_read(&uhid->report_done), 5 * HZ);
199
200 /*
201 * Make sure "uhid->running" is cleared on shutdown before
202 * "uhid->report_done" is set.
203 */
204 smp_rmb();
205 if (!ret || !uhid->running) {
206 ret = -EIO;
207 } else if (ret < 0) {
208 ret = -ERESTARTSYS;
209 } else {
210 spin_lock_irqsave(&uhid->qlock, flags);
211 req = &uhid->report_buf.u.feature_answer;
212
213 if (req->err) {
214 ret = -EIO;
215 } else {
216 ret = 0;
217 len = min(count,
218 min_t(size_t, req->size, UHID_DATA_MAX));
219 memcpy(buf, req->data, len);
220 }
221
222 spin_unlock_irqrestore(&uhid->qlock, flags);
223 }
224
225 atomic_set(&uhid->report_done, 1);
226
227unlock:
228 mutex_unlock(&uhid->report_lock);
229 return ret ? ret : len;
230}
231
232static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count,
233 unsigned char report_type)
234{
235 struct uhid_device *uhid = hid->driver_data;
236 __u8 rtype;
237 unsigned long flags;
238 struct uhid_event *ev;
239
240 switch (report_type) {
241 case HID_FEATURE_REPORT:
242 rtype = UHID_FEATURE_REPORT;
243 break;
244 case HID_OUTPUT_REPORT:
245 rtype = UHID_OUTPUT_REPORT;
246 break;
247 default:
248 return -EINVAL;
249 }
250
251 if (count < 1 || count > UHID_DATA_MAX)
252 return -EINVAL;
253
254 ev = kzalloc(sizeof(*ev), GFP_KERNEL);
255 if (!ev)
256 return -ENOMEM;
257
258 ev->type = UHID_OUTPUT;
259 ev->u.output.size = count;
260 ev->u.output.rtype = rtype;
261 memcpy(ev->u.output.data, buf, count);
262
263 spin_lock_irqsave(&uhid->qlock, flags);
264 uhid_queue(uhid, ev);
265 spin_unlock_irqrestore(&uhid->qlock, flags);
266
267 return count;
268}
269
270static struct hid_ll_driver uhid_hid_driver = {
271 .start = uhid_hid_start,
272 .stop = uhid_hid_stop,
273 .open = uhid_hid_open,
274 .close = uhid_hid_close,
275 .hidinput_input_event = uhid_hid_input,
276 .parse = uhid_hid_parse,
277};
278
279static int uhid_dev_create(struct uhid_device *uhid,
280 const struct uhid_event *ev)
281{
282 struct hid_device *hid;
283 int ret;
284
285 if (uhid->running)
286 return -EALREADY;
287
288 uhid->rd_size = ev->u.create.rd_size;
289 if (uhid->rd_size <= 0 || uhid->rd_size > HID_MAX_DESCRIPTOR_SIZE)
290 return -EINVAL;
291
292 uhid->rd_data = kmalloc(uhid->rd_size, GFP_KERNEL);
293 if (!uhid->rd_data)
294 return -ENOMEM;
295
296 if (copy_from_user(uhid->rd_data, ev->u.create.rd_data,
297 uhid->rd_size)) {
298 ret = -EFAULT;
299 goto err_free;
300 }
301
302 hid = hid_allocate_device();
303 if (IS_ERR(hid)) {
304 ret = PTR_ERR(hid);
305 goto err_free;
306 }
307
308 strncpy(hid->name, ev->u.create.name, 127);
309 hid->name[127] = 0;
310 strncpy(hid->phys, ev->u.create.phys, 63);
311 hid->phys[63] = 0;
312 strncpy(hid->uniq, ev->u.create.uniq, 63);
313 hid->uniq[63] = 0;
314
315 hid->ll_driver = &uhid_hid_driver;
316 hid->hid_get_raw_report = uhid_hid_get_raw;
317 hid->hid_output_raw_report = uhid_hid_output_raw;
318 hid->bus = ev->u.create.bus;
319 hid->vendor = ev->u.create.vendor;
320 hid->product = ev->u.create.product;
321 hid->version = ev->u.create.version;
322 hid->country = ev->u.create.country;
323 hid->driver_data = uhid;
324 hid->dev.parent = uhid_misc.this_device;
325
326 uhid->hid = hid;
327 uhid->running = true;
328
329 ret = hid_add_device(hid);
330 if (ret) {
331 hid_err(hid, "Cannot register HID device\n");
332 goto err_hid;
333 }
334
335 return 0;
336
337err_hid:
338 hid_destroy_device(hid);
339 uhid->hid = NULL;
340 uhid->running = false;
341err_free:
342 kfree(uhid->rd_data);
343 return ret;
344}
345
346static int uhid_dev_destroy(struct uhid_device *uhid)
347{
348 if (!uhid->running)
349 return -EINVAL;
350
351 /* clear "running" before setting "report_done" */
352 uhid->running = false;
353 smp_wmb();
354 atomic_set(&uhid->report_done, 1);
355 wake_up_interruptible(&uhid->report_wait);
356
357 hid_destroy_device(uhid->hid);
358 kfree(uhid->rd_data);
359
360 return 0;
361}
362
363static int uhid_dev_input(struct uhid_device *uhid, struct uhid_event *ev)
364{
365 if (!uhid->running)
366 return -EINVAL;
367
368 hid_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input.data,
369 min_t(size_t, ev->u.input.size, UHID_DATA_MAX), 0);
370
371 return 0;
372}
373
374static int uhid_dev_feature_answer(struct uhid_device *uhid,
375 struct uhid_event *ev)
376{
377 unsigned long flags;
378
379 if (!uhid->running)
380 return -EINVAL;
381
382 spin_lock_irqsave(&uhid->qlock, flags);
383
384 /* id for old report; drop it silently */
385 if (atomic_read(&uhid->report_id) != ev->u.feature_answer.id)
386 goto unlock;
387 if (atomic_read(&uhid->report_done))
388 goto unlock;
389
390 memcpy(&uhid->report_buf, ev, sizeof(*ev));
391 atomic_set(&uhid->report_done, 1);
392 wake_up_interruptible(&uhid->report_wait);
393
394unlock:
395 spin_unlock_irqrestore(&uhid->qlock, flags);
396 return 0;
397}
398
399static int uhid_char_open(struct inode *inode, struct file *file)
400{
401 struct uhid_device *uhid;
402
403 uhid = kzalloc(sizeof(*uhid), GFP_KERNEL);
404 if (!uhid)
405 return -ENOMEM;
406
407 mutex_init(&uhid->devlock);
408 mutex_init(&uhid->report_lock);
409 spin_lock_init(&uhid->qlock);
410 init_waitqueue_head(&uhid->waitq);
411 init_waitqueue_head(&uhid->report_wait);
412 uhid->running = false;
413 atomic_set(&uhid->report_done, 1);
414
415 file->private_data = uhid;
416 nonseekable_open(inode, file);
417
418 return 0;
419}
420
421static int uhid_char_release(struct inode *inode, struct file *file)
422{
423 struct uhid_device *uhid = file->private_data;
424 unsigned int i;
425
426 uhid_dev_destroy(uhid);
427
428 for (i = 0; i < UHID_BUFSIZE; ++i)
429 kfree(uhid->outq[i]);
430
431 kfree(uhid);
432
433 return 0;
434}
435
436static ssize_t uhid_char_read(struct file *file, char __user *buffer,
437 size_t count, loff_t *ppos)
438{
439 struct uhid_device *uhid = file->private_data;
440 int ret;
441 unsigned long flags;
442 size_t len;
443
444 /* they need at least the "type" member of uhid_event */
445 if (count < sizeof(__u32))
446 return -EINVAL;
447
448try_again:
449 if (file->f_flags & O_NONBLOCK) {
450 if (uhid->head == uhid->tail)
451 return -EAGAIN;
452 } else {
453 ret = wait_event_interruptible(uhid->waitq,
454 uhid->head != uhid->tail);
455 if (ret)
456 return ret;
457 }
458
459 ret = mutex_lock_interruptible(&uhid->devlock);
460 if (ret)
461 return ret;
462
463 if (uhid->head == uhid->tail) {
464 mutex_unlock(&uhid->devlock);
465 goto try_again;
466 } else {
467 len = min(count, sizeof(**uhid->outq));
468 if (copy_to_user(buffer, uhid->outq[uhid->tail], len)) {
469 ret = -EFAULT;
470 } else {
471 kfree(uhid->outq[uhid->tail]);
472 uhid->outq[uhid->tail] = NULL;
473
474 spin_lock_irqsave(&uhid->qlock, flags);
475 uhid->tail = (uhid->tail + 1) % UHID_BUFSIZE;
476 spin_unlock_irqrestore(&uhid->qlock, flags);
477 }
478 }
479
480 mutex_unlock(&uhid->devlock);
481 return ret ? ret : len;
482}
483
484static ssize_t uhid_char_write(struct file *file, const char __user *buffer,
485 size_t count, loff_t *ppos)
486{
487 struct uhid_device *uhid = file->private_data;
488 int ret;
489 size_t len;
490
491 /* we need at least the "type" member of uhid_event */
492 if (count < sizeof(__u32))
493 return -EINVAL;
494
495 ret = mutex_lock_interruptible(&uhid->devlock);
496 if (ret)
497 return ret;
498
499 memset(&uhid->input_buf, 0, sizeof(uhid->input_buf));
500 len = min(count, sizeof(uhid->input_buf));
501 if (copy_from_user(&uhid->input_buf, buffer, len)) {
502 ret = -EFAULT;
503 goto unlock;
504 }
505
506 switch (uhid->input_buf.type) {
507 case UHID_CREATE:
508 ret = uhid_dev_create(uhid, &uhid->input_buf);
509 break;
510 case UHID_DESTROY:
511 ret = uhid_dev_destroy(uhid);
512 break;
513 case UHID_INPUT:
514 ret = uhid_dev_input(uhid, &uhid->input_buf);
515 break;
516 case UHID_FEATURE_ANSWER:
517 ret = uhid_dev_feature_answer(uhid, &uhid->input_buf);
518 break;
519 default:
520 ret = -EOPNOTSUPP;
521 }
522
523unlock:
524 mutex_unlock(&uhid->devlock);
525
526 /* return "count" not "len" to not confuse the caller */
527 return ret ? ret : count;
528}
529
530static unsigned int uhid_char_poll(struct file *file, poll_table *wait)
531{
532 struct uhid_device *uhid = file->private_data;
533
534 poll_wait(file, &uhid->waitq, wait);
535
536 if (uhid->head != uhid->tail)
537 return POLLIN | POLLRDNORM;
538
539 return 0;
540}
541
542static const struct file_operations uhid_fops = {
543 .owner = THIS_MODULE,
544 .open = uhid_char_open,
545 .release = uhid_char_release,
546 .read = uhid_char_read,
547 .write = uhid_char_write,
548 .poll = uhid_char_poll,
549 .llseek = no_llseek,
550};
551
552static struct miscdevice uhid_misc = {
553 .fops = &uhid_fops,
554 .minor = MISC_DYNAMIC_MINOR,
555 .name = UHID_NAME,
556};
557
558static int __init uhid_init(void)
559{
560 return misc_register(&uhid_misc);
561}
562
563static void __exit uhid_exit(void)
564{
565 misc_deregister(&uhid_misc);
566}
567
568module_init(uhid_init);
569module_exit(uhid_exit);
570MODULE_LICENSE("GPL");
571MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
572MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem");
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 8760be30b375..cb2a7d1ad47b 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -376,6 +376,7 @@ header-y += tty.h
376header-y += types.h 376header-y += types.h
377header-y += udf_fs_i.h 377header-y += udf_fs_i.h
378header-y += udp.h 378header-y += udp.h
379header-y += uhid.h
379header-y += uinput.h 380header-y += uinput.h
380header-y += uio.h 381header-y += uio.h
381header-y += ultrasound.h 382header-y += ultrasound.h
diff --git a/include/linux/uhid.h b/include/linux/uhid.h
new file mode 100644
index 000000000000..9c6974f16966
--- /dev/null
+++ b/include/linux/uhid.h
@@ -0,0 +1,104 @@
1#ifndef __UHID_H_
2#define __UHID_H_
3
4/*
5 * User-space I/O driver support for HID subsystem
6 * Copyright (c) 2012 David Herrmann
7 */
8
9/*
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 */
15
16/*
17 * Public header for user-space communication. We try to keep every structure
18 * aligned but to be safe we also use __attribute__((__packed__)). Therefore,
19 * the communication should be ABI compatible even between architectures.
20 */
21
22#include <linux/input.h>
23#include <linux/types.h>
24
25enum uhid_event_type {
26 UHID_CREATE,
27 UHID_DESTROY,
28 UHID_START,
29 UHID_STOP,
30 UHID_OPEN,
31 UHID_CLOSE,
32 UHID_OUTPUT,
33 UHID_OUTPUT_EV,
34 UHID_INPUT,
35 UHID_FEATURE,
36 UHID_FEATURE_ANSWER,
37};
38
39struct uhid_create_req {
40 __u8 name[128];
41 __u8 phys[64];
42 __u8 uniq[64];
43 __u8 __user *rd_data;
44 __u16 rd_size;
45
46 __u16 bus;
47 __u32 vendor;
48 __u32 product;
49 __u32 version;
50 __u32 country;
51} __attribute__((__packed__));
52
53#define UHID_DATA_MAX 4096
54
55enum uhid_report_type {
56 UHID_FEATURE_REPORT,
57 UHID_OUTPUT_REPORT,
58 UHID_INPUT_REPORT,
59};
60
61struct uhid_input_req {
62 __u8 data[UHID_DATA_MAX];
63 __u16 size;
64} __attribute__((__packed__));
65
66struct uhid_output_req {
67 __u8 data[UHID_DATA_MAX];
68 __u16 size;
69 __u8 rtype;
70} __attribute__((__packed__));
71
72struct uhid_output_ev_req {
73 __u16 type;
74 __u16 code;
75 __s32 value;
76} __attribute__((__packed__));
77
78struct uhid_feature_req {
79 __u32 id;
80 __u8 rnum;
81 __u8 rtype;
82} __attribute__((__packed__));
83
84struct uhid_feature_answer_req {
85 __u32 id;
86 __u16 err;
87 __u16 size;
88 __u8 data[UHID_DATA_MAX];
89};
90
91struct uhid_event {
92 __u32 type;
93
94 union {
95 struct uhid_create_req create;
96 struct uhid_input_req input;
97 struct uhid_output_req output;
98 struct uhid_output_ev_req output_ev;
99 struct uhid_feature_req feature;
100 struct uhid_feature_answer_req feature_answer;
101 } u;
102} __attribute__((__packed__));
103
104#endif /* __UHID_H_ */
diff --git a/samples/uhid/Makefile b/samples/uhid/Makefile
new file mode 100644
index 000000000000..c95a696560a7
--- /dev/null
+++ b/samples/uhid/Makefile
@@ -0,0 +1,10 @@
1# kbuild trick to avoid linker error. Can be omitted if a module is built.
2obj- := dummy.o
3
4# List of programs to build
5hostprogs-y := uhid-example
6
7# Tell kbuild to always build the programs
8always := $(hostprogs-y)
9
10HOSTCFLAGS_uhid-example.o += -I$(objtree)/usr/include
diff --git a/samples/uhid/uhid-example.c b/samples/uhid/uhid-example.c
new file mode 100644
index 000000000000..03ce3c059a5e
--- /dev/null
+++ b/samples/uhid/uhid-example.c
@@ -0,0 +1,381 @@
1/*
2 * UHID Example
3 *
4 * Copyright (c) 2012 David Herrmann <dh.herrmann@googlemail.com>
5 *
6 * The code may be used by anyone for any purpose,
7 * and can serve as a starting point for developing
8 * applications using uhid.
9 */
10
11/* UHID Example
12 * This example emulates a basic 3 buttons mouse with wheel over UHID. Run this
13 * program as root and then use the following keys to control the mouse:
14 * q: Quit the application
15 * 1: Toggle left button (down, up, ...)
16 * 2: Toggle right button
17 * 3: Toggle middle button
18 * a: Move mouse left
19 * d: Move mouse right
20 * w: Move mouse up
21 * s: Move mouse down
22 * r: Move wheel up
23 * f: Move wheel down
24 *
25 * If uhid is not available as /dev/uhid, then you can pass a different path as
26 * first argument.
27 * If <linux/uhid.h> is not installed in /usr, then compile this with:
28 * gcc -o ./uhid_test -Wall -I./include ./samples/uhid/uhid-example.c
29 * And ignore the warning about kernel headers. However, it is recommended to
30 * use the installed uhid.h if available.
31 */
32
33#include <errno.h>
34#include <fcntl.h>
35#include <poll.h>
36#include <stdbool.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <termios.h>
41#include <unistd.h>
42#include <linux/uhid.h>
43
44/* HID Report Desciptor
45 * We emulate a basic 3 button mouse with wheel. This is the report-descriptor
46 * as the kernel will parse it:
47 *
48 * INPUT[INPUT]
49 * Field(0)
50 * Physical(GenericDesktop.Pointer)
51 * Application(GenericDesktop.Mouse)
52 * Usage(3)
53 * Button.0001
54 * Button.0002
55 * Button.0003
56 * Logical Minimum(0)
57 * Logical Maximum(1)
58 * Report Size(1)
59 * Report Count(3)
60 * Report Offset(0)
61 * Flags( Variable Absolute )
62 * Field(1)
63 * Physical(GenericDesktop.Pointer)
64 * Application(GenericDesktop.Mouse)
65 * Usage(3)
66 * GenericDesktop.X
67 * GenericDesktop.Y
68 * GenericDesktop.Wheel
69 * Logical Minimum(-128)
70 * Logical Maximum(127)
71 * Report Size(8)
72 * Report Count(3)
73 * Report Offset(8)
74 * Flags( Variable Relative )
75 *
76 * This is the mapping that we expect:
77 * Button.0001 ---> Key.LeftBtn
78 * Button.0002 ---> Key.RightBtn
79 * Button.0003 ---> Key.MiddleBtn
80 * GenericDesktop.X ---> Relative.X
81 * GenericDesktop.Y ---> Relative.Y
82 * GenericDesktop.Wheel ---> Relative.Wheel
83 *
84 * This information can be verified by reading /sys/kernel/debug/hid/<dev>/rdesc
85 * This file should print the same information as showed above.
86 */
87
88static unsigned char rdesc[] = {
89 0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01,
90 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
91 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01,
92 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01,
93 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x38,
94 0x15, 0x80, 0x25, 0x7f, 0x75, 0x08, 0x95, 0x03,
95 0x81, 0x06, 0xc0, 0xc0,
96};
97
98static int uhid_write(int fd, const struct uhid_event *ev)
99{
100 ssize_t ret;
101
102 ret = write(fd, ev, sizeof(*ev));
103 if (ret < 0) {
104 fprintf(stderr, "Cannot write to uhid: %m\n");
105 return -errno;
106 } else if (ret != sizeof(*ev)) {
107 fprintf(stderr, "Wrong size written to uhid: %ld != %lu\n",
108 ret, sizeof(ev));
109 return -EFAULT;
110 } else {
111 return 0;
112 }
113}
114
115static int create(int fd)
116{
117 struct uhid_event ev;
118
119 memset(&ev, 0, sizeof(ev));
120 ev.type = UHID_CREATE;
121 strcpy((char*)ev.u.create.name, "test-uhid-device");
122 ev.u.create.rd_data = rdesc;
123 ev.u.create.rd_size = sizeof(rdesc);
124 ev.u.create.bus = BUS_USB;
125 ev.u.create.vendor = 0x15d9;
126 ev.u.create.product = 0x0a37;
127 ev.u.create.version = 0;
128 ev.u.create.country = 0;
129
130 return uhid_write(fd, &ev);
131}
132
133static void destroy(int fd)
134{
135 struct uhid_event ev;
136
137 memset(&ev, 0, sizeof(ev));
138 ev.type = UHID_DESTROY;
139
140 uhid_write(fd, &ev);
141}
142
143static int event(int fd)
144{
145 struct uhid_event ev;
146 ssize_t ret;
147
148 memset(&ev, 0, sizeof(ev));
149 ret = read(fd, &ev, sizeof(ev));
150 if (ret == 0) {
151 fprintf(stderr, "Read HUP on uhid-cdev\n");
152 return -EFAULT;
153 } else if (ret < 0) {
154 fprintf(stderr, "Cannot read uhid-cdev: %m\n");
155 return -errno;
156 } else if (ret != sizeof(ev)) {
157 fprintf(stderr, "Invalid size read from uhid-dev: %ld != %lu\n",
158 ret, sizeof(ev));
159 return -EFAULT;
160 }
161
162 switch (ev.type) {
163 case UHID_START:
164 fprintf(stderr, "UHID_START from uhid-dev\n");
165 break;
166 case UHID_STOP:
167 fprintf(stderr, "UHID_STOP from uhid-dev\n");
168 break;
169 case UHID_OPEN:
170 fprintf(stderr, "UHID_OPEN from uhid-dev\n");
171 break;
172 case UHID_CLOSE:
173 fprintf(stderr, "UHID_CLOSE from uhid-dev\n");
174 break;
175 case UHID_OUTPUT:
176 fprintf(stderr, "UHID_OUTPUT from uhid-dev\n");
177 break;
178 case UHID_OUTPUT_EV:
179 fprintf(stderr, "UHID_OUTPUT_EV from uhid-dev\n");
180 break;
181 default:
182 fprintf(stderr, "Invalid event from uhid-dev: %u\n", ev.type);
183 }
184
185 return 0;
186}
187
188static bool btn1_down;
189static bool btn2_down;
190static bool btn3_down;
191static signed char abs_hor;
192static signed char abs_ver;
193static signed char wheel;
194
195static int send_event(int fd)
196{
197 struct uhid_event ev;
198
199 memset(&ev, 0, sizeof(ev));
200 ev.type = UHID_INPUT;
201 ev.u.input.size = 4;
202
203 if (btn1_down)
204 ev.u.input.data[0] |= 0x1;
205 if (btn2_down)
206 ev.u.input.data[0] |= 0x2;
207 if (btn3_down)
208 ev.u.input.data[0] |= 0x4;
209
210 ev.u.input.data[1] = abs_hor;
211 ev.u.input.data[2] = abs_ver;
212 ev.u.input.data[3] = wheel;
213
214 return uhid_write(fd, &ev);
215}
216
217static int keyboard(int fd)
218{
219 char buf[128];
220 ssize_t ret, i;
221
222 ret = read(STDIN_FILENO, buf, sizeof(buf));
223 if (ret == 0) {
224 fprintf(stderr, "Read HUP on stdin\n");
225 return -EFAULT;
226 } else if (ret < 0) {
227 fprintf(stderr, "Cannot read stdin: %m\n");
228 return -errno;
229 }
230
231 for (i = 0; i < ret; ++i) {
232 switch (buf[i]) {
233 case '1':
234 btn1_down = !btn1_down;
235 ret = send_event(fd);
236 if (ret)
237 return ret;
238 break;
239 case '2':
240 btn2_down = !btn2_down;
241 ret = send_event(fd);
242 if (ret)
243 return ret;
244 break;
245 case '3':
246 btn3_down = !btn3_down;
247 ret = send_event(fd);
248 if (ret)
249 return ret;
250 break;
251 case 'a':
252 abs_hor = -20;
253 ret = send_event(fd);
254 abs_hor = 0;
255 if (ret)
256 return ret;
257 break;
258 case 'd':
259 abs_hor = 20;
260 ret = send_event(fd);
261 abs_hor = 0;
262 if (ret)
263 return ret;
264 break;
265 case 'w':
266 abs_ver = -20;
267 ret = send_event(fd);
268 abs_ver = 0;
269 if (ret)
270 return ret;
271 break;
272 case 's':
273 abs_ver = 20;
274 ret = send_event(fd);
275 abs_ver = 0;
276 if (ret)
277 return ret;
278 break;
279 case 'r':
280 wheel = 1;
281 ret = send_event(fd);
282 wheel = 0;
283 if (ret)
284 return ret;
285 break;
286 case 'f':
287 wheel = -1;
288 ret = send_event(fd);
289 wheel = 0;
290 if (ret)
291 return ret;
292 break;
293 case 'q':
294 return -ECANCELED;
295 default:
296 fprintf(stderr, "Invalid input: %c\n", buf[i]);
297 }
298 }
299
300 return 0;
301}
302
303int main(int argc, char **argv)
304{
305 int fd;
306 const char *path = "/dev/uhid";
307 struct pollfd pfds[2];
308 int ret;
309 struct termios state;
310
311 ret = tcgetattr(STDIN_FILENO, &state);
312 if (ret) {
313 fprintf(stderr, "Cannot get tty state\n");
314 } else {
315 state.c_lflag &= ~ICANON;
316 state.c_cc[VMIN] = 1;
317 ret = tcsetattr(STDIN_FILENO, TCSANOW, &state);
318 if (ret)
319 fprintf(stderr, "Cannot set tty state\n");
320 }
321
322 if (argc >= 2) {
323 if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
324 fprintf(stderr, "Usage: %s [%s]\n", argv[0], path);
325 return EXIT_SUCCESS;
326 } else {
327 path = argv[1];
328 }
329 }
330
331 fprintf(stderr, "Open uhid-cdev %s\n", path);
332 fd = open(path, O_RDWR | O_CLOEXEC);
333 if (fd < 0) {
334 fprintf(stderr, "Cannot open uhid-cdev %s: %m\n", path);
335 return EXIT_FAILURE;
336 }
337
338 fprintf(stderr, "Create uhid device\n");
339 ret = create(fd);
340 if (ret) {
341 close(fd);
342 return EXIT_FAILURE;
343 }
344
345 pfds[0].fd = STDIN_FILENO;
346 pfds[0].events = POLLIN;
347 pfds[1].fd = fd;
348 pfds[1].events = POLLIN;
349
350 fprintf(stderr, "Press 'q' to quit...\n");
351 while (1) {
352 ret = poll(pfds, 2, -1);
353 if (ret < 0) {
354 fprintf(stderr, "Cannot poll for fds: %m\n");
355 break;
356 }
357 if (pfds[0].revents & POLLHUP) {
358 fprintf(stderr, "Received HUP on stdin\n");
359 break;
360 }
361 if (pfds[1].revents & POLLHUP) {
362 fprintf(stderr, "Received HUP on uhid-cdev\n");
363 break;
364 }
365
366 if (pfds[0].revents & POLLIN) {
367 ret = keyboard(fd);
368 if (ret)
369 break;
370 }
371 if (pfds[1].revents & POLLIN) {
372 ret = event(fd);
373 if (ret)
374 break;
375 }
376 }
377
378 fprintf(stderr, "Destroy uhid device\n");
379 destroy(fd);
380 return EXIT_SUCCESS;
381}