aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hidp
diff options
context:
space:
mode:
authorFrank Praznik <frank.praznik@oh.rr.com>2014-01-22 13:49:44 -0500
committerJiri Kosina <jkosina@suse.cz>2014-01-29 08:23:43 -0500
commit0a7f364e812285246cd617a51194a3f8bd0e8daa (patch)
tree018f78b306e0b46a2a94f1df5a737fa4b23b0032 /net/bluetooth/hidp
parent596cfdd80ab8ad11c750511da2c8c9a33f188ba0 (diff)
HID: Add the transport-driver functions to the HIDP driver.
Add raw_request, set_raw_report and output_report transport-driver functions to the HIDP driver. Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com> Acked-by: David Herrmann <dh.herrmann@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'net/bluetooth/hidp')
-rw-r--r--net/bluetooth/hidp/core.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 292e619db896..b062cee3f319 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -353,6 +353,71 @@ err:
353 return ret; 353 return ret;
354} 354}
355 355
356static int hidp_set_raw_report(struct hid_device *hid, unsigned char reportnum,
357 unsigned char *data, size_t count,
358 unsigned char report_type)
359{
360 struct hidp_session *session = hid->driver_data;
361 int ret;
362
363 switch (report_type) {
364 case HID_FEATURE_REPORT:
365 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE;
366 break;
367 case HID_INPUT_REPORT:
368 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_INPUT;
369 break;
370 case HID_OUTPUT_REPORT:
371 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_OUPUT;
372 break;
373 default:
374 return -EINVAL;
375 }
376
377 if (mutex_lock_interruptible(&session->report_mutex))
378 return -ERESTARTSYS;
379
380 /* Set up our wait, and send the report request to the device. */
381 data[0] = reportnum;
382 set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
383 ret = hidp_send_ctrl_message(session, report_type, data, count);
384 if (ret)
385 goto err;
386
387 /* Wait for the ACK from the device. */
388 while (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags) &&
389 !atomic_read(&session->terminate)) {
390 int res;
391
392 res = wait_event_interruptible_timeout(session->report_queue,
393 !test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)
394 || atomic_read(&session->terminate),
395 10*HZ);
396 if (res == 0) {
397 /* timeout */
398 ret = -EIO;
399 goto err;
400 }
401 if (res < 0) {
402 /* signal */
403 ret = -ERESTARTSYS;
404 goto err;
405 }
406 }
407
408 if (!session->output_report_success) {
409 ret = -EIO;
410 goto err;
411 }
412
413 ret = count;
414
415err:
416 clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
417 mutex_unlock(&session->report_mutex);
418 return ret;
419}
420
356static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count, 421static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count,
357 unsigned char report_type) 422 unsigned char report_type)
358{ 423{
@@ -411,6 +476,29 @@ err:
411 return ret; 476 return ret;
412} 477}
413 478
479static int hidp_raw_request(struct hid_device *hid, unsigned char reportnum,
480 __u8 *buf, size_t len, unsigned char rtype,
481 int reqtype)
482{
483 switch (reqtype) {
484 case HID_REQ_GET_REPORT:
485 return hidp_get_raw_report(hid, reportnum, buf, len, rtype);
486 case HID_REQ_SET_REPORT:
487 return hidp_set_raw_report(hid, reportnum, buf, len, rtype);
488 default:
489 return -EIO;
490 }
491}
492
493static int hidp_output_report(struct hid_device *hid, __u8 *data, size_t count)
494{
495 struct hidp_session *session = hid->driver_data;
496
497 return hidp_send_intr_message(session,
498 HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT,
499 data, count);
500}
501
414static void hidp_idle_timeout(unsigned long arg) 502static void hidp_idle_timeout(unsigned long arg)
415{ 503{
416 struct hidp_session *session = (struct hidp_session *) arg; 504 struct hidp_session *session = (struct hidp_session *) arg;
@@ -727,6 +815,8 @@ static struct hid_ll_driver hidp_hid_driver = {
727 .stop = hidp_stop, 815 .stop = hidp_stop,
728 .open = hidp_open, 816 .open = hidp_open,
729 .close = hidp_close, 817 .close = hidp_close,
818 .raw_request = hidp_raw_request,
819 .output_report = hidp_output_report,
730 .hidinput_input_event = hidp_hidinput_event, 820 .hidinput_input_event = hidp_hidinput_event,
731}; 821};
732 822