aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2014-04-01 12:56:24 -0400
committerJiri Kosina <jkosina@suse.cz>2014-04-01 12:56:24 -0400
commitee5f68e6c2f183e6aade0e9c57af13d5eff44f2f (patch)
treede4132918ec7b033c4981e2ba4aea9027816bdb9
parentf74346a04b79c9a5e50a2ee5e923b94195975d17 (diff)
parent0a7f364e812285246cd617a51194a3f8bd0e8daa (diff)
Merge branch 'for-3.15/ll-driver-new-callbacks' into for-linus
-rw-r--r--drivers/hid/uhid.c27
-rw-r--r--drivers/hid/usbhid/hid-core.c78
-rw-r--r--include/linux/hid.h8
-rw-r--r--net/bluetooth/hidp/core.c90
4 files changed, 202 insertions, 1 deletions
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
index cedc6da93c19..f5a2b1931143 100644
--- a/drivers/hid/uhid.c
+++ b/drivers/hid/uhid.c
@@ -244,12 +244,39 @@ static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count,
244 return count; 244 return count;
245} 245}
246 246
247static int uhid_hid_output_report(struct hid_device *hid, __u8 *buf,
248 size_t count)
249{
250 struct uhid_device *uhid = hid->driver_data;
251 unsigned long flags;
252 struct uhid_event *ev;
253
254 if (count < 1 || count > UHID_DATA_MAX)
255 return -EINVAL;
256
257 ev = kzalloc(sizeof(*ev), GFP_KERNEL);
258 if (!ev)
259 return -ENOMEM;
260
261 ev->type = UHID_OUTPUT;
262 ev->u.output.size = count;
263 ev->u.output.rtype = UHID_OUTPUT_REPORT;
264 memcpy(ev->u.output.data, buf, count);
265
266 spin_lock_irqsave(&uhid->qlock, flags);
267 uhid_queue(uhid, ev);
268 spin_unlock_irqrestore(&uhid->qlock, flags);
269
270 return count;
271}
272
247static struct hid_ll_driver uhid_hid_driver = { 273static struct hid_ll_driver uhid_hid_driver = {
248 .start = uhid_hid_start, 274 .start = uhid_hid_start,
249 .stop = uhid_hid_stop, 275 .stop = uhid_hid_stop,
250 .open = uhid_hid_open, 276 .open = uhid_hid_open,
251 .close = uhid_hid_close, 277 .close = uhid_hid_close,
252 .parse = uhid_hid_parse, 278 .parse = uhid_hid_parse,
279 .output_report = uhid_hid_output_report,
253}; 280};
254 281
255#ifdef CONFIG_COMPAT 282#ifdef CONFIG_COMPAT
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 44df131d390a..f8ca312bae1b 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -884,6 +884,38 @@ static int usbhid_get_raw_report(struct hid_device *hid,
884 return ret; 884 return ret;
885} 885}
886 886
887static int usbhid_set_raw_report(struct hid_device *hid, unsigned int reportnum,
888 __u8 *buf, size_t count, unsigned char rtype)
889{
890 struct usbhid_device *usbhid = hid->driver_data;
891 struct usb_device *dev = hid_to_usb_dev(hid);
892 struct usb_interface *intf = usbhid->intf;
893 struct usb_host_interface *interface = intf->cur_altsetting;
894 int ret, skipped_report_id = 0;
895
896 /* Byte 0 is the report number. Report data starts at byte 1.*/
897 buf[0] = reportnum;
898 if (buf[0] == 0x0) {
899 /* Don't send the Report ID */
900 buf++;
901 count--;
902 skipped_report_id = 1;
903 }
904
905 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
906 HID_REQ_SET_REPORT,
907 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
908 ((rtype + 1) << 8) | reportnum,
909 interface->desc.bInterfaceNumber, buf, count,
910 USB_CTRL_SET_TIMEOUT);
911 /* count also the report id, if this was a numbered report. */
912 if (ret > 0 && skipped_report_id)
913 ret++;
914
915 return ret;
916}
917
918
887static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count, 919static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count,
888 unsigned char report_type) 920 unsigned char report_type)
889{ 921{
@@ -936,6 +968,36 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
936 return ret; 968 return ret;
937} 969}
938 970
971static int usbhid_output_report(struct hid_device *hid, __u8 *buf, size_t count)
972{
973 struct usbhid_device *usbhid = hid->driver_data;
974 struct usb_device *dev = hid_to_usb_dev(hid);
975 int actual_length, skipped_report_id = 0, ret;
976
977 if (!usbhid->urbout)
978 return -EIO;
979
980 if (buf[0] == 0x0) {
981 /* Don't send the Report ID */
982 buf++;
983 count--;
984 skipped_report_id = 1;
985 }
986
987 ret = usb_interrupt_msg(dev, usbhid->urbout->pipe,
988 buf, count, &actual_length,
989 USB_CTRL_SET_TIMEOUT);
990 /* return the number of bytes transferred */
991 if (ret == 0) {
992 ret = actual_length;
993 /* count also the report id */
994 if (skipped_report_id)
995 ret++;
996 }
997
998 return ret;
999}
1000
939static void usbhid_restart_queues(struct usbhid_device *usbhid) 1001static void usbhid_restart_queues(struct usbhid_device *usbhid)
940{ 1002{
941 if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)) 1003 if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl))
@@ -1200,6 +1262,20 @@ static void usbhid_request(struct hid_device *hid, struct hid_report *rep, int r
1200 } 1262 }
1201} 1263}
1202 1264
1265static int usbhid_raw_request(struct hid_device *hid, unsigned char reportnum,
1266 __u8 *buf, size_t len, unsigned char rtype,
1267 int reqtype)
1268{
1269 switch (reqtype) {
1270 case HID_REQ_GET_REPORT:
1271 return usbhid_get_raw_report(hid, reportnum, buf, len, rtype);
1272 case HID_REQ_SET_REPORT:
1273 return usbhid_set_raw_report(hid, reportnum, buf, len, rtype);
1274 default:
1275 return -EIO;
1276 }
1277}
1278
1203static int usbhid_idle(struct hid_device *hid, int report, int idle, 1279static int usbhid_idle(struct hid_device *hid, int report, int idle,
1204 int reqtype) 1280 int reqtype)
1205{ 1281{
@@ -1223,6 +1299,8 @@ static struct hid_ll_driver usb_hid_driver = {
1223 .power = usbhid_power, 1299 .power = usbhid_power,
1224 .request = usbhid_request, 1300 .request = usbhid_request,
1225 .wait = usbhid_wait_io, 1301 .wait = usbhid_wait_io,
1302 .raw_request = usbhid_raw_request,
1303 .output_report = usbhid_output_report,
1226 .idle = usbhid_idle, 1304 .idle = usbhid_idle,
1227}; 1305};
1228 1306
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 31b9d299ef6c..003cc8e89831 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -700,8 +700,14 @@ struct hid_ll_driver {
700 struct hid_report *report, int reqtype); 700 struct hid_report *report, int reqtype);
701 701
702 int (*wait)(struct hid_device *hdev); 702 int (*wait)(struct hid_device *hdev);
703 int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype);
704 703
704 int (*raw_request) (struct hid_device *hdev, unsigned char reportnum,
705 __u8 *buf, size_t len, unsigned char rtype,
706 int reqtype);
707
708 int (*output_report) (struct hid_device *hdev, __u8 *buf, size_t len);
709
710 int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype);
705}; 711};
706 712
707#define PM_HINT_FULLON 1<<5 713#define PM_HINT_FULLON 1<<5
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index d9fb93451442..450a0b999614 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;
@@ -739,6 +827,8 @@ static struct hid_ll_driver hidp_hid_driver = {
739 .stop = hidp_stop, 827 .stop = hidp_stop,
740 .open = hidp_open, 828 .open = hidp_open,
741 .close = hidp_close, 829 .close = hidp_close,
830 .raw_request = hidp_raw_request,
831 .output_report = hidp_output_report,
742 .hidinput_input_event = hidp_hidinput_event, 832 .hidinput_input_event = hidp_hidinput_event,
743}; 833};
744 834