aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorAlan Ott <alan@signal11.us>2011-01-18 03:04:37 -0500
committerJiri Kosina <jkosina@suse.cz>2011-02-11 09:05:49 -0500
commit0f69dca20f77dc374b67e17e10b30cec37e778c4 (patch)
tree91af68ffb00e8e0fa70ab636a51abdb6260547a3 /net/bluetooth
parent581548db3b3c0f6e25b500329eb02e3c72e7acbe (diff)
HID: bt: Move hid_add_device() call to after hidp_session() has started.
Move the call to hid_add_device() (which calls a device's probe() function) to after the kernel_thread() call which starts the hidp_session() thread. This ensures the Bluetooth receive socket is fully running by the time a device's probe() function is called. This way, a device can communicate (send and receive) with the Bluetooth device from its probe() function. Signed-off-by: Alan Ott <alan@signal11.us> Acked-by: Gustavo F. Padovan <padovan@profusion.mobi> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hidp/core.c28
-rw-r--r--net/bluetooth/hidp/hidp.h3
2 files changed, 23 insertions, 8 deletions
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 29544c21f4b5..67cc4bc82c68 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -563,6 +563,8 @@ static int hidp_session(void *arg)
563 init_waitqueue_entry(&intr_wait, current); 563 init_waitqueue_entry(&intr_wait, current);
564 add_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); 564 add_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait);
565 add_wait_queue(sk_sleep(intr_sk), &intr_wait); 565 add_wait_queue(sk_sleep(intr_sk), &intr_wait);
566 session->waiting_for_startup = 0;
567 wake_up_interruptible(&session->startup_queue);
566 while (!atomic_read(&session->terminate)) { 568 while (!atomic_read(&session->terminate)) {
567 set_current_state(TASK_INTERRUPTIBLE); 569 set_current_state(TASK_INTERRUPTIBLE);
568 570
@@ -754,6 +756,8 @@ static struct hid_ll_driver hidp_hid_driver = {
754 .hidinput_input_event = hidp_hidinput_event, 756 .hidinput_input_event = hidp_hidinput_event,
755}; 757};
756 758
759/* This function sets up the hid device. It does not add it
760 to the HID system. That is done in hidp_add_connection(). */
757static int hidp_setup_hid(struct hidp_session *session, 761static int hidp_setup_hid(struct hidp_session *session,
758 struct hidp_connadd_req *req) 762 struct hidp_connadd_req *req)
759{ 763{
@@ -795,16 +799,8 @@ static int hidp_setup_hid(struct hidp_session *session,
795 799
796 hid->hid_output_raw_report = hidp_output_raw_report; 800 hid->hid_output_raw_report = hidp_output_raw_report;
797 801
798 err = hid_add_device(hid);
799 if (err < 0)
800 goto failed;
801
802 return 0; 802 return 0;
803 803
804failed:
805 hid_destroy_device(hid);
806 session->hid = NULL;
807
808fault: 804fault:
809 kfree(session->rd_data); 805 kfree(session->rd_data);
810 session->rd_data = NULL; 806 session->rd_data = NULL;
@@ -853,6 +849,8 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
853 skb_queue_head_init(&session->ctrl_transmit); 849 skb_queue_head_init(&session->ctrl_transmit);
854 skb_queue_head_init(&session->intr_transmit); 850 skb_queue_head_init(&session->intr_transmit);
855 851
852 init_waitqueue_head(&session->startup_queue);
853 session->waiting_for_startup = 1;
856 session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID); 854 session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);
857 session->idle_to = req->idle_to; 855 session->idle_to = req->idle_to;
858 856
@@ -875,6 +873,14 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
875 err = kernel_thread(hidp_session, session, CLONE_KERNEL); 873 err = kernel_thread(hidp_session, session, CLONE_KERNEL);
876 if (err < 0) 874 if (err < 0)
877 goto unlink; 875 goto unlink;
876 while (session->waiting_for_startup) {
877 wait_event_interruptible(session->startup_queue,
878 !session->waiting_for_startup);
879 }
880
881 err = hid_add_device(session->hid);
882 if (err < 0)
883 goto err_add_device;
878 884
879 if (session->input) { 885 if (session->input) {
880 hidp_send_ctrl_message(session, 886 hidp_send_ctrl_message(session,
@@ -888,6 +894,12 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
888 up_write(&hidp_session_sem); 894 up_write(&hidp_session_sem);
889 return 0; 895 return 0;
890 896
897err_add_device:
898 hid_destroy_device(session->hid);
899 session->hid = NULL;
900 atomic_inc(&session->terminate);
901 hidp_schedule(session);
902
891unlink: 903unlink:
892 hidp_del_timer(session); 904 hidp_del_timer(session);
893 905
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h
index 8d934a19da0a..2cc35dc8fa03 100644
--- a/net/bluetooth/hidp/hidp.h
+++ b/net/bluetooth/hidp/hidp.h
@@ -157,6 +157,9 @@ struct hidp_session {
157 /* Report descriptor */ 157 /* Report descriptor */
158 __u8 *rd_data; 158 __u8 *rd_data;
159 uint rd_size; 159 uint rd_size;
160
161 wait_queue_head_t startup_queue;
162 int waiting_for_startup;
160}; 163};
161 164
162static inline void hidp_schedule(struct hidp_session *session) 165static inline void hidp_schedule(struct hidp_session *session)