aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hidp/core.c64
1 files changed, 55 insertions, 9 deletions
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 96434d774c84..56a51f91591a 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -578,7 +578,7 @@ static int hidp_session(void *arg)
578 if (session->hid) { 578 if (session->hid) {
579 if (session->hid->claimed & HID_CLAIMED_INPUT) 579 if (session->hid->claimed & HID_CLAIMED_INPUT)
580 hidinput_disconnect(session->hid); 580 hidinput_disconnect(session->hid);
581 hid_free_device(session->hid); 581 hid_destroy_device(session->hid);
582 } 582 }
583 583
584 /* Wakeup user-space polling for socket errors */ 584 /* Wakeup user-space polling for socket errors */
@@ -698,12 +698,13 @@ static void hidp_setup_quirks(struct hid_device *hid)
698 hid->quirks = hidp_blacklist[n].quirks; 698 hid->quirks = hidp_blacklist[n].quirks;
699} 699}
700 700
701static void hidp_setup_hid(struct hidp_session *session, 701static int hidp_setup_hid(struct hidp_session *session,
702 struct hidp_connadd_req *req) 702 struct hidp_connadd_req *req)
703{ 703{
704 struct hid_device *hid = session->hid; 704 struct hid_device *hid = session->hid;
705 struct hid_report *report; 705 struct hid_report *report;
706 bdaddr_t src, dst; 706 bdaddr_t src, dst;
707 int ret;
707 708
708 baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); 709 baswap(&src, &bt_sk(session->ctrl_sock->sk)->src);
709 baswap(&dst, &bt_sk(session->ctrl_sock->sk)->dst); 710 baswap(&dst, &bt_sk(session->ctrl_sock->sk)->dst);
@@ -721,7 +722,7 @@ static void hidp_setup_hid(struct hidp_session *session,
721 strncpy(hid->phys, batostr(&src), 64); 722 strncpy(hid->phys, batostr(&src), 64);
722 strncpy(hid->uniq, batostr(&dst), 64); 723 strncpy(hid->uniq, batostr(&dst), 64);
723 724
724 hid->dev = hidp_get_device(session); 725 hid->dev.parent = hidp_get_device(session);
725 726
726 hid->hid_open = hidp_open; 727 hid->hid_open = hidp_open;
727 hid->hid_close = hidp_close; 728 hid->hid_close = hidp_close;
@@ -738,6 +739,15 @@ static void hidp_setup_hid(struct hidp_session *session,
738 739
739 if (hidinput_connect(hid) == 0) 740 if (hidinput_connect(hid) == 0)
740 hid->claimed |= HID_CLAIMED_INPUT; 741 hid->claimed |= HID_CLAIMED_INPUT;
742
743 ret = hid_add_device(hid);
744 if (ret) {
745 if (hid->claimed & HID_CLAIMED_INPUT)
746 hidinput_disconnect(hid);
747 skb_queue_purge(&session->intr_transmit);
748 }
749
750 return ret;
741} 751}
742 752
743int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock) 753int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
@@ -771,11 +781,19 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
771 return -EFAULT; 781 return -EFAULT;
772 } 782 }
773 783
774 session->hid = hid_parse_report(buf, req->rd_size); 784 session->hid = hid_allocate_device();
785 if (IS_ERR(session->hid)) {
786 kfree(buf);
787 kfree(session);
788 return PTR_ERR(session->hid);
789 }
790
791 err = hid_parse_report(session->hid, buf, req->rd_size);
775 792
776 kfree(buf); 793 kfree(buf);
777 794
778 if (!session->hid) { 795 if (err) {
796 hid_destroy_device(session->hid);
779 kfree(session); 797 kfree(session);
780 return -EINVAL; 798 return -EINVAL;
781 } 799 }
@@ -822,8 +840,11 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
822 goto failed; 840 goto failed;
823 } 841 }
824 842
825 if (session->hid) 843 if (session->hid) {
826 hidp_setup_hid(session, req); 844 err = hidp_setup_hid(session, req);
845 if (err)
846 goto failed;
847 }
827 848
828 __hidp_link_session(session); 849 __hidp_link_session(session);
829 850
@@ -859,7 +880,7 @@ failed:
859 up_write(&hidp_session_sem); 880 up_write(&hidp_session_sem);
860 881
861 if (session->hid) 882 if (session->hid)
862 hid_free_device(session->hid); 883 hid_destroy_device(session->hid);
863 884
864 input_free_device(session->input); 885 input_free_device(session->input);
865 kfree(session); 886 kfree(session);
@@ -950,18 +971,43 @@ int hidp_get_conninfo(struct hidp_conninfo *ci)
950 return err; 971 return err;
951} 972}
952 973
974static const struct hid_device_id hidp_table[] = {
975 { HID_BLUETOOTH_DEVICE(HID_ANY_ID, HID_ANY_ID) },
976 { }
977};
978
979static struct hid_driver hidp_driver = {
980 .name = "generic-bluetooth",
981 .id_table = hidp_table,
982};
983
953static int __init hidp_init(void) 984static int __init hidp_init(void)
954{ 985{
986 int ret;
987
955 l2cap_load(); 988 l2cap_load();
956 989
957 BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION); 990 BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION);
958 991
959 return hidp_init_sockets(); 992 ret = hid_register_driver(&hidp_driver);
993 if (ret)
994 goto err;
995
996 ret = hidp_init_sockets();
997 if (ret)
998 goto err_drv;
999
1000 return 0;
1001err_drv:
1002 hid_unregister_driver(&hidp_driver);
1003err:
1004 return ret;
960} 1005}
961 1006
962static void __exit hidp_exit(void) 1007static void __exit hidp_exit(void)
963{ 1008{
964 hidp_cleanup_sockets(); 1009 hidp_cleanup_sockets();
1010 hid_unregister_driver(&hidp_driver);
965} 1011}
966 1012
967module_init(hidp_init); 1013module_init(hidp_init);