blob: f8c3bbaf2d3f22e61adf901b8c73502b641153c4 [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
Kun Han Kim15b911f2011-07-08 09:30:28 -07004 Copyright (c) 2011, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07005
6 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as
10 published by the Free Software Foundation;
11
12 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
13 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
15 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090016 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
17 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070019 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090021 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
22 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070023 SOFTWARE IS DISCLAIMED.
24*/
25
26/* Bluetooth SCO sockets. */
27
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/module.h>
29
30#include <linux/types.h>
31#include <linux/errno.h>
32#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/sched.h>
34#include <linux/slab.h>
35#include <linux/poll.h>
36#include <linux/fcntl.h>
37#include <linux/init.h>
38#include <linux/interrupt.h>
39#include <linux/socket.h>
40#include <linux/skbuff.h>
Marcel Holtmannbe9d1222005-11-08 09:57:38 -080041#include <linux/device.h>
Marcel Holtmannaef7d972010-03-21 05:27:45 +010042#include <linux/debugfs.h>
43#include <linux/seq_file.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <linux/list.h>
45#include <net/sock.h>
46
47#include <asm/system.h>
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +020048#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
50#include <net/bluetooth/bluetooth.h>
51#include <net/bluetooth/hci_core.h>
52#include <net/bluetooth/sco.h>
53
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +020054static int disable_esco;
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Eric Dumazet90ddc4f2005-12-22 12:49:22 -080056static const struct proto_ops sco_sock_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
58static struct bt_sock_list sco_sk_list = {
Robert P. J. Dayd5fb2962008-03-28 16:17:38 -070059 .lock = __RW_LOCK_UNLOCKED(sco_sk_list.lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070060};
61
62static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
63static void sco_chan_del(struct sock *sk, int err);
64
Mat Martineau3b9239a2012-02-16 11:54:30 -080065static int sco_conn_del(struct hci_conn *conn, int err, u8 is_process);
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
67static void sco_sock_close(struct sock *sk);
68static void sco_sock_kill(struct sock *sk);
69
70/* ---- SCO timers ---- */
71static void sco_sock_timeout(unsigned long arg)
72{
73 struct sock *sk = (struct sock *) arg;
74
75 BT_DBG("sock %p state %d", sk, sk->sk_state);
76
77 bh_lock_sock(sk);
78 sk->sk_err = ETIMEDOUT;
79 sk->sk_state_change(sk);
80 bh_unlock_sock(sk);
81
82 sco_sock_kill(sk);
83 sock_put(sk);
84}
85
86static void sco_sock_set_timer(struct sock *sk, long timeout)
87{
88 BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout);
89 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
90}
91
92static void sco_sock_clear_timer(struct sock *sk)
93{
94 BT_DBG("sock %p state %d", sk, sk->sk_state);
95 sk_stop_timer(sk, &sk->sk_timer);
96}
97
Linus Torvalds1da177e2005-04-16 15:20:36 -070098/* ---- SCO connections ---- */
99static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
100{
101 struct hci_dev *hdev = hcon->hdev;
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200102 struct sco_conn *conn = hcon->sco_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200104 if (conn || status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 return conn;
106
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200107 conn = kzalloc(sizeof(struct sco_conn), GFP_ATOMIC);
108 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110
111 spin_lock_init(&conn->lock);
112
113 hcon->sco_data = conn;
114 conn->hcon = hcon;
115
116 conn->src = &hdev->bdaddr;
117 conn->dst = &hcon->dst;
118
119 if (hdev->sco_mtu > 0)
120 conn->mtu = hdev->sco_mtu;
121 else
122 conn->mtu = 60;
123
124 BT_DBG("hcon %p conn %p", hcon, conn);
Marcel Holtmann25ea6db2006-07-06 15:40:09 +0200125
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 return conn;
127}
128
129static inline struct sock *sco_chan_get(struct sco_conn *conn)
130{
131 struct sock *sk = NULL;
132 sco_conn_lock(conn);
133 sk = conn->sk;
134 sco_conn_unlock(conn);
135 return sk;
136}
137
Mat Martineau3b9239a2012-02-16 11:54:30 -0800138static int sco_conn_del(struct hci_conn *hcon, int err, u8 is_process)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139{
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200140 struct sco_conn *conn = hcon->sco_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141 struct sock *sk;
142
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200143 if (!conn)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 return 0;
145
146 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
147
148 /* Kill socket */
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200149 sk = sco_chan_get(conn);
150 if (sk) {
Mat Martineau3b9239a2012-02-16 11:54:30 -0800151 if (is_process)
152 lock_sock(sk);
153 else
154 bh_lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 sco_sock_clear_timer(sk);
156 sco_chan_del(sk, err);
Mat Martineau3b9239a2012-02-16 11:54:30 -0800157 if (is_process)
158 release_sock(sk);
159 else
160 bh_unlock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 sco_sock_kill(sk);
162 }
163
164 hcon->sco_data = NULL;
165 kfree(conn);
166 return 0;
167}
168
169static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
170{
171 int err = 0;
172
173 sco_conn_lock(conn);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300174 if (conn->sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175 err = -EBUSY;
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300176 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 __sco_chan_add(conn, sk, parent);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300178
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 sco_conn_unlock(conn);
180 return err;
181}
182
Kun Han Kim15b911f2011-07-08 09:30:28 -0700183static int sco_connect(struct sock *sk, __s8 is_wbs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184{
185 bdaddr_t *src = &bt_sk(sk)->src;
186 bdaddr_t *dst = &bt_sk(sk)->dst;
Nick Pellybbcda3b2010-02-11 11:54:28 -0800187 __u16 pkt_type = sco_pi(sk)->pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 struct sco_conn *conn;
189 struct hci_conn *hcon;
190 struct hci_dev *hdev;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200191 int err, type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192
193 BT_DBG("%s -> %s", batostr(src), batostr(dst));
194
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200195 hdev = hci_get_route(dst, src);
196 if (!hdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 return -EHOSTUNREACH;
198
199 hci_dev_lock_bh(hdev);
200
Kun Han Kim15b911f2011-07-08 09:30:28 -0700201 hdev->is_wbs = is_wbs;
202
203 if (lmp_esco_capable(hdev) && !disable_esco) {
Marcel Holtmann7cb127d2008-07-14 20:13:53 +0200204 type = ESCO_LINK;
Kun Han Kim15b911f2011-07-08 09:30:28 -0700205 } else if (is_wbs) {
206 return -ENAVAIL;
207 } else {
Marcel Holtmann7cb127d2008-07-14 20:13:53 +0200208 type = SCO_LINK;
Nick Pellybbcda3b2010-02-11 11:54:28 -0800209 pkt_type &= SCO_ESCO_MASK;
210 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200211
Kun Han Kim15b911f2011-07-08 09:30:28 -0700212 BT_DBG("type: %d, pkt_type: 0x%x", type, pkt_type);
213
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700214 hcon = hci_connect(hdev, type, pkt_type, dst,
215 BT_SECURITY_LOW, HCI_AT_NO_BONDING);
Ville Tervo30e76272011-02-22 16:10:53 -0300216 if (IS_ERR(hcon)) {
217 err = PTR_ERR(hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 goto done;
Ville Tervo30e76272011-02-22 16:10:53 -0300219 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
Kun Han Kim15b911f2011-07-08 09:30:28 -0700221 if (is_wbs && (hcon->type != ESCO_LINK)) {
222 BT_ERR("WBS [ hcon->type: 0x%x, hcon->pkt_type: 0x%x ]",
223 hcon->type, hcon->pkt_type);
224 err = -EREMOTEIO;
225 goto done;
226 }
227
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228 conn = sco_conn_add(hcon, 0);
229 if (!conn) {
230 hci_conn_put(hcon);
Ville Tervo30e76272011-02-22 16:10:53 -0300231 err = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232 goto done;
233 }
234
235 /* Update source addr of the socket */
236 bacpy(src, conn->src);
237
238 err = sco_chan_add(conn, sk, NULL);
239 if (err)
240 goto done;
241
242 if (hcon->state == BT_CONNECTED) {
243 sco_sock_clear_timer(sk);
244 sk->sk_state = BT_CONNECTED;
245 } else {
246 sk->sk_state = BT_CONNECT;
247 sco_sock_set_timer(sk, sk->sk_sndtimeo);
248 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200249
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250done:
251 hci_dev_unlock_bh(hdev);
252 hci_dev_put(hdev);
253 return err;
254}
255
256static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
257{
258 struct sco_conn *conn = sco_pi(sk)->conn;
259 struct sk_buff *skb;
260 int err, count;
261
262 /* Check outgoing MTU */
263 if (len > conn->mtu)
264 return -EINVAL;
265
266 BT_DBG("sk %p len %d", sk, len);
267
268 count = min_t(unsigned int, conn->mtu, len);
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300269 skb = bt_skb_send_alloc(sk, count,
270 msg->msg_flags & MSG_DONTWAIT, &err);
271 if (!skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272 return err;
273
274 if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300275 kfree_skb(skb);
276 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 }
278
Gustavo F. Padovan0d861d82010-05-01 16:15:35 -0300279 hci_send_sco(conn->hcon, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280
281 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282}
283
284static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
285{
286 struct sock *sk = sco_chan_get(conn);
287
288 if (!sk)
289 goto drop;
290
291 BT_DBG("sk %p len %d", sk, skb->len);
292
293 if (sk->sk_state != BT_CONNECTED)
294 goto drop;
295
296 if (!sock_queue_rcv_skb(sk, skb))
297 return;
298
299drop:
300 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301}
302
303/* -------- Socket interface ---------- */
304static struct sock *__sco_get_sock_by_addr(bdaddr_t *ba)
305{
306 struct sock *sk;
307 struct hlist_node *node;
308
309 sk_for_each(sk, node, &sco_sk_list.head)
310 if (!bacmp(&bt_sk(sk)->src, ba))
311 goto found;
312 sk = NULL;
313found:
314 return sk;
315}
316
317/* Find socket listening on source bdaddr.
318 * Returns closest match.
319 */
320static struct sock *sco_get_sock_listen(bdaddr_t *src)
321{
322 struct sock *sk = NULL, *sk1 = NULL;
323 struct hlist_node *node;
324
325 read_lock(&sco_sk_list.lock);
326
327 sk_for_each(sk, node, &sco_sk_list.head) {
328 if (sk->sk_state != BT_LISTEN)
329 continue;
330
331 /* Exact match. */
332 if (!bacmp(&bt_sk(sk)->src, src))
333 break;
334
335 /* Closest match */
336 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
337 sk1 = sk;
338 }
339
340 read_unlock(&sco_sk_list.lock);
341
342 return node ? sk : sk1;
343}
344
345static void sco_sock_destruct(struct sock *sk)
346{
347 BT_DBG("sk %p", sk);
348
349 skb_queue_purge(&sk->sk_receive_queue);
350 skb_queue_purge(&sk->sk_write_queue);
351}
352
353static void sco_sock_cleanup_listen(struct sock *parent)
354{
355 struct sock *sk;
356
357 BT_DBG("parent %p", parent);
358
359 /* Close not yet accepted channels */
360 while ((sk = bt_accept_dequeue(parent, NULL))) {
361 sco_sock_close(sk);
362 sco_sock_kill(sk);
363 }
364
365 parent->sk_state = BT_CLOSED;
366 sock_set_flag(parent, SOCK_ZAPPED);
367}
368
369/* Kill socket (only if zapped and orphan)
370 * Must be called on unlocked socket.
371 */
372static void sco_sock_kill(struct sock *sk)
373{
374 if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
375 return;
376
377 BT_DBG("sk %p state %d", sk, sk->sk_state);
378
379 /* Kill poor orphan */
380 bt_sock_unlink(&sco_sk_list, sk);
381 sock_set_flag(sk, SOCK_DEAD);
382 sock_put(sk);
383}
384
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200385static void __sco_sock_close(struct sock *sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386{
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200387 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388
389 switch (sk->sk_state) {
390 case BT_LISTEN:
391 sco_sock_cleanup_listen(sk);
392 break;
393
394 case BT_CONNECTED:
395 case BT_CONFIG:
396 case BT_CONNECT:
397 case BT_DISCONN:
398 sco_chan_del(sk, ECONNRESET);
399 break;
400
401 default:
402 sock_set_flag(sk, SOCK_ZAPPED);
403 break;
Stephen Hemminger3ff50b72007-04-20 17:09:22 -0700404 }
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200405}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200407/* Must be called on unlocked socket. */
408static void sco_sock_close(struct sock *sk)
409{
410 sco_sock_clear_timer(sk);
411 lock_sock(sk);
412 __sco_sock_close(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414 sco_sock_kill(sk);
415}
416
417static void sco_sock_init(struct sock *sk, struct sock *parent)
418{
419 BT_DBG("sk %p", sk);
420
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900421 if (parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 sk->sk_type = parent->sk_type;
423}
424
425static struct proto sco_proto = {
426 .name = "SCO",
427 .owner = THIS_MODULE,
428 .obj_size = sizeof(struct sco_pinfo)
429};
430
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700431static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432{
433 struct sock *sk;
434
Pavel Emelyanov6257ff22007-11-01 00:39:31 -0700435 sk = sk_alloc(net, PF_BLUETOOTH, prio, &sco_proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436 if (!sk)
437 return NULL;
438
439 sock_init_data(sock, sk);
440 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
441
442 sk->sk_destruct = sco_sock_destruct;
443 sk->sk_sndtimeo = SCO_CONN_TIMEOUT;
444
445 sock_reset_flag(sk, SOCK_ZAPPED);
446
447 sk->sk_protocol = proto;
448 sk->sk_state = BT_OPEN;
449
Pavel Emelyanovb24b8a22008-01-23 21:20:07 -0800450 setup_timer(&sk->sk_timer, sco_sock_timeout, (unsigned long)sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451
452 bt_sock_link(&sco_sk_list, sk);
453 return sk;
454}
455
Eric Paris3f378b62009-11-05 22:18:14 -0800456static int sco_sock_create(struct net *net, struct socket *sock, int protocol,
457 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458{
459 struct sock *sk;
460
461 BT_DBG("sock %p", sock);
462
463 sock->state = SS_UNCONNECTED;
464
465 if (sock->type != SOCK_SEQPACKET)
466 return -ESOCKTNOSUPPORT;
467
468 sock->ops = &sco_sock_ops;
469
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700470 sk = sco_sock_alloc(net, sock, protocol, GFP_ATOMIC);
Marcel Holtmann74da6262006-10-15 17:31:14 +0200471 if (!sk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 return -ENOMEM;
473
474 sco_sock_init(sk, NULL);
475 return 0;
476}
477
Nick Pellybbcda3b2010-02-11 11:54:28 -0800478static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479{
Nick Pellybbcda3b2010-02-11 11:54:28 -0800480 struct sockaddr_sco sa;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 struct sock *sk = sock->sk;
Nick Pellybbcda3b2010-02-11 11:54:28 -0800482 bdaddr_t *src = &sa.sco_bdaddr;
483 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484
Nick Pellybbcda3b2010-02-11 11:54:28 -0800485 BT_DBG("sk %p %s", sk, batostr(&sa.sco_bdaddr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486
487 if (!addr || addr->sa_family != AF_BLUETOOTH)
488 return -EINVAL;
489
Nick Pellybbcda3b2010-02-11 11:54:28 -0800490 memset(&sa, 0, sizeof(sa));
491 len = min_t(unsigned int, sizeof(sa), alen);
492 memcpy(&sa, addr, len);
493
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 lock_sock(sk);
495
496 if (sk->sk_state != BT_OPEN) {
497 err = -EBADFD;
498 goto done;
499 }
500
501 write_lock_bh(&sco_sk_list.lock);
502
503 if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) {
504 err = -EADDRINUSE;
505 } else {
506 /* Save source address */
Nick Pellybbcda3b2010-02-11 11:54:28 -0800507 bacpy(&bt_sk(sk)->src, &sa.sco_bdaddr);
508 sco_pi(sk)->pkt_type = sa.sco_pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 sk->sk_state = BT_BOUND;
510 }
511
512 write_unlock_bh(&sco_sk_list.lock);
513
514done:
515 release_sock(sk);
516 return err;
517}
518
519static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
520{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 struct sock *sk = sock->sk;
Nick Pellybbcda3b2010-02-11 11:54:28 -0800522 struct sockaddr_sco sa;
523 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524
525 BT_DBG("sk %p", sk);
526
Nick Pellybbcda3b2010-02-11 11:54:28 -0800527 if (!addr || addr->sa_family != AF_BLUETOOTH)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528 return -EINVAL;
529
Nick Pellybbcda3b2010-02-11 11:54:28 -0800530 memset(&sa, 0, sizeof(sa));
531 len = min_t(unsigned int, sizeof(sa), alen);
532 memcpy(&sa, addr, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533
534 lock_sock(sk);
535
Nick Pellybbcda3b2010-02-11 11:54:28 -0800536 if (sk->sk_type != SOCK_SEQPACKET) {
537 err = -EINVAL;
538 goto done;
539 }
540
541 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) {
542 err = -EBADFD;
543 goto done;
544 }
545
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 /* Set destination address and psm */
Nick Pellybbcda3b2010-02-11 11:54:28 -0800547 bacpy(&bt_sk(sk)->dst, &sa.sco_bdaddr);
548 sco_pi(sk)->pkt_type = sa.sco_pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
Kun Han Kim15b911f2011-07-08 09:30:28 -0700550 err = sco_connect(sk, sa.is_wbs);
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200551 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 goto done;
553
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900554 err = bt_sock_wait_state(sk, BT_CONNECTED,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 sock_sndtimeo(sk, flags & O_NONBLOCK));
556
557done:
558 release_sock(sk);
559 return err;
560}
561
562static int sco_sock_listen(struct socket *sock, int backlog)
563{
564 struct sock *sk = sock->sk;
565 int err = 0;
566
567 BT_DBG("sk %p backlog %d", sk, backlog);
568
569 lock_sock(sk);
570
571 if (sk->sk_state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
572 err = -EBADFD;
573 goto done;
574 }
575
576 sk->sk_max_ack_backlog = backlog;
577 sk->sk_ack_backlog = 0;
578 sk->sk_state = BT_LISTEN;
579
580done:
581 release_sock(sk);
582 return err;
583}
584
585static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags)
586{
587 DECLARE_WAITQUEUE(wait, current);
588 struct sock *sk = sock->sk, *ch;
589 long timeo;
590 int err = 0;
591
592 lock_sock(sk);
593
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700594 if (sk->sk_state != BT_LISTEN) {
595 err = -EBADFD;
596 goto done;
597 }
598
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
600
601 BT_DBG("sk %p timeo %ld", sk, timeo);
602
603 /* Wait for an incoming connection. (wake-one). */
Eric Dumazetaa395142010-04-20 13:03:51 +0000604 add_wait_queue_exclusive(sk_sleep(sk), &wait);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700605 while (!(ch = bt_accept_dequeue(sk, newsock))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 set_current_state(TASK_INTERRUPTIBLE);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700607 if (!timeo) {
608 err = -EAGAIN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 break;
610 }
611
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700612 release_sock(sk);
613 timeo = schedule_timeout(timeo);
614 lock_sock(sk);
Peter Hurleyd7581072011-07-24 00:11:01 -0400615
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700616 if (sk->sk_state != BT_LISTEN) {
617 err = -EBADFD;
Peter Hurleyd7581072011-07-24 00:11:01 -0400618 break;
619 }
620
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 if (signal_pending(current)) {
622 err = sock_intr_errno(timeo);
623 break;
624 }
625 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700626 set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +0000627 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628
629 if (err)
630 goto done;
631
632 newsock->state = SS_CONNECTED;
633
634 BT_DBG("new socket %p", ch);
635
636done:
637 release_sock(sk);
638 return err;
639}
640
641static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
642{
643 struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
644 struct sock *sk = sock->sk;
645
646 BT_DBG("sock %p, sk %p", sock, sk);
647
648 addr->sa_family = AF_BLUETOOTH;
649 *len = sizeof(struct sockaddr_sco);
650
651 if (peer)
652 bacpy(&sa->sco_bdaddr, &bt_sk(sk)->dst);
653 else
654 bacpy(&sa->sco_bdaddr, &bt_sk(sk)->src);
Nick Pellybbcda3b2010-02-11 11:54:28 -0800655 sa->sco_pkt_type = sco_pi(sk)->pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656
657 return 0;
658}
659
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900660static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661 struct msghdr *msg, size_t len)
662{
663 struct sock *sk = sock->sk;
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300664 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665
666 BT_DBG("sock %p, sk %p", sock, sk);
667
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -0800668 err = sock_error(sk);
669 if (err)
670 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671
672 if (msg->msg_flags & MSG_OOB)
673 return -EOPNOTSUPP;
674
675 lock_sock(sk);
676
677 if (sk->sk_state == BT_CONNECTED)
678 err = sco_send_frame(sk, msg, len);
679 else
680 err = -ENOTCONN;
681
682 release_sock(sk);
683 return err;
684}
685
David S. Millerb7058842009-09-30 16:12:20 -0700686static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687{
688 struct sock *sk = sock->sk;
689 int err = 0;
690
691 BT_DBG("sk %p", sk);
692
693 lock_sock(sk);
694
695 switch (optname) {
696 default:
697 err = -ENOPROTOOPT;
698 break;
699 }
700
701 release_sock(sk);
702 return err;
703}
704
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100705static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706{
707 struct sock *sk = sock->sk;
708 struct sco_options opts;
709 struct sco_conninfo cinfo;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900710 int len, err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711
712 BT_DBG("sk %p", sk);
713
714 if (get_user(len, optlen))
715 return -EFAULT;
716
717 lock_sock(sk);
718
719 switch (optname) {
720 case SCO_OPTIONS:
721 if (sk->sk_state != BT_CONNECTED) {
722 err = -ENOTCONN;
723 break;
724 }
725
726 opts.mtu = sco_pi(sk)->conn->mtu;
727
728 BT_DBG("mtu %d", opts.mtu);
729
730 len = min_t(unsigned int, len, sizeof(opts));
731 if (copy_to_user(optval, (char *)&opts, len))
732 err = -EFAULT;
733
734 break;
735
736 case SCO_CONNINFO:
737 if (sk->sk_state != BT_CONNECTED) {
738 err = -ENOTCONN;
739 break;
740 }
741
Vasiliy Kulikovc4c896e2011-02-14 13:54:26 +0300742 memset(&cinfo, 0, sizeof(cinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743 cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
744 memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3);
745
746 len = min_t(unsigned int, len, sizeof(cinfo));
747 if (copy_to_user(optval, (char *)&cinfo, len))
748 err = -EFAULT;
749
750 break;
751
752 default:
753 err = -ENOPROTOOPT;
754 break;
755 }
756
757 release_sock(sk);
758 return err;
759}
760
Marcel Holtmannd58daf42009-01-15 21:52:14 +0100761static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
762{
763 struct sock *sk = sock->sk;
764 int len, err = 0;
765
766 BT_DBG("sk %p", sk);
767
768 if (level == SOL_SCO)
769 return sco_sock_getsockopt_old(sock, optname, optval, optlen);
770
771 if (get_user(len, optlen))
772 return -EFAULT;
773
774 lock_sock(sk);
775
776 switch (optname) {
777 default:
778 err = -ENOPROTOOPT;
779 break;
780 }
781
782 release_sock(sk);
783 return err;
784}
785
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +0200786static int sco_sock_shutdown(struct socket *sock, int how)
787{
788 struct sock *sk = sock->sk;
789 int err = 0;
790
791 BT_DBG("sock %p, sk %p", sock, sk);
792
793 if (!sk)
794 return 0;
795
796 lock_sock(sk);
797 if (!sk->sk_shutdown) {
798 sk->sk_shutdown = SHUTDOWN_MASK;
799 sco_sock_clear_timer(sk);
800 __sco_sock_close(sk);
801
802 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
803 err = bt_sock_wait_state(sk, BT_CLOSED,
804 sk->sk_lingertime);
805 }
806 release_sock(sk);
807 return err;
808}
809
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810static int sco_sock_release(struct socket *sock)
811{
812 struct sock *sk = sock->sk;
813 int err = 0;
814
815 BT_DBG("sock %p, sk %p", sock, sk);
816
817 if (!sk)
818 return 0;
819
820 sco_sock_close(sk);
821
822 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) {
823 lock_sock(sk);
824 err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime);
825 release_sock(sk);
826 }
827
828 sock_orphan(sk);
829 sco_sock_kill(sk);
830 return err;
831}
832
833static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
834{
835 BT_DBG("conn %p", conn);
836
837 sco_pi(sk)->conn = conn;
838 conn->sk = sk;
839
840 if (parent)
841 bt_accept_enqueue(parent, sk);
842}
843
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900844/* Delete channel.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 * Must be called on the locked socket. */
846static void sco_chan_del(struct sock *sk, int err)
847{
848 struct sco_conn *conn;
849
850 conn = sco_pi(sk)->conn;
851
852 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
853
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900854 if (conn) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 sco_conn_lock(conn);
856 conn->sk = NULL;
857 sco_pi(sk)->conn = NULL;
858 sco_conn_unlock(conn);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700859 hci_conn_put(conn->hcon);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860 }
861
862 sk->sk_state = BT_CLOSED;
863 sk->sk_err = err;
864 sk->sk_state_change(sk);
865
866 sock_set_flag(sk, SOCK_ZAPPED);
867}
868
869static void sco_conn_ready(struct sco_conn *conn)
870{
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200871 struct sock *parent;
872 struct sock *sk = conn->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873
874 BT_DBG("conn %p", conn);
875
876 sco_conn_lock(conn);
877
Andrei Emeltchenko735cbc42010-12-01 16:58:22 +0200878 if (sk) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879 sco_sock_clear_timer(sk);
880 bh_lock_sock(sk);
881 sk->sk_state = BT_CONNECTED;
882 sk->sk_state_change(sk);
883 bh_unlock_sock(sk);
884 } else {
885 parent = sco_get_sock_listen(conn->src);
886 if (!parent)
887 goto done;
888
889 bh_lock_sock(parent);
890
Gustavo F. Padovanb9dbdbc2010-05-01 16:15:35 -0300891 sk = sco_sock_alloc(sock_net(parent), NULL,
892 BTPROTO_SCO, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 if (!sk) {
894 bh_unlock_sock(parent);
895 goto done;
896 }
897
898 sco_sock_init(sk, parent);
899
900 bacpy(&bt_sk(sk)->src, conn->src);
901 bacpy(&bt_sk(sk)->dst, conn->dst);
902
903 hci_conn_hold(conn->hcon);
904 __sco_chan_add(conn, sk, parent);
905
906 sk->sk_state = BT_CONNECTED;
907
908 /* Wake up parent */
909 parent->sk_data_ready(parent, 1);
910
911 bh_unlock_sock(parent);
912 }
913
914done:
915 sco_conn_unlock(conn);
916}
917
918/* ----- SCO interface with lower layer (HCI) ----- */
919static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
920{
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +0100921 register struct sock *sk;
922 struct hlist_node *node;
923 int lm = 0;
924
925 if (type != SCO_LINK && type != ESCO_LINK)
Mat Martineau8b51dd42012-02-13 10:38:24 -0800926 return 0;
Marcel Holtmann71aeeaa2009-01-15 21:57:02 +0100927
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
929
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) ||
937 !bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
938 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
947static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
948{
949 BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
950
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200951 if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
Gustavo F. Padovanc89ad732010-11-01 19:08:50 +0000952 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953
954 if (!status) {
955 struct sco_conn *conn;
956
957 conn = sco_conn_add(hcon, status);
958 if (conn)
959 sco_conn_ready(conn);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900960 } else
Mat Martineau3b9239a2012-02-16 11:54:30 -0800961 sco_conn_del(hcon, bt_err(status), 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962
963 return 0;
964}
965
Mat Martineau3b9239a2012-02-16 11:54:30 -0800966static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason, __u8 is_process)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967{
968 BT_DBG("hcon %p reason %d", hcon, reason);
969
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200970 if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
Gustavo F. Padovanc89ad732010-11-01 19:08:50 +0000971 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972
Mat Martineau3b9239a2012-02-16 11:54:30 -0800973 sco_conn_del(hcon, bt_err(reason), is_process);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200974
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 return 0;
976}
977
978static int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
979{
980 struct sco_conn *conn = hcon->sco_data;
981
982 if (!conn)
983 goto drop;
984
985 BT_DBG("conn %p len %d", conn, skb->len);
986
987 if (skb->len) {
988 sco_recv_frame(conn, skb);
989 return 0;
990 }
991
992drop:
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900993 kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994 return 0;
995}
996
Marcel Holtmannaef7d972010-03-21 05:27:45 +0100997static int sco_debugfs_show(struct seq_file *f, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998{
999 struct sock *sk;
1000 struct hlist_node *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001
1002 read_lock_bh(&sco_sk_list.lock);
1003
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08001004 sk_for_each(sk, node, &sco_sk_list.head) {
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001005 seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src),
1006 batostr(&bt_sk(sk)->dst), sk->sk_state);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08001007 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009 read_unlock_bh(&sco_sk_list.lock);
Marcel Holtmannbe9d1222005-11-08 09:57:38 -08001010
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001011 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012}
1013
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001014static int sco_debugfs_open(struct inode *inode, struct file *file)
1015{
1016 return single_open(file, sco_debugfs_show, inode->i_private);
1017}
1018
1019static const struct file_operations sco_debugfs_fops = {
1020 .open = sco_debugfs_open,
1021 .read = seq_read,
1022 .llseek = seq_lseek,
1023 .release = single_release,
1024};
1025
1026static struct dentry *sco_debugfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027
Eric Dumazet90ddc4f2005-12-22 12:49:22 -08001028static const struct proto_ops sco_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 .family = PF_BLUETOOTH,
1030 .owner = THIS_MODULE,
1031 .release = sco_sock_release,
1032 .bind = sco_sock_bind,
1033 .connect = sco_sock_connect,
1034 .listen = sco_sock_listen,
1035 .accept = sco_sock_accept,
1036 .getname = sco_sock_getname,
1037 .sendmsg = sco_sock_sendmsg,
1038 .recvmsg = bt_sock_recvmsg,
1039 .poll = bt_sock_poll,
Marcel Holtmann3241ad82008-07-14 20:13:50 +02001040 .ioctl = bt_sock_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 .mmap = sock_no_mmap,
1042 .socketpair = sock_no_socketpair,
Marcel Holtmannfd0b3ff2009-06-16 00:01:49 +02001043 .shutdown = sco_sock_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 .setsockopt = sco_sock_setsockopt,
1045 .getsockopt = sco_sock_getsockopt
1046};
1047
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +00001048static const struct net_proto_family sco_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 .family = PF_BLUETOOTH,
1050 .owner = THIS_MODULE,
1051 .create = sco_sock_create,
1052};
1053
1054static struct hci_proto sco_hci_proto = {
1055 .name = "SCO",
1056 .id = HCI_PROTO_SCO,
1057 .connect_ind = sco_connect_ind,
1058 .connect_cfm = sco_connect_cfm,
Marcel Holtmann2950f212009-02-12 14:02:50 +01001059 .disconn_cfm = sco_disconn_cfm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 .recv_scodata = sco_recv_scodata
1061};
1062
Gustavo F. Padovan64274512011-02-07 20:08:52 -02001063int __init sco_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064{
1065 int err;
1066
1067 err = proto_register(&sco_proto, 0);
1068 if (err < 0)
1069 return err;
1070
1071 err = bt_sock_register(BTPROTO_SCO, &sco_sock_family_ops);
1072 if (err < 0) {
1073 BT_ERR("SCO socket registration failed");
1074 goto error;
1075 }
1076
1077 err = hci_register_proto(&sco_hci_proto);
1078 if (err < 0) {
1079 BT_ERR("SCO protocol registration failed");
1080 bt_sock_unregister(BTPROTO_SCO);
1081 goto error;
1082 }
1083
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001084 if (bt_debugfs) {
1085 sco_debugfs = debugfs_create_file("sco", 0444,
1086 bt_debugfs, NULL, &sco_debugfs_fops);
1087 if (!sco_debugfs)
1088 BT_ERR("Failed to create SCO debug file");
1089 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 BT_INFO("SCO socket layer initialized");
1092
1093 return 0;
1094
1095error:
1096 proto_unregister(&sco_proto);
1097 return err;
1098}
1099
Gustavo F. Padovan64274512011-02-07 20:08:52 -02001100void __exit sco_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101{
Marcel Holtmannaef7d972010-03-21 05:27:45 +01001102 debugfs_remove(sco_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103
1104 if (bt_sock_unregister(BTPROTO_SCO) < 0)
1105 BT_ERR("SCO socket unregistration failed");
1106
1107 if (hci_unregister_proto(&sco_hci_proto) < 0)
1108 BT_ERR("SCO protocol unregistration failed");
1109
1110 proto_unregister(&sco_proto);
1111}
1112
Marcel Holtmann7cb127d2008-07-14 20:13:53 +02001113module_param(disable_esco, bool, 0644);
1114MODULE_PARM_DESC(disable_esco, "Disable eSCO connection creation");