diff options
Diffstat (limited to 'drivers/hid/uhid.c')
-rw-r--r-- | drivers/hid/uhid.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 4dd693e1c8b8..421c492dc824 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c | |||
@@ -149,7 +149,39 @@ static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum, | |||
149 | static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count, | 149 | static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count, |
150 | unsigned char report_type) | 150 | unsigned char report_type) |
151 | { | 151 | { |
152 | return 0; | 152 | struct uhid_device *uhid = hid->driver_data; |
153 | __u8 rtype; | ||
154 | unsigned long flags; | ||
155 | struct uhid_event *ev; | ||
156 | |||
157 | switch (report_type) { | ||
158 | case HID_FEATURE_REPORT: | ||
159 | rtype = UHID_FEATURE_REPORT; | ||
160 | break; | ||
161 | case HID_OUTPUT_REPORT: | ||
162 | rtype = UHID_OUTPUT_REPORT; | ||
163 | break; | ||
164 | default: | ||
165 | return -EINVAL; | ||
166 | } | ||
167 | |||
168 | if (count < 1 || count > UHID_DATA_MAX) | ||
169 | return -EINVAL; | ||
170 | |||
171 | ev = kzalloc(sizeof(*ev), GFP_KERNEL); | ||
172 | if (!ev) | ||
173 | return -ENOMEM; | ||
174 | |||
175 | ev->type = UHID_OUTPUT; | ||
176 | ev->u.output.size = count; | ||
177 | ev->u.output.rtype = rtype; | ||
178 | memcpy(ev->u.output.data, buf, count); | ||
179 | |||
180 | spin_lock_irqsave(&uhid->qlock, flags); | ||
181 | uhid_queue(uhid, ev); | ||
182 | spin_unlock_irqrestore(&uhid->qlock, flags); | ||
183 | |||
184 | return count; | ||
153 | } | 185 | } |
154 | 186 | ||
155 | static struct hid_ll_driver uhid_hid_driver = { | 187 | static struct hid_ll_driver uhid_hid_driver = { |