aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/sco.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/sco.c')
-rw-r--r--net/bluetooth/sco.c125
1 files changed, 75 insertions, 50 deletions
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index c06dbd3938e8..7ee9e4ab00f8 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -40,13 +40,38 @@ static struct bt_sock_list sco_sk_list = {
40 .lock = __RW_LOCK_UNLOCKED(sco_sk_list.lock) 40 .lock = __RW_LOCK_UNLOCKED(sco_sk_list.lock)
41}; 41};
42 42
43static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent); 43/* ---- SCO connections ---- */
44static void sco_chan_del(struct sock *sk, int err); 44struct sco_conn {
45 struct hci_conn *hcon;
46
47 spinlock_t lock;
48 struct sock *sk;
49
50 unsigned int mtu;
51};
52
53#define sco_conn_lock(c) spin_lock(&c->lock);
54#define sco_conn_unlock(c) spin_unlock(&c->lock);
45 55
46static void sco_sock_close(struct sock *sk); 56static void sco_sock_close(struct sock *sk);
47static void sco_sock_kill(struct sock *sk); 57static void sco_sock_kill(struct sock *sk);
48 58
59/* ----- SCO socket info ----- */
60#define sco_pi(sk) ((struct sco_pinfo *) sk)
61
62struct sco_pinfo {
63 struct bt_sock bt;
64 bdaddr_t src;
65 bdaddr_t dst;
66 __u32 flags;
67 __u16 setting;
68 struct sco_conn *conn;
69};
70
49/* ---- SCO timers ---- */ 71/* ---- SCO timers ---- */
72#define SCO_CONN_TIMEOUT (HZ * 40)
73#define SCO_DISCONN_TIMEOUT (HZ * 2)
74
50static void sco_sock_timeout(unsigned long arg) 75static void sco_sock_timeout(unsigned long arg)
51{ 76{
52 struct sock *sk = (struct sock *) arg; 77 struct sock *sk = (struct sock *) arg;
@@ -102,13 +127,31 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon)
102 return conn; 127 return conn;
103} 128}
104 129
105static struct sock *sco_chan_get(struct sco_conn *conn) 130/* Delete channel.
131 * Must be called on the locked socket. */
132static void sco_chan_del(struct sock *sk, int err)
106{ 133{
107 struct sock *sk = NULL; 134 struct sco_conn *conn;
108 sco_conn_lock(conn); 135
109 sk = conn->sk; 136 conn = sco_pi(sk)->conn;
110 sco_conn_unlock(conn); 137
111 return sk; 138 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
139
140 if (conn) {
141 sco_conn_lock(conn);
142 conn->sk = NULL;
143 sco_pi(sk)->conn = NULL;
144 sco_conn_unlock(conn);
145
146 if (conn->hcon)
147 hci_conn_drop(conn->hcon);
148 }
149
150 sk->sk_state = BT_CLOSED;
151 sk->sk_err = err;
152 sk->sk_state_change(sk);
153
154 sock_set_flag(sk, SOCK_ZAPPED);
112} 155}
113 156
114static int sco_conn_del(struct hci_conn *hcon, int err) 157static int sco_conn_del(struct hci_conn *hcon, int err)
@@ -122,7 +165,10 @@ static int sco_conn_del(struct hci_conn *hcon, int err)
122 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); 165 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
123 166
124 /* Kill socket */ 167 /* Kill socket */
125 sk = sco_chan_get(conn); 168 sco_conn_lock(conn);
169 sk = conn->sk;
170 sco_conn_unlock(conn);
171
126 if (sk) { 172 if (sk) {
127 bh_lock_sock(sk); 173 bh_lock_sock(sk);
128 sco_sock_clear_timer(sk); 174 sco_sock_clear_timer(sk);
@@ -136,6 +182,17 @@ static int sco_conn_del(struct hci_conn *hcon, int err)
136 return 0; 182 return 0;
137} 183}
138 184
185static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
186{
187 BT_DBG("conn %p", conn);
188
189 sco_pi(sk)->conn = conn;
190 conn->sk = sk;
191
192 if (parent)
193 bt_accept_enqueue(parent, sk);
194}
195
139static int sco_chan_add(struct sco_conn *conn, struct sock *sk, 196static int sco_chan_add(struct sco_conn *conn, struct sock *sk,
140 struct sock *parent) 197 struct sock *parent)
141{ 198{
@@ -240,7 +297,11 @@ static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
240 297
241static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb) 298static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
242{ 299{
243 struct sock *sk = sco_chan_get(conn); 300 struct sock *sk;
301
302 sco_conn_lock(conn);
303 sk = conn->sk;
304 sco_conn_unlock(conn);
244 305
245 if (!sk) 306 if (!sk)
246 goto drop; 307 goto drop;
@@ -909,7 +970,8 @@ static int sco_sock_shutdown(struct socket *sock, int how)
909 sco_sock_clear_timer(sk); 970 sco_sock_clear_timer(sk);
910 __sco_sock_close(sk); 971 __sco_sock_close(sk);
911 972
912 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) 973 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
974 !(current->flags & PF_EXITING))
913 err = bt_sock_wait_state(sk, BT_CLOSED, 975 err = bt_sock_wait_state(sk, BT_CLOSED,
914 sk->sk_lingertime); 976 sk->sk_lingertime);
915 } 977 }
@@ -929,7 +991,8 @@ static int sco_sock_release(struct socket *sock)
929 991
930 sco_sock_close(sk); 992 sco_sock_close(sk);
931 993
932 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) { 994 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
995 !(current->flags & PF_EXITING)) {
933 lock_sock(sk); 996 lock_sock(sk);
934 err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime); 997 err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
935 release_sock(sk); 998 release_sock(sk);
@@ -940,44 +1003,6 @@ static int sco_sock_release(struct socket *sock)
940 return err; 1003 return err;
941} 1004}
942 1005
943static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
944{
945 BT_DBG("conn %p", conn);
946
947 sco_pi(sk)->conn = conn;
948 conn->sk = sk;
949
950 if (parent)
951 bt_accept_enqueue(parent, sk);
952}
953
954/* Delete channel.
955 * Must be called on the locked socket. */
956static void sco_chan_del(struct sock *sk, int err)
957{
958 struct sco_conn *conn;
959
960 conn = sco_pi(sk)->conn;
961
962 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
963
964 if (conn) {
965 sco_conn_lock(conn);
966 conn->sk = NULL;
967 sco_pi(sk)->conn = NULL;
968 sco_conn_unlock(conn);
969
970 if (conn->hcon)
971 hci_conn_drop(conn->hcon);
972 }
973
974 sk->sk_state = BT_CLOSED;
975 sk->sk_err = err;
976 sk->sk_state_change(sk);
977
978 sock_set_flag(sk, SOCK_ZAPPED);
979}
980
981static void sco_conn_ready(struct sco_conn *conn) 1006static void sco_conn_ready(struct sco_conn *conn)
982{ 1007{
983 struct sock *parent; 1008 struct sock *parent;