diff options
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_conn.c | 3 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 1 | ||||
-rw-r--r-- | net/bluetooth/hidp/core.c | 49 | ||||
-rw-r--r-- | net/bluetooth/hidp/hidp.h | 4 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 8 |
5 files changed, 37 insertions, 28 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index b7c4224f4e7d..b10e3cdb08f8 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -377,6 +377,9 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 | |||
377 | 377 | ||
378 | if (acl->state == BT_CONNECTED && | 378 | if (acl->state == BT_CONNECTED && |
379 | (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { | 379 | (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { |
380 | acl->power_save = 1; | ||
381 | hci_conn_enter_active_mode(acl); | ||
382 | |||
380 | if (lmp_esco_capable(hdev)) | 383 | if (lmp_esco_capable(hdev)) |
381 | hci_setup_sync(sco, acl->handle); | 384 | hci_setup_sync(sco, acl->handle); |
382 | else | 385 | else |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 28517bad796c..592da5c909c1 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -1699,6 +1699,7 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu | |||
1699 | break; | 1699 | break; |
1700 | 1700 | ||
1701 | case 0x1c: /* SCO interval rejected */ | 1701 | case 0x1c: /* SCO interval rejected */ |
1702 | case 0x1a: /* Unsupported Remote Feature */ | ||
1702 | case 0x1f: /* Unspecified error */ | 1703 | case 0x1f: /* Unspecified error */ |
1703 | if (conn->out && conn->attempt < 2) { | 1704 | if (conn->out && conn->attempt < 2) { |
1704 | conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | | 1705 | conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 37ba153c4cd4..280529ad9274 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -714,29 +714,9 @@ static void hidp_close(struct hid_device *hid) | |||
714 | static int hidp_parse(struct hid_device *hid) | 714 | static int hidp_parse(struct hid_device *hid) |
715 | { | 715 | { |
716 | struct hidp_session *session = hid->driver_data; | 716 | struct hidp_session *session = hid->driver_data; |
717 | struct hidp_connadd_req *req = session->req; | ||
718 | unsigned char *buf; | ||
719 | int ret; | ||
720 | |||
721 | buf = kmalloc(req->rd_size, GFP_KERNEL); | ||
722 | if (!buf) | ||
723 | return -ENOMEM; | ||
724 | |||
725 | if (copy_from_user(buf, req->rd_data, req->rd_size)) { | ||
726 | kfree(buf); | ||
727 | return -EFAULT; | ||
728 | } | ||
729 | |||
730 | ret = hid_parse_report(session->hid, buf, req->rd_size); | ||
731 | |||
732 | kfree(buf); | ||
733 | |||
734 | if (ret) | ||
735 | return ret; | ||
736 | |||
737 | session->req = NULL; | ||
738 | 717 | ||
739 | return 0; | 718 | return hid_parse_report(session->hid, session->rd_data, |
719 | session->rd_size); | ||
740 | } | 720 | } |
741 | 721 | ||
742 | static int hidp_start(struct hid_device *hid) | 722 | static int hidp_start(struct hid_device *hid) |
@@ -781,12 +761,24 @@ static int hidp_setup_hid(struct hidp_session *session, | |||
781 | bdaddr_t src, dst; | 761 | bdaddr_t src, dst; |
782 | int err; | 762 | int err; |
783 | 763 | ||
764 | session->rd_data = kzalloc(req->rd_size, GFP_KERNEL); | ||
765 | if (!session->rd_data) | ||
766 | return -ENOMEM; | ||
767 | |||
768 | if (copy_from_user(session->rd_data, req->rd_data, req->rd_size)) { | ||
769 | err = -EFAULT; | ||
770 | goto fault; | ||
771 | } | ||
772 | session->rd_size = req->rd_size; | ||
773 | |||
784 | hid = hid_allocate_device(); | 774 | hid = hid_allocate_device(); |
785 | if (IS_ERR(hid)) | 775 | if (IS_ERR(hid)) { |
786 | return PTR_ERR(hid); | 776 | err = PTR_ERR(hid); |
777 | goto fault; | ||
778 | } | ||
787 | 779 | ||
788 | session->hid = hid; | 780 | session->hid = hid; |
789 | session->req = req; | 781 | |
790 | hid->driver_data = session; | 782 | hid->driver_data = session; |
791 | 783 | ||
792 | baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); | 784 | baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); |
@@ -817,6 +809,10 @@ failed: | |||
817 | hid_destroy_device(hid); | 809 | hid_destroy_device(hid); |
818 | session->hid = NULL; | 810 | session->hid = NULL; |
819 | 811 | ||
812 | fault: | ||
813 | kfree(session->rd_data); | ||
814 | session->rd_data = NULL; | ||
815 | |||
820 | return err; | 816 | return err; |
821 | } | 817 | } |
822 | 818 | ||
@@ -911,6 +907,9 @@ unlink: | |||
911 | session->hid = NULL; | 907 | session->hid = NULL; |
912 | } | 908 | } |
913 | 909 | ||
910 | kfree(session->rd_data); | ||
911 | session->rd_data = NULL; | ||
912 | |||
914 | purge: | 913 | purge: |
915 | skb_queue_purge(&session->ctrl_transmit); | 914 | skb_queue_purge(&session->ctrl_transmit); |
916 | skb_queue_purge(&session->intr_transmit); | 915 | 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) |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index fc5ee3296e22..89f4a59eb82b 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -252,7 +252,6 @@ static void rfcomm_session_timeout(unsigned long arg) | |||
252 | BT_DBG("session %p state %ld", s, s->state); | 252 | BT_DBG("session %p state %ld", s, s->state); |
253 | 253 | ||
254 | set_bit(RFCOMM_TIMED_OUT, &s->flags); | 254 | set_bit(RFCOMM_TIMED_OUT, &s->flags); |
255 | rfcomm_session_put(s); | ||
256 | rfcomm_schedule(RFCOMM_SCHED_TIMEO); | 255 | rfcomm_schedule(RFCOMM_SCHED_TIMEO); |
257 | } | 256 | } |
258 | 257 | ||
@@ -1151,7 +1150,11 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) | |||
1151 | break; | 1150 | break; |
1152 | 1151 | ||
1153 | case BT_DISCONN: | 1152 | case BT_DISCONN: |
1154 | rfcomm_session_put(s); | 1153 | /* When socket is closed and we are not RFCOMM |
1154 | * initiator rfcomm_process_rx already calls | ||
1155 | * rfcomm_session_put() */ | ||
1156 | if (s->sock->sk->sk_state != BT_CLOSED) | ||
1157 | rfcomm_session_put(s); | ||
1155 | break; | 1158 | break; |
1156 | } | 1159 | } |
1157 | } | 1160 | } |
@@ -1920,6 +1923,7 @@ static inline void rfcomm_process_sessions(void) | |||
1920 | if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) { | 1923 | if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) { |
1921 | s->state = BT_DISCONN; | 1924 | s->state = BT_DISCONN; |
1922 | rfcomm_send_disc(s, 0); | 1925 | rfcomm_send_disc(s, 0); |
1926 | rfcomm_session_put(s); | ||
1923 | continue; | 1927 | continue; |
1924 | } | 1928 | } |
1925 | 1929 | ||