aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>2012-02-21 05:54:57 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2012-02-23 06:06:58 -0500
commit0e587be728a522fd8e522ad905b02f2892b61712 (patch)
treed0104f63cf6a80045b94e7cd04f8da7dddacf34e
parentc03b355ea2938495bbdf25a4645be545be8890f4 (diff)
Bluetooth: Add locked and unlocked state_change
Split to locked and unlocked versions of l2cap_state_change helping to remove socket locks from l2cap code. Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Reviewed-by: Ulisses Furquim <ulisses@profusion.mobi> Acked-by: Gustavo F. Padovan <padovan@profusion.mobi> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
-rw-r--r--net/bluetooth/l2cap_core.c41
1 files changed, 25 insertions, 16 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index e39eba1ac4da..4638dbbaa4b2 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -199,7 +199,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
199 return 0; 199 return 0;
200} 200}
201 201
202static void l2cap_state_change(struct l2cap_chan *chan, int state) 202static void __l2cap_state_change(struct l2cap_chan *chan, int state)
203{ 203{
204 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state), 204 BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
205 state_to_string(state)); 205 state_to_string(state));
@@ -208,6 +208,15 @@ static void l2cap_state_change(struct l2cap_chan *chan, int state)
208 chan->ops->state_change(chan->data, state); 208 chan->ops->state_change(chan->data, state);
209} 209}
210 210
211static void l2cap_state_change(struct l2cap_chan *chan, int state)
212{
213 struct sock *sk = chan->sk;
214
215 lock_sock(sk);
216 __l2cap_state_change(chan, state);
217 release_sock(sk);
218}
219
211static void l2cap_chan_timeout(struct work_struct *work) 220static void l2cap_chan_timeout(struct work_struct *work)
212{ 221{
213 struct l2cap_chan *chan = container_of(work, struct l2cap_chan, 222 struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
@@ -348,7 +357,7 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err)
348 hci_conn_put(conn->hcon); 357 hci_conn_put(conn->hcon);
349 } 358 }
350 359
351 l2cap_state_change(chan, BT_CLOSED); 360 __l2cap_state_change(chan, BT_CLOSED);
352 sock_set_flag(sk, SOCK_ZAPPED); 361 sock_set_flag(sk, SOCK_ZAPPED);
353 362
354 if (err) 363 if (err)
@@ -413,7 +422,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
413 case BT_LISTEN: 422 case BT_LISTEN:
414 l2cap_chan_cleanup_listen(sk); 423 l2cap_chan_cleanup_listen(sk);
415 424
416 l2cap_state_change(chan, BT_CLOSED); 425 __l2cap_state_change(chan, BT_CLOSED);
417 sock_set_flag(sk, SOCK_ZAPPED); 426 sock_set_flag(sk, SOCK_ZAPPED);
418 break; 427 break;
419 428
@@ -704,7 +713,7 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *c
704 l2cap_send_cmd(conn, l2cap_get_ident(conn), 713 l2cap_send_cmd(conn, l2cap_get_ident(conn),
705 L2CAP_DISCONN_REQ, sizeof(req), &req); 714 L2CAP_DISCONN_REQ, sizeof(req), &req);
706 715
707 l2cap_state_change(chan, BT_DISCONN); 716 __l2cap_state_change(chan, BT_DISCONN);
708 sk->sk_err = err; 717 sk->sk_err = err;
709} 718}
710 719
@@ -770,7 +779,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
770 parent->sk_data_ready(parent, 0); 779 parent->sk_data_ready(parent, 0);
771 780
772 } else { 781 } else {
773 l2cap_state_change(chan, BT_CONFIG); 782 __l2cap_state_change(chan, BT_CONFIG);
774 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); 783 rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
775 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); 784 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
776 } 785 }
@@ -873,7 +882,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
873 882
874 __set_chan_timer(chan, sk->sk_sndtimeo); 883 __set_chan_timer(chan, sk->sk_sndtimeo);
875 884
876 l2cap_state_change(chan, BT_CONNECTED); 885 __l2cap_state_change(chan, BT_CONNECTED);
877 parent->sk_data_ready(parent, 0); 886 parent->sk_data_ready(parent, 0);
878 887
879clean: 888clean:
@@ -890,7 +899,7 @@ static void l2cap_chan_ready(struct l2cap_chan *chan)
890 chan->conf_state = 0; 899 chan->conf_state = 0;
891 __clear_chan_timer(chan); 900 __clear_chan_timer(chan);
892 901
893 l2cap_state_change(chan, BT_CONNECTED); 902 __l2cap_state_change(chan, BT_CONNECTED);
894 sk->sk_state_change(sk); 903 sk->sk_state_change(sk);
895 904
896 if (parent) 905 if (parent)
@@ -922,7 +931,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
922 931
923 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { 932 } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
924 __clear_chan_timer(chan); 933 __clear_chan_timer(chan);
925 l2cap_state_change(chan, BT_CONNECTED); 934 __l2cap_state_change(chan, BT_CONNECTED);
926 sk->sk_state_change(sk); 935 sk->sk_state_change(sk);
927 936
928 } else if (chan->state == BT_CONNECT) 937 } else if (chan->state == BT_CONNECT)
@@ -1196,14 +1205,14 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *d
1196 1205
1197 l2cap_chan_add(conn, chan); 1206 l2cap_chan_add(conn, chan);
1198 1207
1199 l2cap_state_change(chan, BT_CONNECT); 1208 __l2cap_state_change(chan, BT_CONNECT);
1200 __set_chan_timer(chan, sk->sk_sndtimeo); 1209 __set_chan_timer(chan, sk->sk_sndtimeo);
1201 1210
1202 if (hcon->state == BT_CONNECTED) { 1211 if (hcon->state == BT_CONNECTED) {
1203 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { 1212 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
1204 __clear_chan_timer(chan); 1213 __clear_chan_timer(chan);
1205 if (l2cap_chan_check_security(chan)) 1214 if (l2cap_chan_check_security(chan))
1206 l2cap_state_change(chan, BT_CONNECTED); 1215 __l2cap_state_change(chan, BT_CONNECTED);
1207 } else 1216 } else
1208 l2cap_do_start(chan); 1217 l2cap_do_start(chan);
1209 } 1218 }
@@ -2650,22 +2659,22 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
2650 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) { 2659 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
2651 if (l2cap_chan_check_security(chan)) { 2660 if (l2cap_chan_check_security(chan)) {
2652 if (bt_sk(sk)->defer_setup) { 2661 if (bt_sk(sk)->defer_setup) {
2653 l2cap_state_change(chan, BT_CONNECT2); 2662 __l2cap_state_change(chan, BT_CONNECT2);
2654 result = L2CAP_CR_PEND; 2663 result = L2CAP_CR_PEND;
2655 status = L2CAP_CS_AUTHOR_PEND; 2664 status = L2CAP_CS_AUTHOR_PEND;
2656 parent->sk_data_ready(parent, 0); 2665 parent->sk_data_ready(parent, 0);
2657 } else { 2666 } else {
2658 l2cap_state_change(chan, BT_CONFIG); 2667 __l2cap_state_change(chan, BT_CONFIG);
2659 result = L2CAP_CR_SUCCESS; 2668 result = L2CAP_CR_SUCCESS;
2660 status = L2CAP_CS_NO_INFO; 2669 status = L2CAP_CS_NO_INFO;
2661 } 2670 }
2662 } else { 2671 } else {
2663 l2cap_state_change(chan, BT_CONNECT2); 2672 __l2cap_state_change(chan, BT_CONNECT2);
2664 result = L2CAP_CR_PEND; 2673 result = L2CAP_CR_PEND;
2665 status = L2CAP_CS_AUTHEN_PEND; 2674 status = L2CAP_CS_AUTHEN_PEND;
2666 } 2675 }
2667 } else { 2676 } else {
2668 l2cap_state_change(chan, BT_CONNECT2); 2677 __l2cap_state_change(chan, BT_CONNECT2);
2669 result = L2CAP_CR_PEND; 2678 result = L2CAP_CR_PEND;
2670 status = L2CAP_CS_NO_INFO; 2679 status = L2CAP_CS_NO_INFO;
2671 } 2680 }
@@ -4584,12 +4593,12 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
4584 if (parent) 4593 if (parent)
4585 parent->sk_data_ready(parent, 0); 4594 parent->sk_data_ready(parent, 0);
4586 } else { 4595 } else {
4587 l2cap_state_change(chan, BT_CONFIG); 4596 __l2cap_state_change(chan, BT_CONFIG);
4588 res = L2CAP_CR_SUCCESS; 4597 res = L2CAP_CR_SUCCESS;
4589 stat = L2CAP_CS_NO_INFO; 4598 stat = L2CAP_CS_NO_INFO;
4590 } 4599 }
4591 } else { 4600 } else {
4592 l2cap_state_change(chan, BT_DISCONN); 4601 __l2cap_state_change(chan, BT_DISCONN);
4593 __set_chan_timer(chan, 4602 __set_chan_timer(chan,
4594 msecs_to_jiffies(L2CAP_DISC_TIMEOUT)); 4603 msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
4595 res = L2CAP_CR_SEC_BLOCK; 4604 res = L2CAP_CR_SEC_BLOCK;