Lines Matching refs:session

72 static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)  in hidp_copy_session()  argument
76 bacpy(&ci->bdaddr, &session->bdaddr); in hidp_copy_session()
78 ci->flags = session->flags & valid_flags; in hidp_copy_session()
81 if (session->input) { in hidp_copy_session()
82 ci->vendor = session->input->id.vendor; in hidp_copy_session()
83 ci->product = session->input->id.product; in hidp_copy_session()
84 ci->version = session->input->id.version; in hidp_copy_session()
85 if (session->input->name) in hidp_copy_session()
86 strlcpy(ci->name, session->input->name, 128); in hidp_copy_session()
89 } else if (session->hid) { in hidp_copy_session()
90 ci->vendor = session->hid->vendor; in hidp_copy_session()
91 ci->product = session->hid->product; in hidp_copy_session()
92 ci->version = session->hid->version; in hidp_copy_session()
93 strlcpy(ci->name, session->hid->name, 128); in hidp_copy_session()
98 static int hidp_send_message(struct hidp_session *session, struct socket *sock, in hidp_send_message() argument
105 BT_DBG("session %p data %p size %d", session, data, size); in hidp_send_message()
107 if (atomic_read(&session->terminate)) in hidp_send_message()
126 static int hidp_send_ctrl_message(struct hidp_session *session, in hidp_send_ctrl_message() argument
130 return hidp_send_message(session, session->ctrl_sock, in hidp_send_ctrl_message()
131 &session->ctrl_transmit, hdr, data, size); in hidp_send_ctrl_message()
134 static int hidp_send_intr_message(struct hidp_session *session, in hidp_send_intr_message() argument
138 return hidp_send_message(session, session->intr_sock, in hidp_send_intr_message()
139 &session->intr_transmit, hdr, data, size); in hidp_send_intr_message()
145 struct hidp_session *session = input_get_drvdata(dev); in hidp_input_event() local
150 session, type, code, value); in hidp_input_event()
161 if (session->leds == newleds) in hidp_input_event()
164 session->leds = newleds; in hidp_input_event()
170 return hidp_send_intr_message(session, hdr, data, 2); in hidp_input_event()
173 static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb) in hidp_input_report() argument
175 struct input_dev *dev = session->input; in hidp_input_report()
176 unsigned char *keys = session->keys; in hidp_input_report()
233 struct hidp_session *session = hid->driver_data; in hidp_get_raw_report() local
239 if (atomic_read(&session->terminate)) in hidp_get_raw_report()
256 if (mutex_lock_interruptible(&session->report_mutex)) in hidp_get_raw_report()
260 session->waiting_report_type = report_type & HIDP_DATA_RTYPE_MASK; in hidp_get_raw_report()
261 session->waiting_report_number = numbered_reports ? report_number : -1; in hidp_get_raw_report()
262 set_bit(HIDP_WAITING_FOR_RETURN, &session->flags); in hidp_get_raw_report()
264 ret = hidp_send_ctrl_message(session, report_type, data, 1); in hidp_get_raw_report()
270 while (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags) && in hidp_get_raw_report()
271 !atomic_read(&session->terminate)) { in hidp_get_raw_report()
274 res = wait_event_interruptible_timeout(session->report_queue, in hidp_get_raw_report()
275 !test_bit(HIDP_WAITING_FOR_RETURN, &session->flags) in hidp_get_raw_report()
276 || atomic_read(&session->terminate), in hidp_get_raw_report()
290 skb = session->report_return; in hidp_get_raw_report()
296 session->report_return = NULL; in hidp_get_raw_report()
302 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); in hidp_get_raw_report()
303 mutex_unlock(&session->report_mutex); in hidp_get_raw_report()
308 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); in hidp_get_raw_report()
309 mutex_unlock(&session->report_mutex); in hidp_get_raw_report()
317 struct hidp_session *session = hid->driver_data; in hidp_set_raw_report() local
334 if (mutex_lock_interruptible(&session->report_mutex)) in hidp_set_raw_report()
339 set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); in hidp_set_raw_report()
340 ret = hidp_send_ctrl_message(session, report_type, data, count); in hidp_set_raw_report()
345 while (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags) && in hidp_set_raw_report()
346 !atomic_read(&session->terminate)) { in hidp_set_raw_report()
349 res = wait_event_interruptible_timeout(session->report_queue, in hidp_set_raw_report()
350 !test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags) in hidp_set_raw_report()
351 || atomic_read(&session->terminate), in hidp_set_raw_report()
365 if (!session->output_report_success) { in hidp_set_raw_report()
373 clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); in hidp_set_raw_report()
374 mutex_unlock(&session->report_mutex); in hidp_set_raw_report()
380 struct hidp_session *session = hid->driver_data; in hidp_output_report() local
382 return hidp_send_intr_message(session, in hidp_output_report()
403 struct hidp_session *session = from_timer(session, t, timer); in hidp_idle_timeout() local
414 session->intr_sock->sk->sk_err = EUNATCH; in hidp_idle_timeout()
415 session->ctrl_sock->sk->sk_err = EUNATCH; in hidp_idle_timeout()
416 wake_up_interruptible(sk_sleep(session->intr_sock->sk)); in hidp_idle_timeout()
417 wake_up_interruptible(sk_sleep(session->ctrl_sock->sk)); in hidp_idle_timeout()
419 hidp_session_terminate(session); in hidp_idle_timeout()
422 static void hidp_set_timer(struct hidp_session *session) in hidp_set_timer() argument
424 if (session->idle_to > 0) in hidp_set_timer()
425 mod_timer(&session->timer, jiffies + HZ * session->idle_to); in hidp_set_timer()
428 static void hidp_del_timer(struct hidp_session *session) in hidp_del_timer() argument
430 if (session->idle_to > 0) in hidp_del_timer()
431 del_timer(&session->timer); in hidp_del_timer()
434 static void hidp_process_report(struct hidp_session *session, int type, in hidp_process_report() argument
440 memcpy(session->input_buf, data, len); in hidp_process_report()
441 hid_input_report(session->hid, type, session->input_buf, len, intr); in hidp_process_report()
444 static void hidp_process_handshake(struct hidp_session *session, in hidp_process_handshake() argument
447 BT_DBG("session %p param 0x%02x", session, param); in hidp_process_handshake()
448 session->output_report_success = 0; /* default condition */ in hidp_process_handshake()
453 session->output_report_success = 1; in hidp_process_handshake()
460 if (test_and_clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags)) in hidp_process_handshake()
461 wake_up_interruptible(&session->report_queue); in hidp_process_handshake()
472 hidp_send_ctrl_message(session, in hidp_process_handshake()
477 hidp_send_ctrl_message(session, in hidp_process_handshake()
483 if (test_and_clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) in hidp_process_handshake()
484 wake_up_interruptible(&session->report_queue); in hidp_process_handshake()
487 static void hidp_process_hid_control(struct hidp_session *session, in hidp_process_hid_control() argument
490 BT_DBG("session %p param 0x%02x", session, param); in hidp_process_hid_control()
494 skb_queue_purge(&session->ctrl_transmit); in hidp_process_hid_control()
495 skb_queue_purge(&session->intr_transmit); in hidp_process_hid_control()
497 hidp_session_terminate(session); in hidp_process_hid_control()
502 static int hidp_process_data(struct hidp_session *session, struct sk_buff *skb, in hidp_process_data() argument
506 BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param); in hidp_process_data()
510 hidp_set_timer(session); in hidp_process_data()
512 if (session->input) in hidp_process_data()
513 hidp_input_report(session, skb); in hidp_process_data()
515 if (session->hid) in hidp_process_data()
516 hidp_process_report(session, HID_INPUT_REPORT, in hidp_process_data()
526 hidp_send_ctrl_message(session, in hidp_process_data()
530 if (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags) && in hidp_process_data()
531 param == session->waiting_report_type) { in hidp_process_data()
532 if (session->waiting_report_number < 0 || in hidp_process_data()
533 session->waiting_report_number == skb->data[0]) { in hidp_process_data()
535 session->report_return = skb; in hidp_process_data()
537 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); in hidp_process_data()
538 wake_up_interruptible(&session->report_queue); in hidp_process_data()
545 static void hidp_recv_ctrl_frame(struct hidp_session *session, in hidp_recv_ctrl_frame() argument
551 BT_DBG("session %p skb %p len %d", session, skb, skb->len); in hidp_recv_ctrl_frame()
561 hidp_process_handshake(session, param); in hidp_recv_ctrl_frame()
565 hidp_process_hid_control(session, param); in hidp_recv_ctrl_frame()
569 free_skb = hidp_process_data(session, skb, param); in hidp_recv_ctrl_frame()
573 hidp_send_ctrl_message(session, in hidp_recv_ctrl_frame()
582 static void hidp_recv_intr_frame(struct hidp_session *session, in hidp_recv_intr_frame() argument
587 BT_DBG("session %p skb %p len %d", session, skb, skb->len); in hidp_recv_intr_frame()
593 hidp_set_timer(session); in hidp_recv_intr_frame()
595 if (session->input) in hidp_recv_intr_frame()
596 hidp_input_report(session, skb); in hidp_recv_intr_frame()
598 if (session->hid) { in hidp_recv_intr_frame()
599 hidp_process_report(session, HID_INPUT_REPORT, in hidp_recv_intr_frame()
626 static void hidp_process_transmit(struct hidp_session *session, in hidp_process_transmit() argument
633 BT_DBG("session %p", session); in hidp_process_transmit()
641 hidp_session_terminate(session); in hidp_process_transmit()
646 hidp_set_timer(session); in hidp_process_transmit()
651 static int hidp_setup_input(struct hidp_session *session, in hidp_setup_input() argument
661 session->input = input; in hidp_setup_input()
663 input_set_drvdata(input, session); in hidp_setup_input()
698 input->dev.parent = &session->conn->hcon->dev; in hidp_setup_input()
716 struct hidp_session *session = hid->driver_data; in hidp_parse() local
718 return hid_parse_report(session->hid, session->rd_data, in hidp_parse()
719 session->rd_size); in hidp_parse()
729 struct hidp_session *session = hid->driver_data; in hidp_stop() local
731 skb_queue_purge(&session->ctrl_transmit); in hidp_stop()
732 skb_queue_purge(&session->intr_transmit); in hidp_stop()
750 static int hidp_setup_hid(struct hidp_session *session, in hidp_setup_hid() argument
756 session->rd_data = memdup_user(req->rd_data, req->rd_size); in hidp_setup_hid()
757 if (IS_ERR(session->rd_data)) in hidp_setup_hid()
758 return PTR_ERR(session->rd_data); in hidp_setup_hid()
760 session->rd_size = req->rd_size; in hidp_setup_hid()
768 session->hid = hid; in hidp_setup_hid()
770 hid->driver_data = session; in hidp_setup_hid()
781 &l2cap_pi(session->ctrl_sock->sk)->chan->src); in hidp_setup_hid()
787 &l2cap_pi(session->ctrl_sock->sk)->chan->dst); in hidp_setup_hid()
789 hid->dev.parent = &session->conn->hcon->dev; in hidp_setup_hid()
794 hid_destroy_device(session->hid); in hidp_setup_hid()
795 session->hid = NULL; in hidp_setup_hid()
802 kfree(session->rd_data); in hidp_setup_hid()
803 session->rd_data = NULL; in hidp_setup_hid()
809 static int hidp_session_dev_init(struct hidp_session *session, in hidp_session_dev_init() argument
815 ret = hidp_setup_hid(session, req); in hidp_session_dev_init()
820 if (!session->hid) { in hidp_session_dev_init()
821 ret = hidp_setup_input(session, req); in hidp_session_dev_init()
830 static void hidp_session_dev_destroy(struct hidp_session *session) in hidp_session_dev_destroy() argument
832 if (session->hid) in hidp_session_dev_destroy()
833 put_device(&session->hid->dev); in hidp_session_dev_destroy()
834 else if (session->input) in hidp_session_dev_destroy()
835 input_put_device(session->input); in hidp_session_dev_destroy()
837 kfree(session->rd_data); in hidp_session_dev_destroy()
838 session->rd_data = NULL; in hidp_session_dev_destroy()
842 static int hidp_session_dev_add(struct hidp_session *session) in hidp_session_dev_add() argument
851 if (session->hid) { in hidp_session_dev_add()
852 ret = hid_add_device(session->hid); in hidp_session_dev_add()
855 get_device(&session->hid->dev); in hidp_session_dev_add()
856 } else if (session->input) { in hidp_session_dev_add()
857 ret = input_register_device(session->input); in hidp_session_dev_add()
860 input_get_device(session->input); in hidp_session_dev_add()
867 static void hidp_session_dev_del(struct hidp_session *session) in hidp_session_dev_del() argument
869 if (session->hid) in hidp_session_dev_del()
870 hid_destroy_device(session->hid); in hidp_session_dev_del()
871 else if (session->input) in hidp_session_dev_del()
872 input_unregister_device(session->input); in hidp_session_dev_del()
886 struct hidp_session *session = container_of(work, in hidp_session_dev_work() local
891 ret = hidp_session_dev_add(session); in hidp_session_dev_work()
893 atomic_inc(&session->state); in hidp_session_dev_work()
895 hidp_session_terminate(session); in hidp_session_dev_work()
912 struct hidp_session *session; in hidp_session_new() local
919 session = kzalloc(sizeof(*session), GFP_KERNEL); in hidp_session_new()
920 if (!session) in hidp_session_new()
924 kref_init(&session->ref); in hidp_session_new()
925 atomic_set(&session->state, HIDP_SESSION_IDLING); in hidp_session_new()
926 init_waitqueue_head(&session->state_queue); in hidp_session_new()
927 session->flags = req->flags & BIT(HIDP_BLUETOOTH_VENDOR_ID); in hidp_session_new()
930 bacpy(&session->bdaddr, bdaddr); in hidp_session_new()
931 session->conn = l2cap_conn_get(conn); in hidp_session_new()
932 session->user.probe = hidp_session_probe; in hidp_session_new()
933 session->user.remove = hidp_session_remove; in hidp_session_new()
934 INIT_LIST_HEAD(&session->user.list); in hidp_session_new()
935 session->ctrl_sock = ctrl_sock; in hidp_session_new()
936 session->intr_sock = intr_sock; in hidp_session_new()
937 skb_queue_head_init(&session->ctrl_transmit); in hidp_session_new()
938 skb_queue_head_init(&session->intr_transmit); in hidp_session_new()
939 session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl)->chan->omtu, in hidp_session_new()
941 session->intr_mtu = min_t(uint, l2cap_pi(intr)->chan->omtu, in hidp_session_new()
943 session->idle_to = req->idle_to; in hidp_session_new()
946 INIT_WORK(&session->dev_init, hidp_session_dev_work); in hidp_session_new()
947 timer_setup(&session->timer, hidp_idle_timeout, 0); in hidp_session_new()
950 mutex_init(&session->report_mutex); in hidp_session_new()
951 init_waitqueue_head(&session->report_queue); in hidp_session_new()
953 ret = hidp_session_dev_init(session, req); in hidp_session_new()
957 get_file(session->intr_sock->file); in hidp_session_new()
958 get_file(session->ctrl_sock->file); in hidp_session_new()
959 *out = session; in hidp_session_new()
963 l2cap_conn_put(session->conn); in hidp_session_new()
964 kfree(session); in hidp_session_new()
969 static void hidp_session_get(struct hidp_session *session) in hidp_session_get() argument
971 kref_get(&session->ref); in hidp_session_get()
977 struct hidp_session *session = container_of(ref, struct hidp_session, in session_free() local
980 hidp_session_dev_destroy(session); in session_free()
981 skb_queue_purge(&session->ctrl_transmit); in session_free()
982 skb_queue_purge(&session->intr_transmit); in session_free()
983 fput(session->intr_sock->file); in session_free()
984 fput(session->ctrl_sock->file); in session_free()
985 l2cap_conn_put(session->conn); in session_free()
986 kfree(session); in session_free()
990 static void hidp_session_put(struct hidp_session *session) in hidp_session_put() argument
992 kref_put(&session->ref, session_free); in hidp_session_put()
1003 struct hidp_session *session; in __hidp_session_find() local
1005 list_for_each_entry(session, &hidp_session_list, list) { in __hidp_session_find()
1006 if (!bacmp(bdaddr, &session->bdaddr)) in __hidp_session_find()
1007 return session; in __hidp_session_find()
1020 struct hidp_session *session; in hidp_session_find() local
1024 session = __hidp_session_find(bdaddr); in hidp_session_find()
1025 if (session) in hidp_session_find()
1026 hidp_session_get(session); in hidp_session_find()
1030 return session; in hidp_session_find()
1040 static int hidp_session_start_sync(struct hidp_session *session) in hidp_session_start_sync() argument
1044 if (session->hid) { in hidp_session_start_sync()
1045 vendor = session->hid->vendor; in hidp_session_start_sync()
1046 product = session->hid->product; in hidp_session_start_sync()
1047 } else if (session->input) { in hidp_session_start_sync()
1048 vendor = session->input->id.vendor; in hidp_session_start_sync()
1049 product = session->input->id.product; in hidp_session_start_sync()
1055 session->task = kthread_run(hidp_session_thread, session, in hidp_session_start_sync()
1057 if (IS_ERR(session->task)) in hidp_session_start_sync()
1058 return PTR_ERR(session->task); in hidp_session_start_sync()
1060 while (atomic_read(&session->state) <= HIDP_SESSION_IDLING) in hidp_session_start_sync()
1061 wait_event(session->state_queue, in hidp_session_start_sync()
1062 atomic_read(&session->state) > HIDP_SESSION_IDLING); in hidp_session_start_sync()
1074 static void hidp_session_terminate(struct hidp_session *session) in hidp_session_terminate() argument
1076 atomic_inc(&session->terminate); in hidp_session_terminate()
1092 struct hidp_session *session = container_of(user, in hidp_session_probe() local
1101 s = __hidp_session_find(&session->bdaddr); in hidp_session_probe()
1107 if (session->input) { in hidp_session_probe()
1108 ret = hidp_session_dev_add(session); in hidp_session_probe()
1113 ret = hidp_session_start_sync(session); in hidp_session_probe()
1118 if (session->input) in hidp_session_probe()
1119 atomic_inc(&session->state); in hidp_session_probe()
1121 schedule_work(&session->dev_init); in hidp_session_probe()
1123 hidp_session_get(session); in hidp_session_probe()
1124 list_add(&session->list, &hidp_session_list); in hidp_session_probe()
1129 if (session->input) in hidp_session_probe()
1130 hidp_session_dev_del(session); in hidp_session_probe()
1153 struct hidp_session *session = container_of(user, in hidp_session_remove() local
1159 hidp_session_terminate(session); in hidp_session_remove()
1161 cancel_work_sync(&session->dev_init); in hidp_session_remove()
1162 if (session->input || in hidp_session_remove()
1163 atomic_read(&session->state) > HIDP_SESSION_PREPARING) in hidp_session_remove()
1164 hidp_session_dev_del(session); in hidp_session_remove()
1166 list_del(&session->list); in hidp_session_remove()
1170 hidp_session_put(session); in hidp_session_remove()
1179 static void hidp_session_run(struct hidp_session *session) in hidp_session_run() argument
1181 struct sock *ctrl_sk = session->ctrl_sock->sk; in hidp_session_run()
1182 struct sock *intr_sk = session->intr_sock->sk; in hidp_session_run()
1198 if (atomic_read(&session->terminate)) in hidp_session_run()
1209 hidp_recv_intr_frame(session, skb); in hidp_session_run()
1215 hidp_process_transmit(session, &session->intr_transmit, in hidp_session_run()
1216 session->intr_sock); in hidp_session_run()
1222 hidp_recv_ctrl_frame(session, skb); in hidp_session_run()
1228 hidp_process_transmit(session, &session->ctrl_transmit, in hidp_session_run()
1229 session->ctrl_sock); in hidp_session_run()
1235 atomic_inc(&session->terminate); in hidp_session_run()
1258 struct hidp_session *session = arg; in hidp_session_thread() local
1262 BT_DBG("session %p", session); in hidp_session_thread()
1265 hidp_session_get(session); in hidp_session_thread()
1268 hidp_set_timer(session); in hidp_session_thread()
1270 add_wait_queue(sk_sleep(session->ctrl_sock->sk), &ctrl_wait); in hidp_session_thread()
1271 add_wait_queue(sk_sleep(session->intr_sock->sk), &intr_wait); in hidp_session_thread()
1277 atomic_inc(&session->state); in hidp_session_thread()
1278 wake_up(&session->state_queue); in hidp_session_thread()
1281 hidp_session_run(session); in hidp_session_thread()
1284 remove_wait_queue(sk_sleep(session->intr_sock->sk), &intr_wait); in hidp_session_thread()
1285 remove_wait_queue(sk_sleep(session->intr_sock->sk), &ctrl_wait); in hidp_session_thread()
1286 wake_up_interruptible(&session->report_queue); in hidp_session_thread()
1287 hidp_del_timer(session); in hidp_session_thread()
1297 l2cap_unregister_user(session->conn, &session->user); in hidp_session_thread()
1298 hidp_session_put(session); in hidp_session_thread()
1309 struct hidp_session *session; in hidp_verify_sockets() local
1329 session = hidp_session_find(&ctrl_chan->dst); in hidp_verify_sockets()
1330 if (session) { in hidp_verify_sockets()
1331 hidp_session_put(session); in hidp_verify_sockets()
1344 struct hidp_session *session; in hidp_connection_add() local
1366 ret = hidp_session_new(&session, &chan->dst, ctrl_sock, in hidp_connection_add()
1371 ret = l2cap_register_user(conn, &session->user); in hidp_connection_add()
1378 hidp_session_put(session); in hidp_connection_add()
1387 struct hidp_session *session; in hidp_connection_del() local
1392 session = hidp_session_find(&req->bdaddr); in hidp_connection_del()
1393 if (!session) in hidp_connection_del()
1397 hidp_send_ctrl_message(session, in hidp_connection_del()
1402 l2cap_unregister_user(session->conn, &session->user); in hidp_connection_del()
1404 hidp_session_put(session); in hidp_connection_del()
1411 struct hidp_session *session; in hidp_get_connlist() local
1418 list_for_each_entry(session, &hidp_session_list, list) { in hidp_get_connlist()
1421 hidp_copy_session(session, &ci); in hidp_get_connlist()
1441 struct hidp_session *session; in hidp_get_conninfo() local
1443 session = hidp_session_find(&ci->bdaddr); in hidp_get_conninfo()
1444 if (session) { in hidp_get_conninfo()
1445 hidp_copy_session(session, ci); in hidp_get_conninfo()
1446 hidp_session_put(session); in hidp_get_conninfo()
1449 return session ? 0 : -ENOENT; in hidp_get_conninfo()