aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap_sock.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-12-19 14:28:22 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-12-19 14:28:22 -0500
commit9662cbc712babe3f7a792af2bdd47fa0c631f27f (patch)
tree9a19f5656fb83ab58a4a3773b12ed1036bf8753b /net/bluetooth/l2cap_sock.c
parent640f5950a7d9fd0d279d843b261eb934793605fb (diff)
parent4b0b2f088f12e2ada1297502d7bebde182cf65b0 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
-rw-r--r--net/bluetooth/l2cap_sock.c62
1 files changed, 4 insertions, 58 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index f73704321a77..9ca5616166f7 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -3,6 +3,7 @@
3 Copyright (C) 2000-2001 Qualcomm Incorporated 3 Copyright (C) 2000-2001 Qualcomm Incorporated
4 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org> 4 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
5 Copyright (C) 2010 Google Inc. 5 Copyright (C) 2010 Google Inc.
6 Copyright (C) 2011 ProFUSION Embedded Systems
6 7
7 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 8 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
8 9
@@ -122,70 +123,15 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
122 if (la.l2_cid && la.l2_psm) 123 if (la.l2_cid && la.l2_psm)
123 return -EINVAL; 124 return -EINVAL;
124 125
125 lock_sock(sk); 126 err = l2cap_chan_connect(chan, la.l2_psm, la.l2_cid, &la.l2_bdaddr);
126
127 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED
128 && !(la.l2_psm || la.l2_cid)) {
129 err = -EINVAL;
130 goto done;
131 }
132
133 switch (chan->mode) {
134 case L2CAP_MODE_BASIC:
135 break;
136 case L2CAP_MODE_ERTM:
137 case L2CAP_MODE_STREAMING:
138 if (!disable_ertm)
139 break;
140 /* fall through */
141 default:
142 err = -ENOTSUPP;
143 goto done;
144 }
145
146 switch (sk->sk_state) {
147 case BT_CONNECT:
148 case BT_CONNECT2:
149 case BT_CONFIG:
150 /* Already connecting */
151 goto wait;
152
153 case BT_CONNECTED:
154 /* Already connected */
155 err = -EISCONN;
156 goto done;
157
158 case BT_OPEN:
159 case BT_BOUND:
160 /* Can connect */
161 break;
162
163 default:
164 err = -EBADFD;
165 goto done;
166 }
167
168 /* PSM must be odd and lsb of upper byte must be 0 */
169 if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && !la.l2_cid &&
170 chan->chan_type != L2CAP_CHAN_RAW) {
171 err = -EINVAL;
172 goto done;
173 }
174
175 /* Set destination address and psm */
176 bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
177 chan->psm = la.l2_psm;
178 chan->dcid = la.l2_cid;
179
180 err = l2cap_chan_connect(l2cap_pi(sk)->chan);
181 if (err) 127 if (err)
182 goto done; 128 goto done;
183 129
184wait:
185 err = bt_sock_wait_state(sk, BT_CONNECTED, 130 err = bt_sock_wait_state(sk, BT_CONNECTED,
186 sock_sndtimeo(sk, flags & O_NONBLOCK)); 131 sock_sndtimeo(sk, flags & O_NONBLOCK));
187done: 132done:
188 release_sock(sk); 133 if (sock_owned_by_user(sk))
134 release_sock(sk);
189 return err; 135 return err;
190} 136}
191 137