diff options
-rw-r--r-- | include/net/bluetooth/bluetooth.h | 3 | ||||
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 8 |
2 files changed, 9 insertions, 2 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index a04f8463ac7e..847e9e6df08b 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -53,6 +53,8 @@ | |||
53 | #define SOL_SCO 17 | 53 | #define SOL_SCO 17 |
54 | #define SOL_RFCOMM 18 | 54 | #define SOL_RFCOMM 18 |
55 | 55 | ||
56 | #define BT_DEFER_SETUP 7 | ||
57 | |||
56 | #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) | 58 | #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) |
57 | #define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg) | 59 | #define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg) |
58 | #define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg) | 60 | #define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg) |
@@ -108,6 +110,7 @@ struct bt_sock { | |||
108 | bdaddr_t dst; | 110 | bdaddr_t dst; |
109 | struct list_head accept_q; | 111 | struct list_head accept_q; |
110 | struct sock *parent; | 112 | struct sock *parent; |
113 | u32 defer_setup; | ||
111 | }; | 114 | }; |
112 | 115 | ||
113 | struct bt_sock_list { | 116 | struct bt_sock_list { |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 744ed3f07ef3..7c0031ff8cfb 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -217,7 +217,8 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) | |||
217 | continue; | 217 | continue; |
218 | } | 218 | } |
219 | 219 | ||
220 | if (sk->sk_state == BT_CONNECTED || !newsock) { | 220 | if (sk->sk_state == BT_CONNECTED || !newsock || |
221 | bt_sk(parent)->defer_setup) { | ||
221 | bt_accept_unlink(sk); | 222 | bt_accept_unlink(sk); |
222 | if (newsock) | 223 | if (newsock) |
223 | sock_graft(sk, newsock); | 224 | sock_graft(sk, newsock); |
@@ -232,7 +233,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) | |||
232 | EXPORT_SYMBOL(bt_accept_dequeue); | 233 | EXPORT_SYMBOL(bt_accept_dequeue); |
233 | 234 | ||
234 | int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | 235 | int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, |
235 | struct msghdr *msg, size_t len, int flags) | 236 | struct msghdr *msg, size_t len, int flags) |
236 | { | 237 | { |
237 | int noblock = flags & MSG_DONTWAIT; | 238 | int noblock = flags & MSG_DONTWAIT; |
238 | struct sock *sk = sock->sk; | 239 | struct sock *sk = sock->sk; |
@@ -275,6 +276,9 @@ static inline unsigned int bt_accept_poll(struct sock *parent) | |||
275 | struct list_head *p, *n; | 276 | struct list_head *p, *n; |
276 | struct sock *sk; | 277 | struct sock *sk; |
277 | 278 | ||
279 | if (bt_sk(parent)->defer_setup) | ||
280 | return POLLIN | POLLRDNORM; | ||
281 | |||
278 | list_for_each_safe(p, n, &bt_sk(parent)->accept_q) { | 282 | list_for_each_safe(p, n, &bt_sk(parent)->accept_q) { |
279 | sk = (struct sock *) list_entry(p, struct bt_sock, accept_q); | 283 | sk = (struct sock *) list_entry(p, struct bt_sock, accept_q); |
280 | if (sk->sk_state == BT_CONNECTED) | 284 | if (sk->sk_state == BT_CONNECTED) |