diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2014-07-29 19:14:25 +0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2014-08-25 12:28:08 +0400 |
commit | c2b2f16c5c62583d4f8904e44c4b30c94a01eaf1 (patch) | |
tree | 72ff984b458a6ff721a67a062fc11fe6c9548a26 /drivers/hid/uhid.c | |
parent | 11c221553080408b203a00b91ad5f647dfb218d1 (diff) | |
download | linux-c2b2f16c5c62583d4f8904e44c4b30c94a01eaf1.tar.xz |
HID: uhid: report to user-space whether reports are numbered
This makes UHID_START include a "dev_flags" field that describes details
of the hid-device in the kernel. The first flags we introduce describe
whether a given report-type uses numbered reports. This is useful for
transport layers that force report-numbers and therefore might have to
prefix kernel-provided HID-messages with the report-number.
Currently, only HoG needs this and the spec only talks about "global
report numbers". That is, it's a global boolean not a per-type boolean.
However, given the quirks we already have in kernel-space, a per-type
value seems much more appropriate.
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/uhid.c')
-rw-r--r-- | drivers/hid/uhid.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 19511481a7d3..f6ec5eaf6b89 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -92,8 +92,27 @@ static int uhid_queue_event(struct uhid_device *uhid, __u32 event) static int uhid_hid_start(struct hid_device *hid) { struct uhid_device *uhid = hid->driver_data; + struct uhid_event *ev; + unsigned long flags; + + ev = kzalloc(sizeof(*ev), GFP_KERNEL); + if (!ev) + return -ENOMEM; + + ev->type = UHID_START; - return uhid_queue_event(uhid, UHID_START); + if (hid->report_enum[HID_FEATURE_REPORT].numbered) + ev->u.start.dev_flags |= UHID_DEV_NUMBERED_FEATURE_REPORTS; + if (hid->report_enum[HID_OUTPUT_REPORT].numbered) + ev->u.start.dev_flags |= UHID_DEV_NUMBERED_OUTPUT_REPORTS; + if (hid->report_enum[HID_INPUT_REPORT].numbered) + ev->u.start.dev_flags |= UHID_DEV_NUMBERED_INPUT_REPORTS; + + spin_lock_irqsave(&uhid->qlock, flags); + uhid_queue(uhid, ev); + spin_unlock_irqrestore(&uhid->qlock, flags); + + return 0; } static void uhid_hid_stop(struct hid_device *hid) |