diff -Naur linux-2.6.24.4/net/bluetooth/hidp.orig/core.c linux-2.6.24.4/net/bluetooth/hidp/core.c --- linux-2.6.24.4/net/bluetooth/hidp.orig/core.c 2008-03-24 19:49:18.000000000 +0100 +++ linux-2.6.24.4/net/bluetooth/hidp/core.c 2008-04-01 11:14:05.000000000 +0200 @@ -378,8 +378,12 @@ skb_queue_purge(&session->ctrl_transmit); skb_queue_purge(&session->intr_transmit); + if (session->hidp_sock) + session->hidp_sock->sk->sk_shutdown = SHUTDOWN_MASK; + /* Kill session thread */ atomic_inc(&session->terminate); + hidp_schedule(session); break; case HIDP_CTRL_HARD_RESET: @@ -743,7 +747,7 @@ hid->claimed |= HID_CLAIMED_INPUT; } -int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock) +int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock, struct socket *hidp_sock) { struct hidp_session *session, *s; int err; @@ -809,6 +813,7 @@ session->ctrl_sock = ctrl_sock; session->intr_sock = intr_sock; + session->hidp_sock = hidp_sock; session->state = BT_CONNECTED; init_timer(&session->timer); @@ -952,6 +957,24 @@ return err; } +void hidp_remove_hidp_sock_ref(struct socket *hidp_sock) +{ + struct list_head *p; + + down_read(&hidp_session_sem); + + list_for_each(p, &hidp_session_list) { + struct hidp_session *session; + + session = list_entry(p, struct hidp_session, list); + + if (session->hidp_sock == hidp_sock) + session->hidp_sock = NULL; + } + + up_read(&hidp_session_sem); +} + static int __init hidp_init(void) { l2cap_load(); diff -Naur linux-2.6.24.4/net/bluetooth/hidp.orig/hidp.h linux-2.6.24.4/net/bluetooth/hidp/hidp.h --- linux-2.6.24.4/net/bluetooth/hidp.orig/hidp.h 2008-03-24 19:49:18.000000000 +0100 +++ linux-2.6.24.4/net/bluetooth/hidp/hidp.h 2008-04-01 11:14:33.000000000 +0200 @@ -117,10 +117,11 @@ struct hidp_conninfo __user *ci; }; -int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock); +int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock, struct socket *hidp_sock); int hidp_del_connection(struct hidp_conndel_req *req); int hidp_get_connlist(struct hidp_connlist_req *req); int hidp_get_conninfo(struct hidp_conninfo *ci); +void hidp_remove_hidp_sock_ref(struct socket *hidp_sock); /* HIDP session defines */ struct hidp_session { @@ -128,6 +129,7 @@ struct socket *ctrl_sock; struct socket *intr_sock; + struct socket *hidp_sock; bdaddr_t bdaddr; diff -Naur linux-2.6.24.4/net/bluetooth/hidp.orig/sock.c linux-2.6.24.4/net/bluetooth/hidp/sock.c --- linux-2.6.24.4/net/bluetooth/hidp.orig/sock.c 2008-03-24 19:49:18.000000000 +0100 +++ linux-2.6.24.4/net/bluetooth/hidp/sock.c 2008-04-01 11:15:33.000000000 +0200 @@ -56,6 +56,8 @@ sock_orphan(sk); sock_put(sk); + hidp_remove_hidp_sock_ref(sock); + return 0; } @@ -96,7 +98,7 @@ return -EBADFD; } - err = hidp_add_connection(&ca, csock, isock); + err = hidp_add_connection(&ca, csock, isock, sock); if (!err) { if (copy_to_user(argp, &ca, sizeof(ca))) err = -EFAULT; @@ -229,7 +231,7 @@ .getname = sock_no_getname, .sendmsg = sock_no_sendmsg, .recvmsg = sock_no_recvmsg, - .poll = sock_no_poll, + .poll = bt_sock_poll, .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = sock_no_setsockopt,