Lines Matching refs:session

71 static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)  in hidp_copy_session()  argument
75 bacpy(&ci->bdaddr, &session->bdaddr); in hidp_copy_session()
77 ci->flags = session->flags & valid_flags; in hidp_copy_session()
80 if (session->input) { in hidp_copy_session()
81 ci->vendor = session->input->id.vendor; in hidp_copy_session()
82 ci->product = session->input->id.product; in hidp_copy_session()
83 ci->version = session->input->id.version; in hidp_copy_session()
84 if (session->input->name) in hidp_copy_session()
85 strlcpy(ci->name, session->input->name, 128); in hidp_copy_session()
88 } else if (session->hid) { in hidp_copy_session()
89 ci->vendor = session->hid->vendor; in hidp_copy_session()
90 ci->product = session->hid->product; in hidp_copy_session()
91 ci->version = session->hid->version; in hidp_copy_session()
92 strlcpy(ci->name, session->hid->name, 128); in hidp_copy_session()
97 static int hidp_send_message(struct hidp_session *session, struct socket *sock, in hidp_send_message() argument
104 BT_DBG("session %p data %p size %d", session, data, size); in hidp_send_message()
106 if (atomic_read(&session->terminate)) in hidp_send_message()
125 static int hidp_send_ctrl_message(struct hidp_session *session, in hidp_send_ctrl_message() argument
129 return hidp_send_message(session, session->ctrl_sock, in hidp_send_ctrl_message()
130 &session->ctrl_transmit, hdr, data, size); in hidp_send_ctrl_message()
133 static int hidp_send_intr_message(struct hidp_session *session, in hidp_send_intr_message() argument
137 return hidp_send_message(session, session->intr_sock, in hidp_send_intr_message()
138 &session->intr_transmit, hdr, data, size); in hidp_send_intr_message()
144 struct hidp_session *session = input_get_drvdata(dev); in hidp_input_event() local
149 session, type, code, value); in hidp_input_event()
160 if (session->leds == newleds) in hidp_input_event()
163 session->leds = newleds; in hidp_input_event()
169 return hidp_send_intr_message(session, hdr, data, 2); in hidp_input_event()
172 static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb) in hidp_input_report() argument
174 struct input_dev *dev = session->input; in hidp_input_report()
175 unsigned char *keys = session->keys; in hidp_input_report()
232 struct hidp_session *session = hid->driver_data; in hidp_get_raw_report() local
238 if (atomic_read(&session->terminate)) in hidp_get_raw_report()
255 if (mutex_lock_interruptible(&session->report_mutex)) in hidp_get_raw_report()
259 session->waiting_report_type = report_type & HIDP_DATA_RTYPE_MASK; in hidp_get_raw_report()
260 session->waiting_report_number = numbered_reports ? report_number : -1; in hidp_get_raw_report()
261 set_bit(HIDP_WAITING_FOR_RETURN, &session->flags); in hidp_get_raw_report()
263 ret = hidp_send_ctrl_message(session, report_type, data, 1); in hidp_get_raw_report()
269 while (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags) && in hidp_get_raw_report()
270 !atomic_read(&session->terminate)) { in hidp_get_raw_report()
273 res = wait_event_interruptible_timeout(session->report_queue, in hidp_get_raw_report()
274 !test_bit(HIDP_WAITING_FOR_RETURN, &session->flags) in hidp_get_raw_report()
275 || atomic_read(&session->terminate), in hidp_get_raw_report()
289 skb = session->report_return; in hidp_get_raw_report()
295 session->report_return = NULL; in hidp_get_raw_report()
301 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); in hidp_get_raw_report()
302 mutex_unlock(&session->report_mutex); in hidp_get_raw_report()
307 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); in hidp_get_raw_report()
308 mutex_unlock(&session->report_mutex); in hidp_get_raw_report()
316 struct hidp_session *session = hid->driver_data; in hidp_set_raw_report() local
333 if (mutex_lock_interruptible(&session->report_mutex)) in hidp_set_raw_report()
338 set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); in hidp_set_raw_report()
339 ret = hidp_send_ctrl_message(session, report_type, data, count); in hidp_set_raw_report()
344 while (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags) && in hidp_set_raw_report()
345 !atomic_read(&session->terminate)) { in hidp_set_raw_report()
348 res = wait_event_interruptible_timeout(session->report_queue, in hidp_set_raw_report()
349 !test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags) in hidp_set_raw_report()
350 || atomic_read(&session->terminate), in hidp_set_raw_report()
364 if (!session->output_report_success) { in hidp_set_raw_report()
372 clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags); in hidp_set_raw_report()
373 mutex_unlock(&session->report_mutex); in hidp_set_raw_report()
379 struct hidp_session *session = hid->driver_data; in hidp_output_report() local
381 return hidp_send_intr_message(session, in hidp_output_report()
402 struct hidp_session *session = (struct hidp_session *) arg; in hidp_idle_timeout() local
413 session->intr_sock->sk->sk_err = EUNATCH; in hidp_idle_timeout()
414 session->ctrl_sock->sk->sk_err = EUNATCH; in hidp_idle_timeout()
415 wake_up_interruptible(sk_sleep(session->intr_sock->sk)); in hidp_idle_timeout()
416 wake_up_interruptible(sk_sleep(session->ctrl_sock->sk)); in hidp_idle_timeout()
418 hidp_session_terminate(session); in hidp_idle_timeout()
421 static void hidp_set_timer(struct hidp_session *session) in hidp_set_timer() argument
423 if (session->idle_to > 0) in hidp_set_timer()
424 mod_timer(&session->timer, jiffies + HZ * session->idle_to); in hidp_set_timer()
427 static void hidp_del_timer(struct hidp_session *session) in hidp_del_timer() argument
429 if (session->idle_to > 0) in hidp_del_timer()
430 del_timer(&session->timer); in hidp_del_timer()
433 static void hidp_process_report(struct hidp_session *session, in hidp_process_report() argument
439 memcpy(session->input_buf, data, len); in hidp_process_report()
440 hid_input_report(session->hid, type, session->input_buf, len, intr); in hidp_process_report()
443 static void hidp_process_handshake(struct hidp_session *session, in hidp_process_handshake() argument
446 BT_DBG("session %p param 0x%02x", session, param); in hidp_process_handshake()
447 session->output_report_success = 0; /* default condition */ in hidp_process_handshake()
452 session->output_report_success = 1; in hidp_process_handshake()
459 if (test_and_clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags)) in hidp_process_handshake()
460 wake_up_interruptible(&session->report_queue); in hidp_process_handshake()
471 hidp_send_ctrl_message(session, in hidp_process_handshake()
476 hidp_send_ctrl_message(session, in hidp_process_handshake()
482 if (test_and_clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) in hidp_process_handshake()
483 wake_up_interruptible(&session->report_queue); in hidp_process_handshake()
486 static void hidp_process_hid_control(struct hidp_session *session, in hidp_process_hid_control() argument
489 BT_DBG("session %p param 0x%02x", session, param); in hidp_process_hid_control()
493 skb_queue_purge(&session->ctrl_transmit); in hidp_process_hid_control()
494 skb_queue_purge(&session->intr_transmit); in hidp_process_hid_control()
496 hidp_session_terminate(session); in hidp_process_hid_control()
501 static int hidp_process_data(struct hidp_session *session, struct sk_buff *skb, in hidp_process_data() argument
505 BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param); in hidp_process_data()
509 hidp_set_timer(session); in hidp_process_data()
511 if (session->input) in hidp_process_data()
512 hidp_input_report(session, skb); in hidp_process_data()
514 if (session->hid) in hidp_process_data()
515 hidp_process_report(session, HID_INPUT_REPORT, in hidp_process_data()
525 hidp_send_ctrl_message(session, in hidp_process_data()
529 if (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags) && in hidp_process_data()
530 param == session->waiting_report_type) { in hidp_process_data()
531 if (session->waiting_report_number < 0 || in hidp_process_data()
532 session->waiting_report_number == skb->data[0]) { in hidp_process_data()
534 session->report_return = skb; in hidp_process_data()
536 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags); in hidp_process_data()
537 wake_up_interruptible(&session->report_queue); in hidp_process_data()
544 static void hidp_recv_ctrl_frame(struct hidp_session *session, in hidp_recv_ctrl_frame() argument
550 BT_DBG("session %p skb %p len %d", session, skb, skb->len); in hidp_recv_ctrl_frame()
560 hidp_process_handshake(session, param); in hidp_recv_ctrl_frame()
564 hidp_process_hid_control(session, param); in hidp_recv_ctrl_frame()
568 free_skb = hidp_process_data(session, skb, param); in hidp_recv_ctrl_frame()
572 hidp_send_ctrl_message(session, in hidp_recv_ctrl_frame()
581 static void hidp_recv_intr_frame(struct hidp_session *session, in hidp_recv_intr_frame() argument
586 BT_DBG("session %p skb %p len %d", session, skb, skb->len); in hidp_recv_intr_frame()
592 hidp_set_timer(session); in hidp_recv_intr_frame()
594 if (session->input) in hidp_recv_intr_frame()
595 hidp_input_report(session, skb); in hidp_recv_intr_frame()
597 if (session->hid) { in hidp_recv_intr_frame()
598 hidp_process_report(session, HID_INPUT_REPORT, in hidp_recv_intr_frame()
625 static void hidp_process_transmit(struct hidp_session *session, in hidp_process_transmit() argument
632 BT_DBG("session %p", session); in hidp_process_transmit()
640 hidp_session_terminate(session); in hidp_process_transmit()
645 hidp_set_timer(session); in hidp_process_transmit()
650 static int hidp_setup_input(struct hidp_session *session, in hidp_setup_input() argument
660 session->input = input; in hidp_setup_input()
662 input_set_drvdata(input, session); in hidp_setup_input()
697 input->dev.parent = &session->conn->hcon->dev; in hidp_setup_input()
715 struct hidp_session *session = hid->driver_data; in hidp_parse() local
717 return hid_parse_report(session->hid, session->rd_data, in hidp_parse()
718 session->rd_size); in hidp_parse()
728 struct hidp_session *session = hid->driver_data; in hidp_stop() local
730 skb_queue_purge(&session->ctrl_transmit); in hidp_stop()
731 skb_queue_purge(&session->intr_transmit); in hidp_stop()
748 static int hidp_setup_hid(struct hidp_session *session, in hidp_setup_hid() argument
754 session->rd_data = memdup_user(req->rd_data, req->rd_size); in hidp_setup_hid()
755 if (IS_ERR(session->rd_data)) in hidp_setup_hid()
756 return PTR_ERR(session->rd_data); in hidp_setup_hid()
758 session->rd_size = req->rd_size; in hidp_setup_hid()
766 session->hid = hid; in hidp_setup_hid()
768 hid->driver_data = session; in hidp_setup_hid()
779 &l2cap_pi(session->ctrl_sock->sk)->chan->src); in hidp_setup_hid()
785 &l2cap_pi(session->ctrl_sock->sk)->chan->dst); in hidp_setup_hid()
787 hid->dev.parent = &session->conn->hcon->dev; in hidp_setup_hid()
792 hid_destroy_device(session->hid); in hidp_setup_hid()
793 session->hid = NULL; in hidp_setup_hid()
800 kfree(session->rd_data); in hidp_setup_hid()
801 session->rd_data = NULL; in hidp_setup_hid()
807 static int hidp_session_dev_init(struct hidp_session *session, in hidp_session_dev_init() argument
813 ret = hidp_setup_hid(session, req); in hidp_session_dev_init()
818 if (!session->hid) { in hidp_session_dev_init()
819 ret = hidp_setup_input(session, req); in hidp_session_dev_init()
828 static void hidp_session_dev_destroy(struct hidp_session *session) in hidp_session_dev_destroy() argument
830 if (session->hid) in hidp_session_dev_destroy()
831 put_device(&session->hid->dev); in hidp_session_dev_destroy()
832 else if (session->input) in hidp_session_dev_destroy()
833 input_put_device(session->input); in hidp_session_dev_destroy()
835 kfree(session->rd_data); in hidp_session_dev_destroy()
836 session->rd_data = NULL; in hidp_session_dev_destroy()
840 static int hidp_session_dev_add(struct hidp_session *session) in hidp_session_dev_add() argument
849 if (session->hid) { in hidp_session_dev_add()
850 ret = hid_add_device(session->hid); in hidp_session_dev_add()
853 get_device(&session->hid->dev); in hidp_session_dev_add()
854 } else if (session->input) { in hidp_session_dev_add()
855 ret = input_register_device(session->input); in hidp_session_dev_add()
858 input_get_device(session->input); in hidp_session_dev_add()
865 static void hidp_session_dev_del(struct hidp_session *session) in hidp_session_dev_del() argument
867 if (session->hid) in hidp_session_dev_del()
868 hid_destroy_device(session->hid); in hidp_session_dev_del()
869 else if (session->input) in hidp_session_dev_del()
870 input_unregister_device(session->input); in hidp_session_dev_del()
884 struct hidp_session *session = container_of(work, in hidp_session_dev_work() local
889 ret = hidp_session_dev_add(session); in hidp_session_dev_work()
891 atomic_inc(&session->state); in hidp_session_dev_work()
893 hidp_session_terminate(session); in hidp_session_dev_work()
910 struct hidp_session *session; in hidp_session_new() local
917 session = kzalloc(sizeof(*session), GFP_KERNEL); in hidp_session_new()
918 if (!session) in hidp_session_new()
922 kref_init(&session->ref); in hidp_session_new()
923 atomic_set(&session->state, HIDP_SESSION_IDLING); in hidp_session_new()
924 init_waitqueue_head(&session->state_queue); in hidp_session_new()
925 session->flags = req->flags & BIT(HIDP_BLUETOOTH_VENDOR_ID); in hidp_session_new()
928 bacpy(&session->bdaddr, bdaddr); in hidp_session_new()
929 session->conn = l2cap_conn_get(conn); in hidp_session_new()
930 session->user.probe = hidp_session_probe; in hidp_session_new()
931 session->user.remove = hidp_session_remove; in hidp_session_new()
932 INIT_LIST_HEAD(&session->user.list); in hidp_session_new()
933 session->ctrl_sock = ctrl_sock; in hidp_session_new()
934 session->intr_sock = intr_sock; in hidp_session_new()
935 skb_queue_head_init(&session->ctrl_transmit); in hidp_session_new()
936 skb_queue_head_init(&session->intr_transmit); in hidp_session_new()
937 session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl)->chan->omtu, in hidp_session_new()
939 session->intr_mtu = min_t(uint, l2cap_pi(intr)->chan->omtu, in hidp_session_new()
941 session->idle_to = req->idle_to; in hidp_session_new()
944 INIT_WORK(&session->dev_init, hidp_session_dev_work); in hidp_session_new()
945 setup_timer(&session->timer, hidp_idle_timeout, in hidp_session_new()
946 (unsigned long)session); in hidp_session_new()
949 mutex_init(&session->report_mutex); in hidp_session_new()
950 init_waitqueue_head(&session->report_queue); in hidp_session_new()
952 ret = hidp_session_dev_init(session, req); in hidp_session_new()
956 get_file(session->intr_sock->file); in hidp_session_new()
957 get_file(session->ctrl_sock->file); in hidp_session_new()
958 *out = session; in hidp_session_new()
962 l2cap_conn_put(session->conn); in hidp_session_new()
963 kfree(session); in hidp_session_new()
968 static void hidp_session_get(struct hidp_session *session) in hidp_session_get() argument
970 kref_get(&session->ref); in hidp_session_get()
976 struct hidp_session *session = container_of(ref, struct hidp_session, in session_free() local
979 hidp_session_dev_destroy(session); in session_free()
980 skb_queue_purge(&session->ctrl_transmit); in session_free()
981 skb_queue_purge(&session->intr_transmit); in session_free()
982 fput(session->intr_sock->file); in session_free()
983 fput(session->ctrl_sock->file); in session_free()
984 l2cap_conn_put(session->conn); in session_free()
985 kfree(session); in session_free()
989 static void hidp_session_put(struct hidp_session *session) in hidp_session_put() argument
991 kref_put(&session->ref, session_free); in hidp_session_put()
1002 struct hidp_session *session; in __hidp_session_find() local
1004 list_for_each_entry(session, &hidp_session_list, list) { in __hidp_session_find()
1005 if (!bacmp(bdaddr, &session->bdaddr)) in __hidp_session_find()
1006 return session; in __hidp_session_find()
1019 struct hidp_session *session; in hidp_session_find() local
1023 session = __hidp_session_find(bdaddr); in hidp_session_find()
1024 if (session) in hidp_session_find()
1025 hidp_session_get(session); in hidp_session_find()
1029 return session; in hidp_session_find()
1039 static int hidp_session_start_sync(struct hidp_session *session) in hidp_session_start_sync() argument
1043 if (session->hid) { in hidp_session_start_sync()
1044 vendor = session->hid->vendor; in hidp_session_start_sync()
1045 product = session->hid->product; in hidp_session_start_sync()
1046 } else if (session->input) { in hidp_session_start_sync()
1047 vendor = session->input->id.vendor; in hidp_session_start_sync()
1048 product = session->input->id.product; in hidp_session_start_sync()
1054 session->task = kthread_run(hidp_session_thread, session, in hidp_session_start_sync()
1056 if (IS_ERR(session->task)) in hidp_session_start_sync()
1057 return PTR_ERR(session->task); in hidp_session_start_sync()
1059 while (atomic_read(&session->state) <= HIDP_SESSION_IDLING) in hidp_session_start_sync()
1060 wait_event(session->state_queue, in hidp_session_start_sync()
1061 atomic_read(&session->state) > HIDP_SESSION_IDLING); in hidp_session_start_sync()
1073 static void hidp_session_terminate(struct hidp_session *session) in hidp_session_terminate() argument
1075 atomic_inc(&session->terminate); in hidp_session_terminate()
1076 wake_up_process(session->task); in hidp_session_terminate()
1091 struct hidp_session *session = container_of(user, in hidp_session_probe() local
1100 s = __hidp_session_find(&session->bdaddr); in hidp_session_probe()
1106 if (session->input) { in hidp_session_probe()
1107 ret = hidp_session_dev_add(session); in hidp_session_probe()
1112 ret = hidp_session_start_sync(session); in hidp_session_probe()
1117 if (session->input) in hidp_session_probe()
1118 atomic_inc(&session->state); in hidp_session_probe()
1120 schedule_work(&session->dev_init); in hidp_session_probe()
1122 hidp_session_get(session); in hidp_session_probe()
1123 list_add(&session->list, &hidp_session_list); in hidp_session_probe()
1128 if (session->input) in hidp_session_probe()
1129 hidp_session_dev_del(session); in hidp_session_probe()
1152 struct hidp_session *session = container_of(user, in hidp_session_remove() local
1158 hidp_session_terminate(session); in hidp_session_remove()
1160 cancel_work_sync(&session->dev_init); in hidp_session_remove()
1161 if (session->input || in hidp_session_remove()
1162 atomic_read(&session->state) > HIDP_SESSION_PREPARING) in hidp_session_remove()
1163 hidp_session_dev_del(session); in hidp_session_remove()
1165 list_del(&session->list); in hidp_session_remove()
1169 hidp_session_put(session); in hidp_session_remove()
1178 static void hidp_session_run(struct hidp_session *session) in hidp_session_run() argument
1180 struct sock *ctrl_sk = session->ctrl_sock->sk; in hidp_session_run()
1181 struct sock *intr_sk = session->intr_sock->sk; in hidp_session_run()
1197 if (atomic_read(&session->terminate)) in hidp_session_run()
1208 hidp_recv_intr_frame(session, skb); in hidp_session_run()
1214 hidp_process_transmit(session, &session->intr_transmit, in hidp_session_run()
1215 session->intr_sock); in hidp_session_run()
1221 hidp_recv_ctrl_frame(session, skb); in hidp_session_run()
1227 hidp_process_transmit(session, &session->ctrl_transmit, in hidp_session_run()
1228 session->ctrl_sock); in hidp_session_run()
1233 atomic_inc(&session->terminate); in hidp_session_run()
1246 struct hidp_session *session = arg; in hidp_session_thread() local
1249 BT_DBG("session %p", session); in hidp_session_thread()
1252 hidp_session_get(session); in hidp_session_thread()
1255 hidp_set_timer(session); in hidp_session_thread()
1259 add_wait_queue(sk_sleep(session->ctrl_sock->sk), &ctrl_wait); in hidp_session_thread()
1260 add_wait_queue(sk_sleep(session->intr_sock->sk), &intr_wait); in hidp_session_thread()
1266 atomic_inc(&session->state); in hidp_session_thread()
1267 wake_up(&session->state_queue); in hidp_session_thread()
1270 hidp_session_run(session); in hidp_session_thread()
1273 remove_wait_queue(sk_sleep(session->intr_sock->sk), &intr_wait); in hidp_session_thread()
1274 remove_wait_queue(sk_sleep(session->intr_sock->sk), &ctrl_wait); in hidp_session_thread()
1275 wake_up_interruptible(&session->report_queue); in hidp_session_thread()
1276 hidp_del_timer(session); in hidp_session_thread()
1286 l2cap_unregister_user(session->conn, &session->user); in hidp_session_thread()
1287 hidp_session_put(session); in hidp_session_thread()
1298 struct hidp_session *session; in hidp_verify_sockets() local
1318 session = hidp_session_find(&ctrl_chan->dst); in hidp_verify_sockets()
1319 if (session) { in hidp_verify_sockets()
1320 hidp_session_put(session); in hidp_verify_sockets()
1333 struct hidp_session *session; in hidp_connection_add() local
1355 ret = hidp_session_new(&session, &chan->dst, ctrl_sock, in hidp_connection_add()
1360 ret = l2cap_register_user(conn, &session->user); in hidp_connection_add()
1367 hidp_session_put(session); in hidp_connection_add()
1376 struct hidp_session *session; in hidp_connection_del() local
1381 session = hidp_session_find(&req->bdaddr); in hidp_connection_del()
1382 if (!session) in hidp_connection_del()
1386 hidp_send_ctrl_message(session, in hidp_connection_del()
1391 l2cap_unregister_user(session->conn, &session->user); in hidp_connection_del()
1393 hidp_session_put(session); in hidp_connection_del()
1400 struct hidp_session *session; in hidp_get_connlist() local
1407 list_for_each_entry(session, &hidp_session_list, list) { in hidp_get_connlist()
1410 hidp_copy_session(session, &ci); in hidp_get_connlist()
1430 struct hidp_session *session; in hidp_get_conninfo() local
1432 session = hidp_session_find(&ci->bdaddr); in hidp_get_conninfo()
1433 if (session) { in hidp_get_conninfo()
1434 hidp_copy_session(session, ci); in hidp_get_conninfo()
1435 hidp_session_put(session); in hidp_get_conninfo()
1438 return session ? 0 : -ENOENT; in hidp_get_conninfo()