diff options
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hidp/core.c | 49 | ||||
-rw-r--r-- | net/bluetooth/hidp/hidp.h | 4 |
2 files changed, 27 insertions, 26 deletions
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 6cf526d06e21..fc6ec1e72652 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -703,29 +703,9 @@ static void hidp_close(struct hid_device *hid) | |||
703 | static int hidp_parse(struct hid_device *hid) | 703 | static int hidp_parse(struct hid_device *hid) |
704 | { | 704 | { |
705 | struct hidp_session *session = hid->driver_data; | 705 | struct hidp_session *session = hid->driver_data; |
706 | struct hidp_connadd_req *req = session->req; | ||
707 | unsigned char *buf; | ||
708 | int ret; | ||
709 | |||
710 | buf = kmalloc(req->rd_size, GFP_KERNEL); | ||
711 | if (!buf) | ||
712 | return -ENOMEM; | ||
713 | |||
714 | if (copy_from_user(buf, req->rd_data, req->rd_size)) { | ||
715 | kfree(buf); | ||
716 | return -EFAULT; | ||
717 | } | ||
718 | |||
719 | ret = hid_parse_report(session->hid, buf, req->rd_size); | ||
720 | |||
721 | kfree(buf); | ||
722 | |||
723 | if (ret) | ||
724 | return ret; | ||
725 | |||
726 | session->req = NULL; | ||
727 | 706 | ||
728 | return 0; | 707 | return hid_parse_report(session->hid, session->rd_data, |
708 | session->rd_size); | ||
729 | } | 709 | } |
730 | 710 | ||
731 | static int hidp_start(struct hid_device *hid) | 711 | static int hidp_start(struct hid_device *hid) |
@@ -770,12 +750,24 @@ static int hidp_setup_hid(struct hidp_session *session, | |||
770 | bdaddr_t src, dst; | 750 | bdaddr_t src, dst; |
771 | int err; | 751 | int err; |
772 | 752 | ||
753 | session->rd_data = kzalloc(req->rd_size, GFP_KERNEL); | ||
754 | if (!session->rd_data) | ||
755 | return -ENOMEM; | ||
756 | |||
757 | if (copy_from_user(session->rd_data, req->rd_data, req->rd_size)) { | ||
758 | err = -EFAULT; | ||
759 | goto fault; | ||
760 | } | ||
761 | session->rd_size = req->rd_size; | ||
762 | |||
773 | hid = hid_allocate_device(); | 763 | hid = hid_allocate_device(); |
774 | if (IS_ERR(hid)) | 764 | if (IS_ERR(hid)) { |
775 | return PTR_ERR(hid); | 765 | err = PTR_ERR(hid); |
766 | goto fault; | ||
767 | } | ||
776 | 768 | ||
777 | session->hid = hid; | 769 | session->hid = hid; |
778 | session->req = req; | 770 | |
779 | hid->driver_data = session; | 771 | hid->driver_data = session; |
780 | 772 | ||
781 | baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); | 773 | baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); |
@@ -806,6 +798,10 @@ failed: | |||
806 | hid_destroy_device(hid); | 798 | hid_destroy_device(hid); |
807 | session->hid = NULL; | 799 | session->hid = NULL; |
808 | 800 | ||
801 | fault: | ||
802 | kfree(session->rd_data); | ||
803 | session->rd_data = NULL; | ||
804 | |||
809 | return err; | 805 | return err; |
810 | } | 806 | } |
811 | 807 | ||
@@ -900,6 +896,9 @@ unlink: | |||
900 | session->hid = NULL; | 896 | session->hid = NULL; |
901 | } | 897 | } |
902 | 898 | ||
899 | kfree(session->rd_data); | ||
900 | session->rd_data = NULL; | ||
901 | |||
903 | purge: | 902 | purge: |
904 | skb_queue_purge(&session->ctrl_transmit); | 903 | skb_queue_purge(&session->ctrl_transmit); |
905 | skb_queue_purge(&session->intr_transmit); | 904 | skb_queue_purge(&session->intr_transmit); |
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h index faf3d74c3586..a4e215d50c10 100644 --- a/net/bluetooth/hidp/hidp.h +++ b/net/bluetooth/hidp/hidp.h | |||
@@ -154,7 +154,9 @@ struct hidp_session { | |||
154 | struct sk_buff_head ctrl_transmit; | 154 | struct sk_buff_head ctrl_transmit; |
155 | struct sk_buff_head intr_transmit; | 155 | struct sk_buff_head intr_transmit; |
156 | 156 | ||
157 | struct hidp_connadd_req *req; | 157 | /* Report descriptor */ |
158 | __u8 *rd_data; | ||
159 | uint rd_size; | ||
158 | }; | 160 | }; |
159 | 161 | ||
160 | static inline void hidp_schedule(struct hidp_session *session) | 162 | static inline void hidp_schedule(struct hidp_session *session) |