blob: c6678f2bffc958e0f10e511ee9522b5dd52bbd34 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth SCO sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010028#include <linux/debugfs.h>
29#include <linux/seq_file.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070030
31#include <net/bluetooth/bluetooth.h>
32#include <net/bluetooth/hci_core.h>
33#include <net/bluetooth/sco.h>
34
Rusty Russelleb939922011-12-19 14:08:01 +000035static bool disable_esco;
Linus Torvalds1da177e2005-04-16 15:20:36 -070036
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080037static const struct proto_ops sco_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070038
39static struct bt_sock_list sco_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070040 .lock = __RW_LOCK_UNLOCKED(sco_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070041};
42
43static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
44static void sco_chan_del(struct sock *sk, int err);
45
Linus Torvalds1da177e2005-04-16 15:20:36 -070046static void sco_sock_close(struct sock *sk);
47static void sco_sock_kill(struct sock *sk);
48
49/* ---- SCO timers ---- */
50static void sco_sock_timeout(unsigned long arg)
51{
52 struct sock *sk = (struct sock *) arg;
53
54 BT_DBG("sock %p state %d", sk, sk->sk_state);
55
56 bh_lock_sock(sk);
57 sk->sk_err = ETIMEDOUT;
58 sk->sk_state_change(sk);
59 bh_unlock_sock(sk);
60
61 sco_sock_kill(sk);
62 sock_put(sk);
63}
64
65static void sco_sock_set_timer(struct sock *sk, long timeout)
66{
67 BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout);
68 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
69}
70
71static void sco_sock_clear_timer(struct sock *sk)
72{
73 BT_DBG("sock %p state %d", sk, sk->sk_state);
74 sk_stop_timer(sk, &sk->sk_timer);
75}
76
Linus Torvalds1da177e2005-04-16 15:20:36 -070077/* ---- SCO connections ---- */
Lukasz Rymanowski519e42b2012-04-19 16:12:28 +020078static struct sco_conn *sco_conn_add(struct hci_conn *hcon)
Linus Torvalds1da177e2005-04-16 15:20:36 -070079{
80 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann25ea6db2006-07-06 15:40:09 +020081 struct sco_conn *conn = hcon->sco_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070082
Lukasz Rymanowski519e42b2012-04-19 16:12:28 +020083 if (conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 return conn;
85
Marcel Holtmann25ea6db2006-07-06 15:40:09 +020086 conn = kzalloc(sizeof(struct sco_conn), GFP_ATOMIC);
87 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
90 spin_lock_init(&conn->lock);
91
92 hcon->sco_data = conn;
93 conn->hcon = hcon;
94
95 conn->src = &hdev->bdaddr;
96 conn->dst = &hcon->dst;
97
98 if (hdev->sco_mtu > 0)
99 conn->mtu = hdev->sco_mtu;
100 else
101 conn->mtu = 60;
102
103 BT_DBG("hcon %p conn %p", hcon, conn);
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200104
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 return conn;
106}
107
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300108static struct sock *sco_chan_get(struct sco_conn *conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109{
110 struct sock *sk = NULL;
111 sco_conn_lock(conn);
112 sk = conn->sk;
113 sco_conn_unlock(conn);
114 return sk;
115}
116
117static int sco_conn_del(struct hci_conn *hcon, int err)
118{
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200119 struct sco_conn *conn = hcon->sco_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 struct sock *sk;
121
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200122 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123 return 0;
124
125 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
126
127 /* Kill socket */
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200128 sk = sco_chan_get(conn);
129 if (sk) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 bh_lock_sock(sk);
131 sco_sock_clear_timer(sk);
132 sco_chan_del(sk, err);
133 bh_unlock_sock(sk);
Gustavo Padovan269c4842012-06-15 02:30:20 -0300134
135 sco_conn_lock(conn);
136 conn->sk = NULL;
137 sco_pi(sk)->conn = NULL;
138 sco_conn_unlock(conn);
139
140 if (conn->hcon)
141 hci_conn_put(conn->hcon);
142
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143 sco_sock_kill(sk);
144 }
145
146 hcon->sco_data = NULL;
147 kfree(conn);
148 return 0;
149}
150
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300151static int sco_chan_add(struct sco_conn *conn, struct sock *sk,
152 struct sock *parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153{
154 int err = 0;
155
156 sco_conn_lock(conn);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300157 if (conn->sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 err = -EBUSY;
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300159 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 __sco_chan_add(conn, sk, parent);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300161
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162 sco_conn_unlock(conn);
163 return err;
164}
165
166static int sco_connect(struct sock *sk)
167{
168 bdaddr_t *src = &bt_sk(sk)->src;
169 bdaddr_t *dst = &bt_sk(sk)->dst;
170 struct sco_conn *conn;
171 struct hci_conn *hcon;
172 struct hci_dev *hdev;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200173 int err, type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +0300175 BT_DBG("%pMR -> %pMR", src, dst);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200177 hdev = hci_get_route(dst, src);
178 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 return -EHOSTUNREACH;
180
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300181 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182
Marcel Holtmann7cb127d2008-07-14 20:13:53 +0200183 if (lmp_esco_capable(hdev) && !disable_esco)
184 type = ESCO_LINK;
185 else
186 type = SCO_LINK;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200187
Andre Guedesb12f62c2012-04-24 21:02:54 -0300188 hcon = hci_connect(hdev, type, dst, BDADDR_BREDR, BT_SECURITY_LOW,
189 HCI_AT_NO_BONDING);
Ville Tervo30e76272011-02-22 16:10:53 -0300190 if (IS_ERR(hcon)) {
191 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -0300193 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194
Lukasz Rymanowski519e42b2012-04-19 16:12:28 +0200195 conn = sco_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196 if (!conn) {
197 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -0300198 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199 goto done;
200 }
201
202 /* Update source addr of the socket */
203 bacpy(src, conn->src);
204
205 err = sco_chan_add(conn, sk, NULL);
206 if (err)
207 goto done;
208
209 if (hcon->state == BT_CONNECTED) {
210 sco_sock_clear_timer(sk);
211 sk->sk_state = BT_CONNECTED;
212 } else {
213 sk->sk_state = BT_CONNECT;
214 sco_sock_set_timer(sk, sk->sk_sndtimeo);
215 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200216
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217done:
Gustavo F. Padovan09fd0de2011-06-17 13:03:21 -0300218 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219 hci_dev_put(hdev);
220 return err;
221}
222
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300223static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224{
225 struct sco_conn *conn = sco_pi(sk)->conn;
226 struct sk_buff *skb;
Mikel Astiz088ce082012-04-11 08:48:48 +0200227 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
229 /* Check outgoing MTU */
230 if (len > conn->mtu)
231 return -EINVAL;
232
233 BT_DBG("sk %p len %d", sk, len);
234
Mikel Astiz088ce082012-04-11 08:48:48 +0200235 skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300236 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 return err;
238
Mikel Astiz088ce082012-04-11 08:48:48 +0200239 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300240 kfree_skb(skb);
241 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242 }
243
Gustavo F. Padovan0d861d82010-05-01 16:15:35 -0300244 hci_send_sco(conn->hcon, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245
Mikel Astiz088ce082012-04-11 08:48:48 +0200246 return len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247}
248
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300249static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250{
251 struct sock *sk = sco_chan_get(conn);
252
253 if (!sk)
254 goto drop;
255
256 BT_DBG("sk %p len %d", sk, skb->len);
257
258 if (sk->sk_state != BT_CONNECTED)
259 goto drop;
260
261 if (!sock_queue_rcv_skb(sk, skb))
262 return;
263
264drop:
265 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266}
267
268/* -------- Socket interface ---------- */
Marcel Holtmannfb334052012-04-19 14:37:58 +0200269static struct sock *__sco_get_sock_listen_by_addr(bdaddr_t *ba)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 struct hlist_node *node;
Marcel Holtmannfb334052012-04-19 14:37:58 +0200272 struct sock *sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273
Marcel Holtmannfb334052012-04-19 14:37:58 +0200274 sk_for_each(sk, node, &sco_sk_list.head) {
275 if (sk->sk_state != BT_LISTEN)
276 continue;
277
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278 if (!bacmp(&bt_sk(sk)->src, ba))
Marcel Holtmannfb334052012-04-19 14:37:58 +0200279 return sk;
280 }
281
282 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283}
284
285/* Find socket listening on source bdaddr.
286 * Returns closest match.
287 */
288static struct sock *sco_get_sock_listen(bdaddr_t *src)
289{
290 struct sock *sk = NULL, *sk1 = NULL;
291 struct hlist_node *node;
292
293 read_lock(&sco_sk_list.lock);
294
295 sk_for_each(sk, node, &sco_sk_list.head) {
296 if (sk->sk_state != BT_LISTEN)
297 continue;
298
299 /* Exact match. */
300 if (!bacmp(&bt_sk(sk)->src, src))
301 break;
302
303 /* Closest match */
304 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
305 sk1 = sk;
306 }
307
308 read_unlock(&sco_sk_list.lock);
309
310 return node ? sk : sk1;
311}
312
313static void sco_sock_destruct(struct sock *sk)
314{
315 BT_DBG("sk %p", sk);
316
317 skb_queue_purge(&sk->sk_receive_queue);
318 skb_queue_purge(&sk->sk_write_queue);
319}
320
321static void sco_sock_cleanup_listen(struct sock *parent)
322{
323 struct sock *sk;
324
325 BT_DBG("parent %p", parent);
326
327 /* Close not yet accepted channels */
328 while ((sk = bt_accept_dequeue(parent, NULL))) {
329 sco_sock_close(sk);
330 sco_sock_kill(sk);
331 }
332
333 parent->sk_state = BT_CLOSED;
334 sock_set_flag(parent, SOCK_ZAPPED);
335}
336
337/* Kill socket (only if zapped and orphan)
338 * Must be called on unlocked socket.
339 */
340static void sco_sock_kill(struct sock *sk)
341{
342 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
343 return;
344
345 BT_DBG("sk %p state %d", sk, sk->sk_state);
346
347 /* Kill poor orphan */
348 bt_sock_unlink(&sco_sk_list, sk);
349 sock_set_flag(sk, SOCK_DEAD);
350 sock_put(sk);
351}
352
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200353static void __sco_sock_close(struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354{
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200355 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356
357 switch (sk->sk_state) {
358 case BT_LISTEN:
359 sco_sock_cleanup_listen(sk);
360 break;
361
362 case BT_CONNECTED:
363 case BT_CONFIG:
Luiz Augusto von Dentz4a777082011-05-12 11:13:15 +0300364 if (sco_pi(sk)->conn) {
365 sk->sk_state = BT_DISCONN;
366 sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT);
367 hci_conn_put(sco_pi(sk)->conn->hcon);
368 sco_pi(sk)->conn->hcon = NULL;
369 } else
370 sco_chan_del(sk, ECONNRESET);
371 break;
372
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 case BT_CONNECT:
374 case BT_DISCONN:
375 sco_chan_del(sk, ECONNRESET);
376 break;
377
378 default:
379 sock_set_flag(sk, SOCK_ZAPPED);
380 break;
Stephen Hemminger3ff50b72007-04-20 17:09:22 -0700381 }
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200382}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200384/* Must be called on unlocked socket. */
385static void sco_sock_close(struct sock *sk)
386{
387 sco_sock_clear_timer(sk);
388 lock_sock(sk);
389 __sco_sock_close(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 sco_sock_kill(sk);
392}
393
394static void sco_sock_init(struct sock *sk, struct sock *parent)
395{
396 BT_DBG("sk %p", sk);
397
Paul Moore6230c9b2011-10-07 09:40:59 +0000398 if (parent) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 sk->sk_type = parent->sk_type;
Paul Moore6230c9b2011-10-07 09:40:59 +0000400 security_sk_clone(parent, sk);
401 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402}
403
404static struct proto sco_proto = {
405 .name = "SCO",
406 .owner = THIS_MODULE,
407 .obj_size = sizeof(struct sco_pinfo)
408};
409
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700410static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411{
412 struct sock *sk;
413
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700414 sk = sk_alloc(net, PF_BLUETOOTH, prio, &sco_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 if (!sk)
416 return NULL;
417
418 sock_init_data(sock, sk);
419 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
420
421 sk->sk_destruct = sco_sock_destruct;
422 sk->sk_sndtimeo = SCO_CONN_TIMEOUT;
423
424 sock_reset_flag(sk, SOCK_ZAPPED);
425
426 sk->sk_protocol = proto;
427 sk->sk_state = BT_OPEN;
428
Pavel Emelyanovb24b8a22008-01-23 21:20:07 -0800429 setup_timer(&sk->sk_timer, sco_sock_timeout, (unsigned long)sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430
431 bt_sock_link(&sco_sk_list, sk);
432 return sk;
433}
434
Eric Paris3f378b62009-11-05 22:18:14 -0800435static int sco_sock_create(struct net *net, struct socket *sock, int protocol,
436 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437{
438 struct sock *sk;
439
440 BT_DBG("sock %p", sock);
441
442 sock->state = SS_UNCONNECTED;
443
444 if (sock->type != SOCK_SEQPACKET)
445 return -ESOCKTNOSUPPORT;
446
447 sock->ops = &sco_sock_ops;
448
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700449 sk = sco_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Marcel Holtmann74da6262006-10-15 17:31:14 +0200450 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 return -ENOMEM;
452
453 sco_sock_init(sk, NULL);
454 return 0;
455}
456
457static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
458{
459 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
460 struct sock *sk = sock->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 int err = 0;
462
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +0300463 BT_DBG("sk %p %pMR", sk, &sa->sco_bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464
465 if (!addr || addr->sa_family != AF_BLUETOOTH)
466 return -EINVAL;
467
468 lock_sock(sk);
469
470 if (sk->sk_state != BT_OPEN) {
471 err = -EBADFD;
472 goto done;
473 }
474
Marcel Holtmann8ed21f72012-04-19 13:43:53 +0200475 if (sk->sk_type != SOCK_SEQPACKET) {
476 err = -EINVAL;
477 goto done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 }
479
Marcel Holtmann8ed21f72012-04-19 13:43:53 +0200480 bacpy(&bt_sk(sk)->src, &sa->sco_bdaddr);
481
482 sk->sk_state = BT_BOUND;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483
484done:
485 release_sock(sk);
486 return err;
487}
488
489static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
490{
491 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
492 struct sock *sk = sock->sk;
493 int err = 0;
494
495
496 BT_DBG("sk %p", sk);
497
Changli Gao6503d962010-03-31 22:58:26 +0000498 if (alen < sizeof(struct sockaddr_sco) ||
499 addr->sa_family != AF_BLUETOOTH)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 return -EINVAL;
501
502 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
503 return -EBADFD;
504
505 if (sk->sk_type != SOCK_SEQPACKET)
506 return -EINVAL;
507
508 lock_sock(sk);
509
510 /* Set destination address and psm */
511 bacpy(&bt_sk(sk)->dst, &sa->sco_bdaddr);
512
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200513 err = sco_connect(sk);
514 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 goto done;
516
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900517 err = bt_sock_wait_state(sk, BT_CONNECTED,
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -0300518 sock_sndtimeo(sk, flags & O_NONBLOCK));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519
520done:
521 release_sock(sk);
522 return err;
523}
524
525static int sco_sock_listen(struct socket *sock, int backlog)
526{
527 struct sock *sk = sock->sk;
Marcel Holtmannfb334052012-04-19 14:37:58 +0200528 bdaddr_t *src = &bt_sk(sk)->src;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 int err = 0;
530
531 BT_DBG("sk %p backlog %d", sk, backlog);
532
533 lock_sock(sk);
534
Marcel Holtmann7d5d7752012-04-19 13:43:52 +0200535 if (sk->sk_state != BT_BOUND) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 err = -EBADFD;
537 goto done;
538 }
539
Marcel Holtmann7d5d7752012-04-19 13:43:52 +0200540 if (sk->sk_type != SOCK_SEQPACKET) {
541 err = -EINVAL;
542 goto done;
543 }
544
Marcel Holtmannfb334052012-04-19 14:37:58 +0200545 write_lock(&sco_sk_list.lock);
546
547 if (__sco_get_sock_listen_by_addr(src)) {
548 err = -EADDRINUSE;
549 goto unlock;
550 }
551
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 sk->sk_max_ack_backlog = backlog;
553 sk->sk_ack_backlog = 0;
Marcel Holtmannfb334052012-04-19 14:37:58 +0200554
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 sk->sk_state = BT_LISTEN;
556
Marcel Holtmannfb334052012-04-19 14:37:58 +0200557unlock:
558 write_unlock(&sco_sk_list.lock);
559
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560done:
561 release_sock(sk);
562 return err;
563}
564
565static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags)
566{
567 DECLARE_WAITQUEUE(wait, current);
568 struct sock *sk = sock->sk, *ch;
569 long timeo;
570 int err = 0;
571
572 lock_sock(sk);
573
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
575
576 BT_DBG("sk %p timeo %ld", sk, timeo);
577
578 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +0000579 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Peter Hurley552b0d32011-07-24 00:11:01 -0400580 while (1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 set_current_state(TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582
583 if (sk->sk_state != BT_LISTEN) {
584 err = -EBADFD;
585 break;
586 }
587
Peter Hurley552b0d32011-07-24 00:11:01 -0400588 ch = bt_accept_dequeue(sk, newsock);
589 if (ch)
590 break;
591
592 if (!timeo) {
593 err = -EAGAIN;
594 break;
595 }
596
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 if (signal_pending(current)) {
598 err = sock_intr_errno(timeo);
599 break;
600 }
Peter Hurley552b0d32011-07-24 00:11:01 -0400601
602 release_sock(sk);
603 timeo = schedule_timeout(timeo);
604 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 }
Peter Hurley552b0d32011-07-24 00:11:01 -0400606 __set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +0000607 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
609 if (err)
610 goto done;
611
612 newsock->state = SS_CONNECTED;
613
614 BT_DBG("new socket %p", ch);
615
616done:
617 release_sock(sk);
618 return err;
619}
620
621static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
622{
623 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
624 struct sock *sk = sock->sk;
625
626 BT_DBG("sock %p, sk %p", sock, sk);
627
628 addr->sa_family = AF_BLUETOOTH;
629 *len = sizeof(struct sockaddr_sco);
630
631 if (peer)
632 bacpy(&sa->sco_bdaddr, &bt_sk(sk)->dst);
633 else
634 bacpy(&sa->sco_bdaddr, &bt_sk(sk)->src);
635
636 return 0;
637}
638
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900639static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 struct msghdr *msg, size_t len)
641{
642 struct sock *sk = sock->sk;
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300643 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644
645 BT_DBG("sock %p, sk %p", sock, sk);
646
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -0800647 err = sock_error(sk);
648 if (err)
649 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650
651 if (msg->msg_flags & MSG_OOB)
652 return -EOPNOTSUPP;
653
654 lock_sock(sk);
655
656 if (sk->sk_state == BT_CONNECTED)
657 err = sco_send_frame(sk, msg, len);
658 else
659 err = -ENOTCONN;
660
661 release_sock(sk);
662 return err;
663}
664
David S. Millerb7058842009-09-30 16:12:20 -0700665static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666{
667 struct sock *sk = sock->sk;
668 int err = 0;
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +0100669 u32 opt;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670
671 BT_DBG("sk %p", sk);
672
673 lock_sock(sk);
674
675 switch (optname) {
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +0100676
677 case BT_DEFER_SETUP:
678 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
679 err = -EINVAL;
680 break;
681 }
682
683 if (get_user(opt, (u32 __user *) optval)) {
684 err = -EFAULT;
685 break;
686 }
687
688 if (opt)
689 set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
690 else
691 clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
692 break;
693
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694 default:
695 err = -ENOPROTOOPT;
696 break;
697 }
698
699 release_sock(sk);
700 return err;
701}
702
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100703static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704{
705 struct sock *sk = sock->sk;
706 struct sco_options opts;
707 struct sco_conninfo cinfo;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900708 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709
710 BT_DBG("sk %p", sk);
711
712 if (get_user(len, optlen))
713 return -EFAULT;
714
715 lock_sock(sk);
716
717 switch (optname) {
718 case SCO_OPTIONS:
719 if (sk->sk_state != BT_CONNECTED) {
720 err = -ENOTCONN;
721 break;
722 }
723
724 opts.mtu = sco_pi(sk)->conn->mtu;
725
726 BT_DBG("mtu %d", opts.mtu);
727
728 len = min_t(unsigned int, len, sizeof(opts));
729 if (copy_to_user(optval, (char *)&opts, len))
730 err = -EFAULT;
731
732 break;
733
734 case SCO_CONNINFO:
735 if (sk->sk_state != BT_CONNECTED) {
736 err = -ENOTCONN;
737 break;
738 }
739
Vasiliy Kulikovc4c896e2011-02-14 13:54:26 +0300740 memset(&cinfo, 0, sizeof(cinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741 cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
742 memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3);
743
744 len = min_t(unsigned int, len, sizeof(cinfo));
745 if (copy_to_user(optval, (char *)&cinfo, len))
746 err = -EFAULT;
747
748 break;
749
750 default:
751 err = -ENOPROTOOPT;
752 break;
753 }
754
755 release_sock(sk);
756 return err;
757}
758
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100759static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
760{
761 struct sock *sk = sock->sk;
762 int len, err = 0;
763
764 BT_DBG("sk %p", sk);
765
766 if (level == SOL_SCO)
767 return sco_sock_getsockopt_old(sock, optname, optval, optlen);
768
769 if (get_user(len, optlen))
770 return -EFAULT;
771
772 lock_sock(sk);
773
774 switch (optname) {
Frédéric Dalleaub96e9c62012-11-21 10:51:11 +0100775
776 case BT_DEFER_SETUP:
777 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
778 err = -EINVAL;
779 break;
780 }
781
782 if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
783 (u32 __user *) optval))
784 err = -EFAULT;
785
786 break;
787
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100788 default:
789 err = -ENOPROTOOPT;
790 break;
791 }
792
793 release_sock(sk);
794 return err;
795}
796
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200797static int sco_sock_shutdown(struct socket *sock, int how)
798{
799 struct sock *sk = sock->sk;
800 int err = 0;
801
802 BT_DBG("sock %p, sk %p", sock, sk);
803
804 if (!sk)
805 return 0;
806
807 lock_sock(sk);
808 if (!sk->sk_shutdown) {
809 sk->sk_shutdown = SHUTDOWN_MASK;
810 sco_sock_clear_timer(sk);
811 __sco_sock_close(sk);
812
813 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
814 err = bt_sock_wait_state(sk, BT_CLOSED,
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -0300815 sk->sk_lingertime);
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200816 }
817 release_sock(sk);
818 return err;
819}
820
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821static int sco_sock_release(struct socket *sock)
822{
823 struct sock *sk = sock->sk;
824 int err = 0;
825
826 BT_DBG("sock %p, sk %p", sock, sk);
827
828 if (!sk)
829 return 0;
830
831 sco_sock_close(sk);
832
833 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) {
834 lock_sock(sk);
835 err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
836 release_sock(sk);
837 }
838
839 sock_orphan(sk);
840 sco_sock_kill(sk);
841 return err;
842}
843
844static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
845{
846 BT_DBG("conn %p", conn);
847
848 sco_pi(sk)->conn = conn;
849 conn->sk = sk;
850
851 if (parent)
852 bt_accept_enqueue(parent, sk);
853}
854
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900855/* Delete channel.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 * Must be called on the locked socket. */
857static void sco_chan_del(struct sock *sk, int err)
858{
859 struct sco_conn *conn;
860
861 conn = sco_pi(sk)->conn;
862
863 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
864
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 sk->sk_state = BT_CLOSED;
866 sk->sk_err = err;
867 sk->sk_state_change(sk);
868
869 sock_set_flag(sk, SOCK_ZAPPED);
870}
871
872static void sco_conn_ready(struct sco_conn *conn)
873{
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200874 struct sock *parent;
875 struct sock *sk = conn->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876
877 BT_DBG("conn %p", conn);
878
879 sco_conn_lock(conn);
880
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200881 if (sk) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 sco_sock_clear_timer(sk);
883 bh_lock_sock(sk);
884 sk->sk_state = BT_CONNECTED;
885 sk->sk_state_change(sk);
886 bh_unlock_sock(sk);
887 } else {
888 parent = sco_get_sock_listen(conn->src);
889 if (!parent)
890 goto done;
891
892 bh_lock_sock(parent);
893
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300894 sk = sco_sock_alloc(sock_net(parent), NULL,
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -0300895 BTPROTO_SCO, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896 if (!sk) {
897 bh_unlock_sock(parent);
898 goto done;
899 }
900
901 sco_sock_init(sk, parent);
902
903 bacpy(&bt_sk(sk)->src, conn->src);
904 bacpy(&bt_sk(sk)->dst, conn->dst);
905
906 hci_conn_hold(conn->hcon);
907 __sco_chan_add(conn, sk, parent);
908
909 sk->sk_state = BT_CONNECTED;
910
911 /* Wake up parent */
912 parent->sk_data_ready(parent, 1);
913
914 bh_unlock_sock(parent);
915 }
916
917done:
918 sco_conn_unlock(conn);
919}
920
921/* ----- SCO interface with lower layer (HCI) ----- */
Ulisses Furquim686ebf22011-12-21 10:11:33 -0200922int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923{
Gustavo Padovanfc5fef62012-05-23 04:04:19 -0300924 struct sock *sk;
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +0100925 struct hlist_node *node;
926 int lm = 0;
927
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +0300928 BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +0100930 /* Find listening sockets */
931 read_lock(&sco_sk_list.lock);
932 sk_for_each(sk, node, &sco_sk_list.head) {
933 if (sk->sk_state != BT_LISTEN)
934 continue;
935
936 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr) ||
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -0300937 !bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +0100938 lm |= HCI_LM_ACCEPT;
939 break;
940 }
941 }
942 read_unlock(&sco_sk_list.lock);
943
944 return lm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945}
946
Andrei Emeltchenko9e664632012-07-24 16:06:15 +0300947void sco_connect_cfm(struct hci_conn *hcon, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948{
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +0300949 BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950 if (!status) {
951 struct sco_conn *conn;
952
Lukasz Rymanowski519e42b2012-04-19 16:12:28 +0200953 conn = sco_conn_add(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 if (conn)
955 sco_conn_ready(conn);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900956 } else
Joe Perchese1750722011-06-29 18:18:29 -0700957 sco_conn_del(hcon, bt_to_errno(status));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958}
959
Andrei Emeltchenko9e664632012-07-24 16:06:15 +0300960void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961{
962 BT_DBG("hcon %p reason %d", hcon, reason);
963
Joe Perchese1750722011-06-29 18:18:29 -0700964 sco_conn_del(hcon, bt_to_errno(reason));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965}
966
Ulisses Furquim686ebf22011-12-21 10:11:33 -0200967int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968{
969 struct sco_conn *conn = hcon->sco_data;
970
971 if (!conn)
972 goto drop;
973
974 BT_DBG("conn %p len %d", conn, skb->len);
975
976 if (skb->len) {
977 sco_recv_frame(conn, skb);
978 return 0;
979 }
980
981drop:
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900982 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983 return 0;
984}
985
Marcel Holtmannaef7d972010-03-21 05:27:45 +0100986static int sco_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987{
988 struct sock *sk;
989 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990
Gustavo F. Padovanee65d192011-12-27 15:28:46 -0200991 read_lock(&sco_sk_list.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992
Marcel Holtmannbe9d1222005-11-08 09:57:38 -0800993 sk_for_each(sk, node, &sco_sk_list.head) {
Andrei Emeltchenkofcb73332012-09-25 12:49:44 +0300994 seq_printf(f, "%pMR %pMR %d\n", &bt_sk(sk)->src,
995 &bt_sk(sk)->dst, sk->sk_state);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -0800996 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997
Gustavo F. Padovanee65d192011-12-27 15:28:46 -0200998 read_unlock(&sco_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -0800999
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001000 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001}
1002
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001003static int sco_debugfs_open(struct inode *inode, struct file *file)
1004{
1005 return single_open(file, sco_debugfs_show, inode->i_private);
1006}
1007
1008static const struct file_operations sco_debugfs_fops = {
1009 .open = sco_debugfs_open,
1010 .read = seq_read,
1011 .llseek = seq_lseek,
1012 .release = single_release,
1013};
1014
1015static struct dentry *sco_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08001017static const struct proto_ops sco_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018 .family = PF_BLUETOOTH,
1019 .owner = THIS_MODULE,
1020 .release = sco_sock_release,
1021 .bind = sco_sock_bind,
1022 .connect = sco_sock_connect,
1023 .listen = sco_sock_listen,
1024 .accept = sco_sock_accept,
1025 .getname = sco_sock_getname,
1026 .sendmsg = sco_sock_sendmsg,
1027 .recvmsg = bt_sock_recvmsg,
1028 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02001029 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 .mmap = sock_no_mmap,
1031 .socketpair = sock_no_socketpair,
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +02001032 .shutdown = sco_sock_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033 .setsockopt = sco_sock_setsockopt,
1034 .getsockopt = sco_sock_getsockopt
1035};
1036
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00001037static const struct net_proto_family sco_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 .family = PF_BLUETOOTH,
1039 .owner = THIS_MODULE,
1040 .create = sco_sock_create,
1041};
1042
Gustavo F. Padovan64274512011-02-07 20:08:52 -02001043int __init sco_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044{
1045 int err;
1046
1047 err = proto_register(&sco_proto, 0);
1048 if (err < 0)
1049 return err;
1050
1051 err = bt_sock_register(BTPROTO_SCO, &sco_sock_family_ops);
1052 if (err < 0) {
1053 BT_ERR("SCO socket registration failed");
1054 goto error;
1055 }
1056
Masatake YAMATOde9b9212012-07-26 01:30:12 +09001057 err = bt_procfs_init(THIS_MODULE, &init_net, "sco", &sco_sk_list, NULL);
1058 if (err < 0) {
1059 BT_ERR("Failed to create SCO proc file");
1060 bt_sock_unregister(BTPROTO_SCO);
1061 goto error;
1062 }
1063
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001064 if (bt_debugfs) {
Gustavo Padovanbe7c2b92012-05-17 00:36:21 -03001065 sco_debugfs = debugfs_create_file("sco", 0444, bt_debugfs,
1066 NULL, &sco_debugfs_fops);
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001067 if (!sco_debugfs)
1068 BT_ERR("Failed to create SCO debug file");
1069 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071 BT_INFO("SCO socket layer initialized");
1072
1073 return 0;
1074
1075error:
1076 proto_unregister(&sco_proto);
1077 return err;
1078}
1079
Gustavo F. Padovan64274512011-02-07 20:08:52 -02001080void __exit sco_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081{
Masatake YAMATOde9b9212012-07-26 01:30:12 +09001082 bt_procfs_cleanup(&init_net, "sco");
1083
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001084 debugfs_remove(sco_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085
1086 if (bt_sock_unregister(BTPROTO_SCO) < 0)
1087 BT_ERR("SCO socket unregistration failed");
1088
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 proto_unregister(&sco_proto);
1090}
1091
Marcel Holtmann7cb127d2008-07-14 20:13:53 +02001092module_param(disable_esco, bool, 0644);
1093MODULE_PARM_DESC(disable_esco, "Disable eSCO connection creation");