diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-12-19 14:28:22 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-12-19 14:28:22 -0500 |
commit | 9662cbc712babe3f7a792af2bdd47fa0c631f27f (patch) | |
tree | 9a19f5656fb83ab58a4a3773b12ed1036bf8753b /net/bluetooth/l2cap_sock.c | |
parent | 640f5950a7d9fd0d279d843b261eb934793605fb (diff) | |
parent | 4b0b2f088f12e2ada1297502d7bebde182cf65b0 (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.c | 62 |
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 | ||
184 | wait: | ||
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)); |
187 | done: | 132 | done: |
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 | ||