diff options
author | Andrei Emeltchenko <andrei.emeltchenko@intel.com> | 2012-02-21 05:54:58 -0500 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-02-23 06:06:58 -0500 |
commit | 2e0052e4cf78e3e205e92d82ee572ed726e315d6 (patch) | |
tree | 1a63bbf0106c85bc5958c72e1560634e135f14c1 /net | |
parent | 0e587be728a522fd8e522ad905b02f2892b61712 (diff) |
Bluetooth: Add socket error function
Use locked and unlocked versions to help removing socket
locks from l2cap core functions.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Reviewed-by: Ulisses Furquim <ulisses@profusion.mobi>
Acked-by: Gustavo F. Padovan <padovan@profusion.mobi>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/l2cap_core.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 4638dbbaa4b..c0640b73c62 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -217,6 +217,22 @@ static void l2cap_state_change(struct l2cap_chan *chan, int state) | |||
217 | release_sock(sk); | 217 | release_sock(sk); |
218 | } | 218 | } |
219 | 219 | ||
220 | static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err) | ||
221 | { | ||
222 | struct sock *sk = chan->sk; | ||
223 | |||
224 | sk->sk_err = err; | ||
225 | } | ||
226 | |||
227 | static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err) | ||
228 | { | ||
229 | struct sock *sk = chan->sk; | ||
230 | |||
231 | lock_sock(sk); | ||
232 | __l2cap_chan_set_err(chan, err); | ||
233 | release_sock(sk); | ||
234 | } | ||
235 | |||
220 | static void l2cap_chan_timeout(struct work_struct *work) | 236 | static void l2cap_chan_timeout(struct work_struct *work) |
221 | { | 237 | { |
222 | struct l2cap_chan *chan = container_of(work, struct l2cap_chan, | 238 | struct l2cap_chan *chan = container_of(work, struct l2cap_chan, |
@@ -361,7 +377,7 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
361 | sock_set_flag(sk, SOCK_ZAPPED); | 377 | sock_set_flag(sk, SOCK_ZAPPED); |
362 | 378 | ||
363 | if (err) | 379 | if (err) |
364 | sk->sk_err = err; | 380 | __l2cap_chan_set_err(chan, err); |
365 | 381 | ||
366 | if (parent) { | 382 | if (parent) { |
367 | bt_accept_unlink(sk); | 383 | bt_accept_unlink(sk); |
@@ -694,14 +710,11 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) | |||
694 | 710 | ||
695 | static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err) | 711 | static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err) |
696 | { | 712 | { |
697 | struct sock *sk; | ||
698 | struct l2cap_disconn_req req; | 713 | struct l2cap_disconn_req req; |
699 | 714 | ||
700 | if (!conn) | 715 | if (!conn) |
701 | return; | 716 | return; |
702 | 717 | ||
703 | sk = chan->sk; | ||
704 | |||
705 | if (chan->mode == L2CAP_MODE_ERTM) { | 718 | if (chan->mode == L2CAP_MODE_ERTM) { |
706 | __clear_retrans_timer(chan); | 719 | __clear_retrans_timer(chan); |
707 | __clear_monitor_timer(chan); | 720 | __clear_monitor_timer(chan); |
@@ -714,7 +727,7 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *c | |||
714 | L2CAP_DISCONN_REQ, sizeof(req), &req); | 727 | L2CAP_DISCONN_REQ, sizeof(req), &req); |
715 | 728 | ||
716 | __l2cap_state_change(chan, BT_DISCONN); | 729 | __l2cap_state_change(chan, BT_DISCONN); |
717 | sk->sk_err = err; | 730 | __l2cap_chan_set_err(chan, err); |
718 | } | 731 | } |
719 | 732 | ||
720 | /* ---- L2CAP connections ---- */ | 733 | /* ---- L2CAP connections ---- */ |
@@ -953,10 +966,8 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) | |||
953 | mutex_lock(&conn->chan_lock); | 966 | mutex_lock(&conn->chan_lock); |
954 | 967 | ||
955 | list_for_each_entry(chan, &conn->chan_l, list) { | 968 | list_for_each_entry(chan, &conn->chan_l, list) { |
956 | struct sock *sk = chan->sk; | ||
957 | |||
958 | if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags)) | 969 | if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags)) |
959 | sk->sk_err = err; | 970 | __l2cap_chan_set_err(chan, err); |
960 | } | 971 | } |
961 | 972 | ||
962 | mutex_unlock(&conn->chan_lock); | 973 | mutex_unlock(&conn->chan_lock); |
@@ -2988,7 +2999,8 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2988 | } | 2999 | } |
2989 | 3000 | ||
2990 | default: | 3001 | default: |
2991 | sk->sk_err = ECONNRESET; | 3002 | __l2cap_chan_set_err(chan, ECONNRESET); |
3003 | |||
2992 | __set_chan_timer(chan, | 3004 | __set_chan_timer(chan, |
2993 | msecs_to_jiffies(L2CAP_DISC_REJ_TIMEOUT)); | 3005 | msecs_to_jiffies(L2CAP_DISC_REJ_TIMEOUT)); |
2994 | l2cap_send_disconn_req(conn, chan, ECONNRESET); | 3006 | l2cap_send_disconn_req(conn, chan, ECONNRESET); |