Commit f2529c2c authored by John W. Linville's avatar John W. Linville

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/padovan/bluetooth-2.6

parents a0b8de35 163f4dab
...@@ -393,6 +393,9 @@ int hci_conn_del(struct hci_conn *conn) ...@@ -393,6 +393,9 @@ int hci_conn_del(struct hci_conn *conn)
hci_dev_put(hdev); hci_dev_put(hdev);
if (conn->handle == 0)
kfree(conn);
return 0; return 0;
} }
......
...@@ -464,7 +464,8 @@ static void hidp_idle_timeout(unsigned long arg) ...@@ -464,7 +464,8 @@ static void hidp_idle_timeout(unsigned long arg)
{ {
struct hidp_session *session = (struct hidp_session *) arg; struct hidp_session *session = (struct hidp_session *) arg;
kthread_stop(session->task); atomic_inc(&session->terminate);
wake_up_process(session->task);
} }
static void hidp_set_timer(struct hidp_session *session) static void hidp_set_timer(struct hidp_session *session)
...@@ -535,7 +536,8 @@ static void hidp_process_hid_control(struct hidp_session *session, ...@@ -535,7 +536,8 @@ static void hidp_process_hid_control(struct hidp_session *session,
skb_queue_purge(&session->ctrl_transmit); skb_queue_purge(&session->ctrl_transmit);
skb_queue_purge(&session->intr_transmit); skb_queue_purge(&session->intr_transmit);
kthread_stop(session->task); atomic_inc(&session->terminate);
wake_up_process(current);
} }
} }
...@@ -706,9 +708,8 @@ static int hidp_session(void *arg) ...@@ -706,9 +708,8 @@ static int hidp_session(void *arg)
add_wait_queue(sk_sleep(intr_sk), &intr_wait); add_wait_queue(sk_sleep(intr_sk), &intr_wait);
session->waiting_for_startup = 0; session->waiting_for_startup = 0;
wake_up_interruptible(&session->startup_queue); wake_up_interruptible(&session->startup_queue);
while (!kthread_should_stop()) { set_current_state(TASK_INTERRUPTIBLE);
set_current_state(TASK_INTERRUPTIBLE); while (!atomic_read(&session->terminate)) {
if (ctrl_sk->sk_state != BT_CONNECTED || if (ctrl_sk->sk_state != BT_CONNECTED ||
intr_sk->sk_state != BT_CONNECTED) intr_sk->sk_state != BT_CONNECTED)
break; break;
...@@ -726,6 +727,7 @@ static int hidp_session(void *arg) ...@@ -726,6 +727,7 @@ static int hidp_session(void *arg)
hidp_process_transmit(session); hidp_process_transmit(session);
schedule(); schedule();
set_current_state(TASK_INTERRUPTIBLE);
} }
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(intr_sk), &intr_wait); remove_wait_queue(sk_sleep(intr_sk), &intr_wait);
...@@ -1060,7 +1062,8 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, ...@@ -1060,7 +1062,8 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
err_add_device: err_add_device:
hid_destroy_device(session->hid); hid_destroy_device(session->hid);
session->hid = NULL; session->hid = NULL;
kthread_stop(session->task); atomic_inc(&session->terminate);
wake_up_process(session->task);
unlink: unlink:
hidp_del_timer(session); hidp_del_timer(session);
...@@ -1111,7 +1114,8 @@ int hidp_del_connection(struct hidp_conndel_req *req) ...@@ -1111,7 +1114,8 @@ int hidp_del_connection(struct hidp_conndel_req *req)
skb_queue_purge(&session->ctrl_transmit); skb_queue_purge(&session->ctrl_transmit);
skb_queue_purge(&session->intr_transmit); skb_queue_purge(&session->intr_transmit);
kthread_stop(session->task); atomic_inc(&session->terminate);
wake_up_process(session->task);
} }
} else } else
err = -ENOENT; err = -ENOENT;
......
...@@ -142,6 +142,7 @@ struct hidp_session { ...@@ -142,6 +142,7 @@ struct hidp_session {
uint ctrl_mtu; uint ctrl_mtu;
uint intr_mtu; uint intr_mtu;
atomic_t terminate;
struct task_struct *task; struct task_struct *task;
unsigned char keys[8]; unsigned char keys[8];
......
...@@ -2323,7 +2323,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr ...@@ -2323,7 +2323,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
sk = chan->sk; sk = chan->sk;
if (sk->sk_state != BT_CONFIG) { if ((bt_sk(sk)->defer_setup && sk->sk_state != BT_CONNECT2) ||
(!bt_sk(sk)->defer_setup && sk->sk_state != BT_CONFIG)) {
struct l2cap_cmd_rej rej; struct l2cap_cmd_rej rej;
rej.reason = cpu_to_le16(0x0002); rej.reason = cpu_to_le16(0x0002);
...@@ -2334,7 +2335,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr ...@@ -2334,7 +2335,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
/* Reject if config buffer is too small. */ /* Reject if config buffer is too small. */
len = cmd_len - sizeof(*req); len = cmd_len - sizeof(*req);
if (chan->conf_len + len > sizeof(chan->conf_req)) { if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
l2cap_build_conf_rsp(chan, rsp, l2cap_build_conf_rsp(chan, rsp,
L2CAP_CONF_REJECT, flags), rsp); L2CAP_CONF_REJECT, flags), rsp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment