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