diff options
Diffstat (limited to 'net/bluetooth/sco.c')
-rw-r--r-- | net/bluetooth/sco.c | 32 |
1 files changed, 15 insertions, 17 deletions
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 57f250c20e39..79d87d8d4f51 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -259,10 +259,9 @@ drop: | |||
259 | /* -------- Socket interface ---------- */ | 259 | /* -------- Socket interface ---------- */ |
260 | static struct sock *__sco_get_sock_listen_by_addr(bdaddr_t *ba) | 260 | static struct sock *__sco_get_sock_listen_by_addr(bdaddr_t *ba) |
261 | { | 261 | { |
262 | struct hlist_node *node; | ||
263 | struct sock *sk; | 262 | struct sock *sk; |
264 | 263 | ||
265 | sk_for_each(sk, node, &sco_sk_list.head) { | 264 | sk_for_each(sk, &sco_sk_list.head) { |
266 | if (sk->sk_state != BT_LISTEN) | 265 | if (sk->sk_state != BT_LISTEN) |
267 | continue; | 266 | continue; |
268 | 267 | ||
@@ -279,11 +278,10 @@ static struct sock *__sco_get_sock_listen_by_addr(bdaddr_t *ba) | |||
279 | static struct sock *sco_get_sock_listen(bdaddr_t *src) | 278 | static struct sock *sco_get_sock_listen(bdaddr_t *src) |
280 | { | 279 | { |
281 | struct sock *sk = NULL, *sk1 = NULL; | 280 | struct sock *sk = NULL, *sk1 = NULL; |
282 | struct hlist_node *node; | ||
283 | 281 | ||
284 | read_lock(&sco_sk_list.lock); | 282 | read_lock(&sco_sk_list.lock); |
285 | 283 | ||
286 | sk_for_each(sk, node, &sco_sk_list.head) { | 284 | sk_for_each(sk, &sco_sk_list.head) { |
287 | if (sk->sk_state != BT_LISTEN) | 285 | if (sk->sk_state != BT_LISTEN) |
288 | continue; | 286 | continue; |
289 | 287 | ||
@@ -298,7 +296,7 @@ static struct sock *sco_get_sock_listen(bdaddr_t *src) | |||
298 | 296 | ||
299 | read_unlock(&sco_sk_list.lock); | 297 | read_unlock(&sco_sk_list.lock); |
300 | 298 | ||
301 | return node ? sk : sk1; | 299 | return sk ? sk : sk1; |
302 | } | 300 | } |
303 | 301 | ||
304 | static void sco_sock_destruct(struct sock *sk) | 302 | static void sco_sock_destruct(struct sock *sk) |
@@ -900,8 +898,6 @@ static void sco_conn_ready(struct sco_conn *conn) | |||
900 | 898 | ||
901 | BT_DBG("conn %p", conn); | 899 | BT_DBG("conn %p", conn); |
902 | 900 | ||
903 | sco_conn_lock(conn); | ||
904 | |||
905 | if (sk) { | 901 | if (sk) { |
906 | sco_sock_clear_timer(sk); | 902 | sco_sock_clear_timer(sk); |
907 | bh_lock_sock(sk); | 903 | bh_lock_sock(sk); |
@@ -909,9 +905,13 @@ static void sco_conn_ready(struct sco_conn *conn) | |||
909 | sk->sk_state_change(sk); | 905 | sk->sk_state_change(sk); |
910 | bh_unlock_sock(sk); | 906 | bh_unlock_sock(sk); |
911 | } else { | 907 | } else { |
908 | sco_conn_lock(conn); | ||
909 | |||
912 | parent = sco_get_sock_listen(conn->src); | 910 | parent = sco_get_sock_listen(conn->src); |
913 | if (!parent) | 911 | if (!parent) { |
914 | goto done; | 912 | sco_conn_unlock(conn); |
913 | return; | ||
914 | } | ||
915 | 915 | ||
916 | bh_lock_sock(parent); | 916 | bh_lock_sock(parent); |
917 | 917 | ||
@@ -919,7 +919,8 @@ static void sco_conn_ready(struct sco_conn *conn) | |||
919 | BTPROTO_SCO, GFP_ATOMIC); | 919 | BTPROTO_SCO, GFP_ATOMIC); |
920 | if (!sk) { | 920 | if (!sk) { |
921 | bh_unlock_sock(parent); | 921 | bh_unlock_sock(parent); |
922 | goto done; | 922 | sco_conn_unlock(conn); |
923 | return; | ||
923 | } | 924 | } |
924 | 925 | ||
925 | sco_sock_init(sk, parent); | 926 | sco_sock_init(sk, parent); |
@@ -939,24 +940,22 @@ static void sco_conn_ready(struct sco_conn *conn) | |||
939 | parent->sk_data_ready(parent, 1); | 940 | parent->sk_data_ready(parent, 1); |
940 | 941 | ||
941 | bh_unlock_sock(parent); | 942 | bh_unlock_sock(parent); |
942 | } | ||
943 | 943 | ||
944 | done: | 944 | sco_conn_unlock(conn); |
945 | sco_conn_unlock(conn); | 945 | } |
946 | } | 946 | } |
947 | 947 | ||
948 | /* ----- SCO interface with lower layer (HCI) ----- */ | 948 | /* ----- SCO interface with lower layer (HCI) ----- */ |
949 | int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) | 949 | int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) |
950 | { | 950 | { |
951 | struct sock *sk; | 951 | struct sock *sk; |
952 | struct hlist_node *node; | ||
953 | int lm = 0; | 952 | int lm = 0; |
954 | 953 | ||
955 | BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr); | 954 | BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr); |
956 | 955 | ||
957 | /* Find listening sockets */ | 956 | /* Find listening sockets */ |
958 | read_lock(&sco_sk_list.lock); | 957 | read_lock(&sco_sk_list.lock); |
959 | sk_for_each(sk, node, &sco_sk_list.head) { | 958 | sk_for_each(sk, &sco_sk_list.head) { |
960 | if (sk->sk_state != BT_LISTEN) | 959 | if (sk->sk_state != BT_LISTEN) |
961 | continue; | 960 | continue; |
962 | 961 | ||
@@ -1016,11 +1015,10 @@ drop: | |||
1016 | static int sco_debugfs_show(struct seq_file *f, void *p) | 1015 | static int sco_debugfs_show(struct seq_file *f, void *p) |
1017 | { | 1016 | { |
1018 | struct sock *sk; | 1017 | struct sock *sk; |
1019 | struct hlist_node *node; | ||
1020 | 1018 | ||
1021 | read_lock(&sco_sk_list.lock); | 1019 | read_lock(&sco_sk_list.lock); |
1022 | 1020 | ||
1023 | sk_for_each(sk, node, &sco_sk_list.head) { | 1021 | sk_for_each(sk, &sco_sk_list.head) { |
1024 | seq_printf(f, "%pMR %pMR %d\n", &bt_sk(sk)->src, | 1022 | seq_printf(f, "%pMR %pMR %d\n", &bt_sk(sk)->src, |
1025 | &bt_sk(sk)->dst, sk->sk_state); | 1023 | &bt_sk(sk)->dst, sk->sk_state); |
1026 | } | 1024 | } |