diff options
-rw-r--r-- | include/net/bluetooth/l2cap.h | 5 | ||||
-rw-r--r-- | net/bluetooth/a2mp.c | 1 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 10 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 10 |
4 files changed, 19 insertions, 7 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index caab98c4512..6e23afdf65c 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -541,6 +541,7 @@ struct l2cap_ops { | |||
541 | void (*state_change) (struct l2cap_chan *chan, | 541 | void (*state_change) (struct l2cap_chan *chan, |
542 | int state); | 542 | int state); |
543 | void (*ready) (struct l2cap_chan *chan); | 543 | void (*ready) (struct l2cap_chan *chan); |
544 | void (*defer) (struct l2cap_chan *chan); | ||
544 | struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, | 545 | struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, |
545 | unsigned long len, int nb); | 546 | unsigned long len, int nb); |
546 | }; | 547 | }; |
@@ -748,6 +749,10 @@ static inline void l2cap_chan_no_ready(struct l2cap_chan *chan) | |||
748 | { | 749 | { |
749 | } | 750 | } |
750 | 751 | ||
752 | static inline void l2cap_chan_no_defer(struct l2cap_chan *chan) | ||
753 | { | ||
754 | } | ||
755 | |||
751 | extern bool disable_ertm; | 756 | extern bool disable_ertm; |
752 | 757 | ||
753 | int l2cap_init_sockets(void); | 758 | int l2cap_init_sockets(void); |
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 3ff4dc928bf..7bf9a10d8e4 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c | |||
@@ -699,6 +699,7 @@ static struct l2cap_ops a2mp_chan_ops = { | |||
699 | .new_connection = l2cap_chan_no_new_connection, | 699 | .new_connection = l2cap_chan_no_new_connection, |
700 | .teardown = l2cap_chan_no_teardown, | 700 | .teardown = l2cap_chan_no_teardown, |
701 | .ready = l2cap_chan_no_ready, | 701 | .ready = l2cap_chan_no_ready, |
702 | .defer = l2cap_chan_no_defer, | ||
702 | }; | 703 | }; |
703 | 704 | ||
704 | static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked) | 705 | static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked) |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 9d84050bed2..314d95580d7 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -1120,11 +1120,9 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
1120 | lock_sock(sk); | 1120 | lock_sock(sk); |
1121 | if (test_bit(BT_SK_DEFER_SETUP, | 1121 | if (test_bit(BT_SK_DEFER_SETUP, |
1122 | &bt_sk(sk)->flags)) { | 1122 | &bt_sk(sk)->flags)) { |
1123 | struct sock *parent = bt_sk(sk)->parent; | ||
1124 | rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); | 1123 | rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); |
1125 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND); | 1124 | rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND); |
1126 | if (parent) | 1125 | chan->ops->defer(chan); |
1127 | parent->sk_data_ready(parent, 0); | ||
1128 | 1126 | ||
1129 | } else { | 1127 | } else { |
1130 | __l2cap_state_change(chan, BT_CONFIG); | 1128 | __l2cap_state_change(chan, BT_CONFIG); |
@@ -3460,7 +3458,7 @@ static void __l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, | |||
3460 | __l2cap_state_change(chan, BT_CONNECT2); | 3458 | __l2cap_state_change(chan, BT_CONNECT2); |
3461 | result = L2CAP_CR_PEND; | 3459 | result = L2CAP_CR_PEND; |
3462 | status = L2CAP_CS_AUTHOR_PEND; | 3460 | status = L2CAP_CS_AUTHOR_PEND; |
3463 | parent->sk_data_ready(parent, 0); | 3461 | chan->ops->defer(chan); |
3464 | } else { | 3462 | } else { |
3465 | __l2cap_state_change(chan, BT_CONFIG); | 3463 | __l2cap_state_change(chan, BT_CONFIG); |
3466 | result = L2CAP_CR_SUCCESS; | 3464 | result = L2CAP_CR_SUCCESS; |
@@ -5523,11 +5521,9 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
5523 | if (!status) { | 5521 | if (!status) { |
5524 | if (test_bit(BT_SK_DEFER_SETUP, | 5522 | if (test_bit(BT_SK_DEFER_SETUP, |
5525 | &bt_sk(sk)->flags)) { | 5523 | &bt_sk(sk)->flags)) { |
5526 | struct sock *parent = bt_sk(sk)->parent; | ||
5527 | res = L2CAP_CR_PEND; | 5524 | res = L2CAP_CR_PEND; |
5528 | stat = L2CAP_CS_AUTHOR_PEND; | 5525 | stat = L2CAP_CS_AUTHOR_PEND; |
5529 | if (parent) | 5526 | chan->ops->defer(chan); |
5530 | parent->sk_data_ready(parent, 0); | ||
5531 | } else { | 5527 | } else { |
5532 | __l2cap_state_change(chan, BT_CONFIG); | 5528 | __l2cap_state_change(chan, BT_CONFIG); |
5533 | res = L2CAP_CR_SUCCESS; | 5529 | res = L2CAP_CR_SUCCESS; |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index d5093b853b0..5fae2bd879a 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -1081,6 +1081,15 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan) | |||
1081 | release_sock(sk); | 1081 | release_sock(sk); |
1082 | } | 1082 | } |
1083 | 1083 | ||
1084 | static void l2cap_sock_defer_cb(struct l2cap_chan *chan) | ||
1085 | { | ||
1086 | struct sock *sk = chan->data; | ||
1087 | struct sock *parent = bt_sk(sk)->parent; | ||
1088 | |||
1089 | if (parent) | ||
1090 | parent->sk_data_ready(parent, 0); | ||
1091 | } | ||
1092 | |||
1084 | static struct l2cap_ops l2cap_chan_ops = { | 1093 | static struct l2cap_ops l2cap_chan_ops = { |
1085 | .name = "L2CAP Socket Interface", | 1094 | .name = "L2CAP Socket Interface", |
1086 | .new_connection = l2cap_sock_new_connection_cb, | 1095 | .new_connection = l2cap_sock_new_connection_cb, |
@@ -1089,6 +1098,7 @@ static struct l2cap_ops l2cap_chan_ops = { | |||
1089 | .teardown = l2cap_sock_teardown_cb, | 1098 | .teardown = l2cap_sock_teardown_cb, |
1090 | .state_change = l2cap_sock_state_change_cb, | 1099 | .state_change = l2cap_sock_state_change_cb, |
1091 | .ready = l2cap_sock_ready_cb, | 1100 | .ready = l2cap_sock_ready_cb, |
1101 | .defer = l2cap_sock_defer_cb, | ||
1092 | .alloc_skb = l2cap_sock_alloc_skb_cb, | 1102 | .alloc_skb = l2cap_sock_alloc_skb_cb, |
1093 | }; | 1103 | }; |
1094 | 1104 | ||