diff options
author | Andrei Emeltchenko <andrei.emeltchenko@intel.com> | 2012-02-21 05:54:57 -0500 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-02-23 06:06:58 -0500 |
commit | 0e587be728a522fd8e522ad905b02f2892b61712 (patch) | |
tree | d0104f63cf6a80045b94e7cd04f8da7dddacf34e | |
parent | c03b355ea2938495bbdf25a4645be545be8890f4 (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.c | 41 |
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 | ||
202 | static void l2cap_state_change(struct l2cap_chan *chan, int state) | 202 | static 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 | ||
211 | static 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 | |||
211 | static void l2cap_chan_timeout(struct work_struct *work) | 220 | static 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 | ||
879 | clean: | 888 | clean: |
@@ -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; |