Linux 3.10.54
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / bluetooth / af_bluetooth.c
CommitLineData
8e87d142 1/*
1da177e4
LT
2 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
8e87d142
YH
15 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
1da177e4
LT
18 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
8e87d142
YH
20 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
1da177e4
LT
22 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth address family and sockets. */
26
1da177e4 27#include <linux/module.h>
3241ad82 28#include <asm/ioctls.h>
1da177e4
LT
29
30#include <net/bluetooth/bluetooth.h>
256a06c8 31#include <linux/proc_fs.h>
1da177e4 32
64274518 33#define VERSION "2.16"
1da177e4
LT
34
35/* Bluetooth sockets */
36#define BT_MAX_PROTO 8
ec1b4cf7 37static const struct net_proto_family *bt_proto[BT_MAX_PROTO];
db7aa1c2 38static DEFINE_RWLOCK(bt_proto_lock);
68845cb2 39
68845cb2 40static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
36cbd3dc 41static const char *const bt_key_strings[BT_MAX_PROTO] = {
68845cb2
DY
42 "sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP",
43 "sk_lock-AF_BLUETOOTH-BTPROTO_HCI",
44 "sk_lock-AF_BLUETOOTH-BTPROTO_SCO",
45 "sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM",
46 "sk_lock-AF_BLUETOOTH-BTPROTO_BNEP",
47 "sk_lock-AF_BLUETOOTH-BTPROTO_CMTP",
48 "sk_lock-AF_BLUETOOTH-BTPROTO_HIDP",
49 "sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP",
50};
51
db7aa1c2 52static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
36cbd3dc 53static const char *const bt_slock_key_strings[BT_MAX_PROTO] = {
68845cb2
DY
54 "slock-AF_BLUETOOTH-BTPROTO_L2CAP",
55 "slock-AF_BLUETOOTH-BTPROTO_HCI",
56 "slock-AF_BLUETOOTH-BTPROTO_SCO",
57 "slock-AF_BLUETOOTH-BTPROTO_RFCOMM",
58 "slock-AF_BLUETOOTH-BTPROTO_BNEP",
59 "slock-AF_BLUETOOTH-BTPROTO_CMTP",
60 "slock-AF_BLUETOOTH-BTPROTO_HIDP",
61 "slock-AF_BLUETOOTH-BTPROTO_AVDTP",
62};
db7aa1c2 63
b5a30dda 64void bt_sock_reclassify_lock(struct sock *sk, int proto)
db7aa1c2 65{
b5a30dda 66 BUG_ON(!sk);
db7aa1c2
MH
67 BUG_ON(sock_owned_by_user(sk));
68
69 sock_lock_init_class_and_name(sk,
70 bt_slock_key_strings[proto], &bt_slock_key[proto],
71 bt_key_strings[proto], &bt_lock_key[proto]);
72}
b5a30dda 73EXPORT_SYMBOL(bt_sock_reclassify_lock);
1da177e4 74
ec1b4cf7 75int bt_sock_register(int proto, const struct net_proto_family *ops)
1da177e4 76{
74da626a
MH
77 int err = 0;
78
1da177e4
LT
79 if (proto < 0 || proto >= BT_MAX_PROTO)
80 return -EINVAL;
81
74da626a
MH
82 write_lock(&bt_proto_lock);
83
1da177e4 84 if (bt_proto[proto])
74da626a
MH
85 err = -EEXIST;
86 else
87 bt_proto[proto] = ops;
88
89 write_unlock(&bt_proto_lock);
1da177e4 90
74da626a 91 return err;
1da177e4
LT
92}
93EXPORT_SYMBOL(bt_sock_register);
94
be9f97f0 95void bt_sock_unregister(int proto)
1da177e4
LT
96{
97 if (proto < 0 || proto >= BT_MAX_PROTO)
be9f97f0 98 return;
1da177e4 99
74da626a 100 write_lock(&bt_proto_lock);
be9f97f0 101 bt_proto[proto] = NULL;
74da626a 102 write_unlock(&bt_proto_lock);
1da177e4
LT
103}
104EXPORT_SYMBOL(bt_sock_unregister);
105
3f378b68
EP
106static int bt_sock_create(struct net *net, struct socket *sock, int proto,
107 int kern)
1da177e4 108{
74da626a 109 int err;
1da177e4 110
1b8d7ae4
EB
111 if (net != &init_net)
112 return -EAFNOSUPPORT;
113
1da177e4
LT
114 if (proto < 0 || proto >= BT_MAX_PROTO)
115 return -EINVAL;
116
95a5afca 117 if (!bt_proto[proto])
1da177e4 118 request_module("bt-proto-%d", proto);
74da626a 119
1da177e4 120 err = -EPROTONOSUPPORT;
74da626a
MH
121
122 read_lock(&bt_proto_lock);
123
1da177e4 124 if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
3f378b68 125 err = bt_proto[proto]->create(net, sock, proto, kern);
b5a30dda
OP
126 if (!err)
127 bt_sock_reclassify_lock(sock->sk, proto);
1da177e4
LT
128 module_put(bt_proto[proto]->owner);
129 }
74da626a
MH
130
131 read_unlock(&bt_proto_lock);
132
8e87d142 133 return err;
1da177e4
LT
134}
135
136void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
137{
94f5bfb8 138 write_lock(&l->lock);
1da177e4 139 sk_add_node(sk, &l->head);
94f5bfb8 140 write_unlock(&l->lock);
1da177e4
LT
141}
142EXPORT_SYMBOL(bt_sock_link);
143
144void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
145{
94f5bfb8 146 write_lock(&l->lock);
1da177e4 147 sk_del_node_init(sk);
94f5bfb8 148 write_unlock(&l->lock);
1da177e4
LT
149}
150EXPORT_SYMBOL(bt_sock_unlink);
151
152void bt_accept_enqueue(struct sock *parent, struct sock *sk)
153{
154 BT_DBG("parent %p, sk %p", parent, sk);
155
156 sock_hold(sk);
157 list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
158 bt_sk(sk)->parent = parent;
159 parent->sk_ack_backlog++;
160}
161EXPORT_SYMBOL(bt_accept_enqueue);
162
163void bt_accept_unlink(struct sock *sk)
164{
165 BT_DBG("sk %p state %d", sk, sk->sk_state);
166
167 list_del_init(&bt_sk(sk)->accept_q);
168 bt_sk(sk)->parent->sk_ack_backlog--;
169 bt_sk(sk)->parent = NULL;
170 sock_put(sk);
171}
172EXPORT_SYMBOL(bt_accept_unlink);
173
174struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
175{
176 struct list_head *p, *n;
177 struct sock *sk;
178
179 BT_DBG("parent %p", parent);
180
181 list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
182 sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
183
8a154a8f 184 lock_sock(sk);
1da177e4
LT
185
186 /* FIXME: Is this check still needed */
187 if (sk->sk_state == BT_CLOSED) {
8a154a8f 188 release_sock(sk);
1da177e4
LT
189 bt_accept_unlink(sk);
190 continue;
191 }
192
c4f912e1 193 if (sk->sk_state == BT_CONNECTED || !newsock ||
d060991f 194 test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags)) {
1da177e4
LT
195 bt_accept_unlink(sk);
196 if (newsock)
197 sock_graft(sk, newsock);
d37f50e1 198
8a154a8f 199 release_sock(sk);
1da177e4
LT
200 return sk;
201 }
202
8a154a8f 203 release_sock(sk);
1da177e4 204 }
d37f50e1 205
1da177e4
LT
206 return NULL;
207}
208EXPORT_SYMBOL(bt_accept_dequeue);
209
210int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
c4f912e1 211 struct msghdr *msg, size_t len, int flags)
1da177e4
LT
212{
213 int noblock = flags & MSG_DONTWAIT;
214 struct sock *sk = sock->sk;
215 struct sk_buff *skb;
216 size_t copied;
217 int err;
218
a418b893 219 BT_DBG("sock %p sk %p len %zu", sock, sk, len);
1da177e4
LT
220
221 if (flags & (MSG_OOB))
222 return -EOPNOTSUPP;
223
5a08ecce
AE
224 skb = skb_recv_datagram(sk, flags, noblock, &err);
225 if (!skb) {
1da177e4
LT
226 if (sk->sk_shutdown & RCV_SHUTDOWN)
227 return 0;
228 return err;
229 }
230
1da177e4
LT
231 copied = skb->len;
232 if (len < copied) {
233 msg->msg_flags |= MSG_TRUNC;
234 copied = len;
235 }
236
badff6d0 237 skb_reset_transport_header(skb);
1da177e4 238 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
3241ad82 239 if (err == 0)
3b885787 240 sock_recv_ts_and_drops(msg, sk, skb);
1da177e4
LT
241
242 skb_free_datagram(sk, skb);
243
244 return err ? : copied;
245}
246EXPORT_SYMBOL(bt_sock_recvmsg);
247
796c86ee
MM
248static long bt_sock_data_wait(struct sock *sk, long timeo)
249{
250 DECLARE_WAITQUEUE(wait, current);
251
252 add_wait_queue(sk_sleep(sk), &wait);
253 for (;;) {
254 set_current_state(TASK_INTERRUPTIBLE);
255
256 if (!skb_queue_empty(&sk->sk_receive_queue))
257 break;
258
259 if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN))
260 break;
261
262 if (signal_pending(current) || !timeo)
263 break;
264
265 set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
266 release_sock(sk);
267 timeo = schedule_timeout(timeo);
268 lock_sock(sk);
269 clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
270 }
271
272 __set_current_state(TASK_RUNNING);
273 remove_wait_queue(sk_sleep(sk), &wait);
274 return timeo;
275}
276
277int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
278 struct msghdr *msg, size_t size, int flags)
279{
280 struct sock *sk = sock->sk;
281 int err = 0;
282 size_t target, copied = 0;
283 long timeo;
284
285 if (flags & MSG_OOB)
286 return -EOPNOTSUPP;
287
796c86ee
MM
288 BT_DBG("sk %p size %zu", sk, size);
289
290 lock_sock(sk);
291
292 target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
293 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
294
295 do {
296 struct sk_buff *skb;
297 int chunk;
298
299 skb = skb_dequeue(&sk->sk_receive_queue);
300 if (!skb) {
301 if (copied >= target)
302 break;
303
5a08ecce
AE
304 err = sock_error(sk);
305 if (err)
796c86ee
MM
306 break;
307 if (sk->sk_shutdown & RCV_SHUTDOWN)
308 break;
309
310 err = -EAGAIN;
311 if (!timeo)
312 break;
313
314 timeo = bt_sock_data_wait(sk, timeo);
315
316 if (signal_pending(current)) {
317 err = sock_intr_errno(timeo);
318 goto out;
319 }
320 continue;
321 }
322
323 chunk = min_t(unsigned int, skb->len, size);
5b668eb3 324 if (skb_copy_datagram_iovec(skb, 0, msg->msg_iov, chunk)) {
796c86ee
MM
325 skb_queue_head(&sk->sk_receive_queue, skb);
326 if (!copied)
327 copied = -EFAULT;
328 break;
329 }
330 copied += chunk;
331 size -= chunk;
332
333 sock_recv_ts_and_drops(msg, sk, skb);
334
335 if (!(flags & MSG_PEEK)) {
5b668eb3
MM
336 int skb_len = skb_headlen(skb);
337
338 if (chunk <= skb_len) {
339 __skb_pull(skb, chunk);
340 } else {
341 struct sk_buff *frag;
342
343 __skb_pull(skb, skb_len);
344 chunk -= skb_len;
345
346 skb_walk_frags(skb, frag) {
347 if (chunk <= frag->len) {
348 /* Pulling partial data */
349 skb->len -= chunk;
350 skb->data_len -= chunk;
351 __skb_pull(frag, chunk);
352 break;
353 } else if (frag->len) {
354 /* Pulling all frag data */
355 chunk -= frag->len;
356 skb->len -= frag->len;
357 skb->data_len -= frag->len;
358 __skb_pull(frag, frag->len);
359 }
360 }
361 }
362
796c86ee
MM
363 if (skb->len) {
364 skb_queue_head(&sk->sk_receive_queue, skb);
365 break;
366 }
367 kfree_skb(skb);
368
369 } else {
370 /* put message back and return */
371 skb_queue_head(&sk->sk_receive_queue, skb);
372 break;
373 }
374 } while (size);
375
376out:
377 release_sock(sk);
378 return copied ? : err;
379}
380EXPORT_SYMBOL(bt_sock_stream_recvmsg);
381
1da177e4
LT
382static inline unsigned int bt_accept_poll(struct sock *parent)
383{
384 struct list_head *p, *n;
385 struct sock *sk;
386
387 list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
388 sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
d5f2d2be 389 if (sk->sk_state == BT_CONNECTED ||
c5daa683
GP
390 (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags) &&
391 sk->sk_state == BT_CONNECT2))
1da177e4
LT
392 return POLLIN | POLLRDNORM;
393 }
394
395 return 0;
396}
397
8fc9ced3
GP
398unsigned int bt_sock_poll(struct file *file, struct socket *sock,
399 poll_table *wait)
1da177e4
LT
400{
401 struct sock *sk = sock->sk;
402 unsigned int mask = 0;
403
404 BT_DBG("sock %p, sk %p", sock, sk);
405
aa395145 406 poll_wait(file, sk_sleep(sk), wait);
1da177e4
LT
407
408 if (sk->sk_state == BT_LISTEN)
409 return bt_accept_poll(sk);
410
411 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
7d4c04fc 412 mask |= POLLERR |
8facd5fb 413 (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0);
1da177e4 414
f348d70a 415 if (sk->sk_shutdown & RCV_SHUTDOWN)
db40980f 416 mask |= POLLRDHUP | POLLIN | POLLRDNORM;
f348d70a 417
1da177e4
LT
418 if (sk->sk_shutdown == SHUTDOWN_MASK)
419 mask |= POLLHUP;
420
db40980f 421 if (!skb_queue_empty(&sk->sk_receive_queue))
1da177e4
LT
422 mask |= POLLIN | POLLRDNORM;
423
424 if (sk->sk_state == BT_CLOSED)
425 mask |= POLLHUP;
426
427 if (sk->sk_state == BT_CONNECT ||
428 sk->sk_state == BT_CONNECT2 ||
429 sk->sk_state == BT_CONFIG)
430 return mask;
431
c5daa683 432 if (!test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags) && sock_writeable(sk))
1da177e4
LT
433 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
434 else
435 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
436
437 return mask;
438}
439EXPORT_SYMBOL(bt_sock_poll);
440
3241ad82
MH
441int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
442{
443 struct sock *sk = sock->sk;
43cbeee9
MH
444 struct sk_buff *skb;
445 long amount;
3241ad82
MH
446 int err;
447
448 BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);
449
450 switch (cmd) {
43cbeee9
MH
451 case TIOCOUTQ:
452 if (sk->sk_state == BT_LISTEN)
453 return -EINVAL;
454
31e6d363 455 amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
43cbeee9
MH
456 if (amount < 0)
457 amount = 0;
458 err = put_user(amount, (int __user *) arg);
459 break;
460
461 case TIOCINQ:
462 if (sk->sk_state == BT_LISTEN)
463 return -EINVAL;
464
465 lock_sock(sk);
466 skb = skb_peek(&sk->sk_receive_queue);
467 amount = skb ? skb->len : 0;
468 release_sock(sk);
469 err = put_user(amount, (int __user *) arg);
470 break;
471
3241ad82
MH
472 case SIOCGSTAMP:
473 err = sock_get_timestamp(sk, (struct timeval __user *) arg);
474 break;
475
476 case SIOCGSTAMPNS:
477 err = sock_get_timestampns(sk, (struct timespec __user *) arg);
478 break;
479
480 default:
481 err = -ENOIOCTLCMD;
482 break;
483 }
484
485 return err;
486}
487EXPORT_SYMBOL(bt_sock_ioctl);
488
1da177e4
LT
489int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
490{
491 DECLARE_WAITQUEUE(wait, current);
492 int err = 0;
493
494 BT_DBG("sk %p", sk);
495
aa395145 496 add_wait_queue(sk_sleep(sk), &wait);
9be4e3fb 497 set_current_state(TASK_INTERRUPTIBLE);
1da177e4 498 while (sk->sk_state != state) {
1da177e4 499 if (!timeo) {
b4c612a4 500 err = -EINPROGRESS;
1da177e4
LT
501 break;
502 }
503
504 if (signal_pending(current)) {
505 err = sock_intr_errno(timeo);
506 break;
507 }
508
509 release_sock(sk);
510 timeo = schedule_timeout(timeo);
511 lock_sock(sk);
9be4e3fb 512 set_current_state(TASK_INTERRUPTIBLE);
1da177e4 513
c1cbe4b7
BL
514 err = sock_error(sk);
515 if (err)
1da177e4 516 break;
1da177e4 517 }
9be4e3fb 518 __set_current_state(TASK_RUNNING);
aa395145 519 remove_wait_queue(sk_sleep(sk), &wait);
1da177e4
LT
520 return err;
521}
522EXPORT_SYMBOL(bt_sock_wait_state);
523
256a06c8
MY
524#ifdef CONFIG_PROC_FS
525struct bt_seq_state {
526 struct bt_sock_list *l;
527};
528
529static void *bt_seq_start(struct seq_file *seq, loff_t *pos)
530 __acquires(seq->private->l->lock)
531{
532 struct bt_seq_state *s = seq->private;
533 struct bt_sock_list *l = s->l;
534
535 read_lock(&l->lock);
536 return seq_hlist_start_head(&l->head, *pos);
537}
538
539static void *bt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
540{
541 struct bt_seq_state *s = seq->private;
542 struct bt_sock_list *l = s->l;
543
544 return seq_hlist_next(v, &l->head, pos);
545}
546
547static void bt_seq_stop(struct seq_file *seq, void *v)
548 __releases(seq->private->l->lock)
549{
550 struct bt_seq_state *s = seq->private;
551 struct bt_sock_list *l = s->l;
552
553 read_unlock(&l->lock);
554}
555
556static int bt_seq_show(struct seq_file *seq, void *v)
557{
256a06c8
MY
558 struct bt_seq_state *s = seq->private;
559 struct bt_sock_list *l = s->l;
256a06c8
MY
560
561 if (v == SEQ_START_TOKEN) {
562 seq_puts(seq ,"sk RefCnt Rmem Wmem User Inode Src Dst Parent");
563
564 if (l->custom_seq_show) {
565 seq_putc(seq, ' ');
566 l->custom_seq_show(seq, v);
567 }
568
569 seq_putc(seq, '\n');
570 } else {
09d5d4aa
AE
571 struct sock *sk = sk_entry(v);
572 struct bt_sock *bt = bt_sk(sk);
256a06c8 573
7028a886
AE
574 seq_printf(seq,
575 "%pK %-6d %-6u %-6u %-6u %-6lu %pMR %pMR %-6lu",
256a06c8
MY
576 sk,
577 atomic_read(&sk->sk_refcnt),
578 sk_rmem_alloc_get(sk),
579 sk_wmem_alloc_get(sk),
1bbb3095 580 from_kuid(seq_user_ns(seq), sock_i_uid(sk)),
256a06c8 581 sock_i_ino(sk),
7028a886
AE
582 &bt->src,
583 &bt->dst,
256a06c8
MY
584 bt->parent? sock_i_ino(bt->parent): 0LU);
585
586 if (l->custom_seq_show) {
587 seq_putc(seq, ' ');
588 l->custom_seq_show(seq, v);
589 }
590
591 seq_putc(seq, '\n');
592 }
593 return 0;
594}
595
596static struct seq_operations bt_seq_ops = {
597 .start = bt_seq_start,
598 .next = bt_seq_next,
599 .stop = bt_seq_stop,
600 .show = bt_seq_show,
601};
602
603static int bt_seq_open(struct inode *inode, struct file *file)
604{
605 struct bt_sock_list *sk_list;
606 struct bt_seq_state *s;
607
d9dda78b 608 sk_list = PDE_DATA(inode);
256a06c8
MY
609 s = __seq_open_private(file, &bt_seq_ops,
610 sizeof(struct bt_seq_state));
31f47073 611 if (!s)
256a06c8
MY
612 return -ENOMEM;
613
614 s->l = sk_list;
615 return 0;
616}
617
14805359
AV
618static const struct file_operations bt_fops = {
619 .open = bt_seq_open,
620 .read = seq_read,
621 .llseek = seq_lseek,
622 .release = seq_release_private
623};
624
b0316615 625int bt_procfs_init(struct net *net, const char *name,
256a06c8
MY
626 struct bt_sock_list* sk_list,
627 int (* seq_show)(struct seq_file *, void *))
628{
256a06c8
MY
629 sk_list->custom_seq_show = seq_show;
630
4d006263 631 if (!proc_create_data(name, 0, net->proc_net, &bt_fops, sk_list))
256a06c8 632 return -ENOMEM;
256a06c8
MY
633 return 0;
634}
635
636void bt_procfs_cleanup(struct net *net, const char *name)
637{
ece31ffd 638 remove_proc_entry(name, net->proc_net);
256a06c8
MY
639}
640#else
b0316615 641int bt_procfs_init(struct net *net, const char *name,
256a06c8
MY
642 struct bt_sock_list* sk_list,
643 int (* seq_show)(struct seq_file *, void *))
644{
645 return 0;
646}
647
648void bt_procfs_cleanup(struct net *net, const char *name)
649{
650}
651#endif
652EXPORT_SYMBOL(bt_procfs_init);
653EXPORT_SYMBOL(bt_procfs_cleanup);
654
1da177e4
LT
655static struct net_proto_family bt_sock_family_ops = {
656 .owner = THIS_MODULE,
657 .family = PF_BLUETOOTH,
658 .create = bt_sock_create,
659};
660
1da177e4
LT
661static int __init bt_init(void)
662{
27d35284
MH
663 int err;
664
1da177e4
LT
665 BT_INFO("Core ver %s", VERSION);
666
27d35284
MH
667 err = bt_sysfs_init();
668 if (err < 0)
669 return err;
1da177e4 670
27d35284
MH
671 err = sock_register(&bt_sock_family_ops);
672 if (err < 0) {
673 bt_sysfs_cleanup();
674 return err;
675 }
1da177e4 676
27d35284 677 BT_INFO("HCI device and connection manager initialized");
1da177e4 678
64274518
GP
679 err = hci_sock_init();
680 if (err < 0)
681 goto error;
682
683 err = l2cap_init();
0ed54dad 684 if (err < 0)
64274518 685 goto sock_err;
64274518
GP
686
687 err = sco_init();
688 if (err < 0) {
689 l2cap_exit();
690 goto sock_err;
691 }
1da177e4
LT
692
693 return 0;
64274518
GP
694
695sock_err:
696 hci_sock_cleanup();
697
698error:
699 sock_unregister(PF_BLUETOOTH);
700 bt_sysfs_cleanup();
701
702 return err;
1da177e4
LT
703}
704
705static void __exit bt_exit(void)
706{
64274518
GP
707
708 sco_exit();
709
710 l2cap_exit();
711
1da177e4
LT
712 hci_sock_cleanup();
713
1da177e4 714 sock_unregister(PF_BLUETOOTH);
27d35284
MH
715
716 bt_sysfs_cleanup();
1da177e4
LT
717}
718
719subsys_initcall(bt_init);
720module_exit(bt_exit);
721
63fbd24e 722MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
1da177e4
LT
723MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
724MODULE_VERSION(VERSION);
725MODULE_LICENSE("GPL");
726MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);