summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/bluetooth.h3
-rw-r--r--net/bluetooth/af_bluetooth.c8
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 @@
#define SOL_SCO 17
#define SOL_RFCOMM 18
+#define BT_DEFER_SETUP 7
+
#define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
#define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg)
@@ -108,6 +110,7 @@ struct bt_sock {
bdaddr_t dst;
struct list_head accept_q;
struct sock *parent;
+ u32 defer_setup;
};
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)
continue;
}
- if (sk->sk_state == BT_CONNECTED || !newsock) {
+ if (sk->sk_state == BT_CONNECTED || !newsock ||
+ bt_sk(parent)->defer_setup) {
bt_accept_unlink(sk);
if (newsock)
sock_graft(sk, newsock);
@@ -232,7 +233,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
EXPORT_SYMBOL(bt_accept_dequeue);
int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
- struct msghdr *msg, size_t len, int flags)
+ struct msghdr *msg, size_t len, int flags)
{
int noblock = flags & MSG_DONTWAIT;
struct sock *sk = sock->sk;
@@ -275,6 +276,9 @@ static inline unsigned int bt_accept_poll(struct sock *parent)
struct list_head *p, *n;
struct sock *sk;
+ if (bt_sk(parent)->defer_setup)
+ return POLLIN | POLLRDNORM;
+
list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
if (sk->sk_state == BT_CONNECTED)