diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hidp/core.c | 107 |
1 files changed, 52 insertions, 55 deletions
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 292e619db896..77c4badb3e9d 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -223,51 +223,6 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb) | |||
223 | input_sync(dev); | 223 | input_sync(dev); |
224 | } | 224 | } |
225 | 225 | ||
226 | static int hidp_send_report(struct hidp_session *session, struct hid_report *report) | ||
227 | { | ||
228 | unsigned char hdr; | ||
229 | u8 *buf; | ||
230 | int rsize, ret; | ||
231 | |||
232 | buf = hid_alloc_report_buf(report, GFP_ATOMIC); | ||
233 | if (!buf) | ||
234 | return -EIO; | ||
235 | |||
236 | hid_output_report(report, buf); | ||
237 | hdr = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT; | ||
238 | |||
239 | rsize = ((report->size - 1) >> 3) + 1 + (report->id > 0); | ||
240 | ret = hidp_send_intr_message(session, hdr, buf, rsize); | ||
241 | |||
242 | kfree(buf); | ||
243 | return ret; | ||
244 | } | ||
245 | |||
246 | static int hidp_hidinput_event(struct input_dev *dev, unsigned int type, | ||
247 | unsigned int code, int value) | ||
248 | { | ||
249 | struct hid_device *hid = input_get_drvdata(dev); | ||
250 | struct hidp_session *session = hid->driver_data; | ||
251 | struct hid_field *field; | ||
252 | int offset; | ||
253 | |||
254 | BT_DBG("session %p type %d code %d value %d", | ||
255 | session, type, code, value); | ||
256 | |||
257 | if (type != EV_LED) | ||
258 | return -1; | ||
259 | |||
260 | offset = hidinput_find_field(hid, type, code, &field); | ||
261 | if (offset == -1) { | ||
262 | hid_warn(dev, "event field not found\n"); | ||
263 | return -1; | ||
264 | } | ||
265 | |||
266 | hid_set_field(field, offset, value); | ||
267 | |||
268 | return hidp_send_report(session, field->report); | ||
269 | } | ||
270 | |||
271 | static int hidp_get_raw_report(struct hid_device *hid, | 226 | static int hidp_get_raw_report(struct hid_device *hid, |
272 | unsigned char report_number, | 227 | unsigned char report_number, |
273 | unsigned char *data, size_t count, | 228 | unsigned char *data, size_t count, |
@@ -353,17 +308,24 @@ err: | |||
353 | return ret; | 308 | return ret; |
354 | } | 309 | } |
355 | 310 | ||
356 | static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count, | 311 | static int hidp_set_raw_report(struct hid_device *hid, unsigned char reportnum, |
357 | unsigned char report_type) | 312 | unsigned char *data, size_t count, |
313 | unsigned char report_type) | ||
358 | { | 314 | { |
359 | struct hidp_session *session = hid->driver_data; | 315 | struct hidp_session *session = hid->driver_data; |
360 | int ret; | 316 | int ret; |
361 | 317 | ||
362 | if (report_type == HID_OUTPUT_REPORT) { | 318 | switch (report_type) { |
363 | report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT; | 319 | case HID_FEATURE_REPORT: |
364 | return hidp_send_intr_message(session, report_type, | 320 | report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE; |
365 | data, count); | 321 | break; |
366 | } else if (report_type != HID_FEATURE_REPORT) { | 322 | case HID_INPUT_REPORT: |
323 | report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_INPUT; | ||
324 | break; | ||
325 | case HID_OUTPUT_REPORT: | ||
326 | report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_OUPUT; | ||
327 | break; | ||
328 | default: | ||
367 | return -EINVAL; | 329 | return -EINVAL; |
368 | } | 330 | } |
369 | 331 | ||
@@ -371,8 +333,8 @@ static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, s | |||
371 | return -ERESTARTSYS; | 333 | return -ERESTARTSYS; |
372 | 334 | ||
373 | /* Set up our wait, and send the report request to the device. */ | 335 | /* Set up our wait, and send the report request to the device. */ |
336 | data[0] = reportnum; | ||
374 | set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); | 337 | set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); |
375 | report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE; | ||
376 | ret = hidp_send_ctrl_message(session, report_type, data, count); | 338 | ret = hidp_send_ctrl_message(session, report_type, data, count); |
377 | if (ret) | 339 | if (ret) |
378 | goto err; | 340 | goto err; |
@@ -411,6 +373,41 @@ err: | |||
411 | return ret; | 373 | return ret; |
412 | } | 374 | } |
413 | 375 | ||
376 | static int hidp_output_report(struct hid_device *hid, __u8 *data, size_t count) | ||
377 | { | ||
378 | struct hidp_session *session = hid->driver_data; | ||
379 | |||
380 | return hidp_send_intr_message(session, | ||
381 | HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT, | ||
382 | data, count); | ||
383 | } | ||
384 | |||
385 | static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, | ||
386 | size_t count, unsigned char report_type) | ||
387 | { | ||
388 | if (report_type == HID_OUTPUT_REPORT) { | ||
389 | return hidp_output_report(hid, data, count); | ||
390 | } else if (report_type != HID_FEATURE_REPORT) { | ||
391 | return -EINVAL; | ||
392 | } | ||
393 | |||
394 | return hidp_set_raw_report(hid, data[0], data, count, report_type); | ||
395 | } | ||
396 | |||
397 | static int hidp_raw_request(struct hid_device *hid, unsigned char reportnum, | ||
398 | __u8 *buf, size_t len, unsigned char rtype, | ||
399 | int reqtype) | ||
400 | { | ||
401 | switch (reqtype) { | ||
402 | case HID_REQ_GET_REPORT: | ||
403 | return hidp_get_raw_report(hid, reportnum, buf, len, rtype); | ||
404 | case HID_REQ_SET_REPORT: | ||
405 | return hidp_set_raw_report(hid, reportnum, buf, len, rtype); | ||
406 | default: | ||
407 | return -EIO; | ||
408 | } | ||
409 | } | ||
410 | |||
414 | static void hidp_idle_timeout(unsigned long arg) | 411 | static void hidp_idle_timeout(unsigned long arg) |
415 | { | 412 | { |
416 | struct hidp_session *session = (struct hidp_session *) arg; | 413 | struct hidp_session *session = (struct hidp_session *) arg; |
@@ -727,7 +724,8 @@ static struct hid_ll_driver hidp_hid_driver = { | |||
727 | .stop = hidp_stop, | 724 | .stop = hidp_stop, |
728 | .open = hidp_open, | 725 | .open = hidp_open, |
729 | .close = hidp_close, | 726 | .close = hidp_close, |
730 | .hidinput_input_event = hidp_hidinput_event, | 727 | .raw_request = hidp_raw_request, |
728 | .output_report = hidp_output_report, | ||
731 | }; | 729 | }; |
732 | 730 | ||
733 | /* This function sets up the hid device. It does not add it | 731 | /* This function sets up the hid device. It does not add it |
@@ -775,7 +773,6 @@ static int hidp_setup_hid(struct hidp_session *session, | |||
775 | hid->dev.parent = &session->conn->hcon->dev; | 773 | hid->dev.parent = &session->conn->hcon->dev; |
776 | hid->ll_driver = &hidp_hid_driver; | 774 | hid->ll_driver = &hidp_hid_driver; |
777 | 775 | ||
778 | hid->hid_get_raw_report = hidp_get_raw_report; | ||
779 | hid->hid_output_raw_report = hidp_output_raw_report; | 776 | hid->hid_output_raw_report = hidp_output_raw_report; |
780 | 777 | ||
781 | /* True if device is blacklisted in drivers/hid/hid-core.c */ | 778 | /* True if device is blacklisted in drivers/hid/hid-core.c */ |