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