blob: 1a35d343e08a593f91cc71fce52306a50d991c4b [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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
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
18 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
22 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080030#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#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/skbuff.h>
39#include <linux/workqueue.h>
40#include <linux/interrupt.h>
41#include <linux/socket.h>
42#include <linux/ioctl.h>
43#include <net/sock.h>
44
45#include <asm/system.h>
46#include <asm/uaccess.h>
47#include <asm/unaligned.h>
48
49#include <net/bluetooth/bluetooth.h>
50#include <net/bluetooth/hci_core.h>
51
52#ifndef CONFIG_BT_HCI_SOCK_DEBUG
53#undef BT_DBG
54#define BT_DBG(D...)
55#endif
56
57/* ----- HCI socket interface ----- */
58
59static inline int hci_test_bit(int nr, void *addr)
60{
61 return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
62}
63
64/* Security filter */
65static struct hci_sec_filter hci_sec_filter = {
66 /* Packet types */
67 0x10,
68 /* Events */
Marcel Holtmanndd7f5522005-10-28 19:20:53 +020069 { 0x1000d9fe, 0x0000b00c },
Linus Torvalds1da177e2005-04-16 15:20:36 -070070 /* Commands */
71 {
72 { 0x0 },
73 /* OGF_LINK_CTL */
Marcel Holtmanndd7f5522005-10-28 19:20:53 +020074 { 0xbe000006, 0x00000001, 0x000000, 0x00 },
Linus Torvalds1da177e2005-04-16 15:20:36 -070075 /* OGF_LINK_POLICY */
Marcel Holtmanndd7f5522005-10-28 19:20:53 +020076 { 0x00005200, 0x00000000, 0x000000, 0x00 },
Linus Torvalds1da177e2005-04-16 15:20:36 -070077 /* OGF_HOST_CTL */
Marcel Holtmanndd7f5522005-10-28 19:20:53 +020078 { 0xaab00200, 0x2b402aaa, 0x020154, 0x00 },
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 /* OGF_INFO_PARAM */
Marcel Holtmanndd7f5522005-10-28 19:20:53 +020080 { 0x000002be, 0x00000000, 0x000000, 0x00 },
Linus Torvalds1da177e2005-04-16 15:20:36 -070081 /* OGF_STATUS_PARAM */
Marcel Holtmanndd7f5522005-10-28 19:20:53 +020082 { 0x000000ea, 0x00000000, 0x000000, 0x00 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070083 }
84};
85
86static struct bt_sock_list hci_sk_list = {
87 .lock = RW_LOCK_UNLOCKED
88};
89
90/* Send frame to RAW socket */
91void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
92{
93 struct sock *sk;
94 struct hlist_node *node;
95
96 BT_DBG("hdev %p len %d", hdev, skb->len);
97
98 read_lock(&hci_sk_list.lock);
99 sk_for_each(sk, node, &hci_sk_list.head) {
100 struct hci_filter *flt;
101 struct sk_buff *nskb;
102
103 if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev)
104 continue;
105
106 /* Don't send frame to the socket it came from */
107 if (skb->sk == sk)
108 continue;
109
110 /* Apply filter */
111 flt = &hci_pi(sk)->filter;
112
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700113 if (!test_bit((bt_cb(skb)->pkt_type == HCI_VENDOR_PKT) ?
114 0 : (bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS), &flt->type_mask))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115 continue;
116
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700117 if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
119
120 if (!hci_test_bit(evt, &flt->event_mask))
121 continue;
122
123 if (flt->opcode && ((evt == HCI_EV_CMD_COMPLETE &&
124 flt->opcode != *(__u16 *)(skb->data + 3)) ||
125 (evt == HCI_EV_CMD_STATUS &&
126 flt->opcode != *(__u16 *)(skb->data + 4))))
127 continue;
128 }
129
130 if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
131 continue;
132
133 /* Put type byte before the data */
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700134 memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
136 if (sock_queue_rcv_skb(sk, nskb))
137 kfree_skb(nskb);
138 }
139 read_unlock(&hci_sk_list.lock);
140}
141
142static int hci_sock_release(struct socket *sock)
143{
144 struct sock *sk = sock->sk;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100145 struct hci_dev *hdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146
147 BT_DBG("sock %p sk %p", sock, sk);
148
149 if (!sk)
150 return 0;
151
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100152 hdev = hci_pi(sk)->hdev;
153
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154 bt_sock_unlink(&hci_sk_list, sk);
155
156 if (hdev) {
157 atomic_dec(&hdev->promisc);
158 hci_dev_put(hdev);
159 }
160
161 sock_orphan(sk);
162
163 skb_queue_purge(&sk->sk_receive_queue);
164 skb_queue_purge(&sk->sk_write_queue);
165
166 sock_put(sk);
167 return 0;
168}
169
170/* Ioctls that require bound socket */
171static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
172{
173 struct hci_dev *hdev = hci_pi(sk)->hdev;
174
175 if (!hdev)
176 return -EBADFD;
177
178 switch (cmd) {
179 case HCISETRAW:
180 if (!capable(CAP_NET_ADMIN))
181 return -EACCES;
182
183 if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
184 return -EPERM;
185
186 if (arg)
187 set_bit(HCI_RAW, &hdev->flags);
188 else
189 clear_bit(HCI_RAW, &hdev->flags);
190
191 return 0;
192
193 case HCISETSECMGR:
194 if (!capable(CAP_NET_ADMIN))
195 return -EACCES;
196
197 if (arg)
198 set_bit(HCI_SECMGR, &hdev->flags);
199 else
200 clear_bit(HCI_SECMGR, &hdev->flags);
201
202 return 0;
203
204 case HCIGETCONNINFO:
205 return hci_get_conn_info(hdev, (void __user *)arg);
206
207 default:
208 if (hdev->ioctl)
209 return hdev->ioctl(hdev, cmd, arg);
210 return -EINVAL;
211 }
212}
213
214static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
215{
216 struct sock *sk = sock->sk;
217 void __user *argp = (void __user *)arg;
218 int err;
219
220 BT_DBG("cmd %x arg %lx", cmd, arg);
221
222 switch (cmd) {
223 case HCIGETDEVLIST:
224 return hci_get_dev_list(argp);
225
226 case HCIGETDEVINFO:
227 return hci_get_dev_info(argp);
228
229 case HCIGETCONNLIST:
230 return hci_get_conn_list(argp);
231
232 case HCIDEVUP:
233 if (!capable(CAP_NET_ADMIN))
234 return -EACCES;
235 return hci_dev_open(arg);
236
237 case HCIDEVDOWN:
238 if (!capable(CAP_NET_ADMIN))
239 return -EACCES;
240 return hci_dev_close(arg);
241
242 case HCIDEVRESET:
243 if (!capable(CAP_NET_ADMIN))
244 return -EACCES;
245 return hci_dev_reset(arg);
246
247 case HCIDEVRESTAT:
248 if (!capable(CAP_NET_ADMIN))
249 return -EACCES;
250 return hci_dev_reset_stat(arg);
251
252 case HCISETSCAN:
253 case HCISETAUTH:
254 case HCISETENCRYPT:
255 case HCISETPTYPE:
256 case HCISETLINKPOL:
257 case HCISETLINKMODE:
258 case HCISETACLMTU:
259 case HCISETSCOMTU:
260 if (!capable(CAP_NET_ADMIN))
261 return -EACCES;
262 return hci_dev_cmd(cmd, argp);
263
264 case HCIINQUIRY:
265 return hci_inquiry(argp);
266
267 default:
268 lock_sock(sk);
269 err = hci_sock_bound_ioctl(sk, cmd, arg);
270 release_sock(sk);
271 return err;
272 }
273}
274
275static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
276{
277 struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
278 struct sock *sk = sock->sk;
279 struct hci_dev *hdev = NULL;
280 int err = 0;
281
282 BT_DBG("sock %p sk %p", sock, sk);
283
284 if (!haddr || haddr->hci_family != AF_BLUETOOTH)
285 return -EINVAL;
286
287 lock_sock(sk);
288
289 if (hci_pi(sk)->hdev) {
290 err = -EALREADY;
291 goto done;
292 }
293
294 if (haddr->hci_dev != HCI_DEV_NONE) {
295 if (!(hdev = hci_dev_get(haddr->hci_dev))) {
296 err = -ENODEV;
297 goto done;
298 }
299
300 atomic_inc(&hdev->promisc);
301 }
302
303 hci_pi(sk)->hdev = hdev;
304 sk->sk_state = BT_BOUND;
305
306done:
307 release_sock(sk);
308 return err;
309}
310
311static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
312{
313 struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
314 struct sock *sk = sock->sk;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100315 struct hci_dev *hdev = hci_pi(sk)->hdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316
317 BT_DBG("sock %p sk %p", sock, sk);
318
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100319 if (!hdev)
320 return -EBADFD;
321
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322 lock_sock(sk);
323
324 *addr_len = sizeof(*haddr);
325 haddr->hci_family = AF_BLUETOOTH;
Marcel Holtmann7b005bd2006-02-13 11:40:03 +0100326 haddr->hci_dev = hdev->id;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327
328 release_sock(sk);
329 return 0;
330}
331
332static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
333{
334 __u32 mask = hci_pi(sk)->cmsg_mask;
335
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700336 if (mask & HCI_CMSG_DIR) {
337 int incoming = bt_cb(skb)->incoming;
338 put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(incoming), &incoming);
339 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340
Patrick McHardya61bbcf2005-08-14 17:24:31 -0700341 if (mask & HCI_CMSG_TSTAMP) {
342 struct timeval tv;
343
344 skb_get_timestamp(skb, &tv);
345 put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, sizeof(tv), &tv);
346 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347}
348
349static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
350 struct msghdr *msg, size_t len, int flags)
351{
352 int noblock = flags & MSG_DONTWAIT;
353 struct sock *sk = sock->sk;
354 struct sk_buff *skb;
355 int copied, err;
356
357 BT_DBG("sock %p, sk %p", sock, sk);
358
359 if (flags & (MSG_OOB))
360 return -EOPNOTSUPP;
361
362 if (sk->sk_state == BT_CLOSED)
363 return 0;
364
365 if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
366 return err;
367
368 msg->msg_namelen = 0;
369
370 copied = skb->len;
371 if (len < copied) {
372 msg->msg_flags |= MSG_TRUNC;
373 copied = len;
374 }
375
376 skb->h.raw = skb->data;
377 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
378
379 hci_sock_cmsg(sk, msg, skb);
380
381 skb_free_datagram(sk, skb);
382
383 return err ? : copied;
384}
385
386static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
387 struct msghdr *msg, size_t len)
388{
389 struct sock *sk = sock->sk;
390 struct hci_dev *hdev;
391 struct sk_buff *skb;
392 int err;
393
394 BT_DBG("sock %p sk %p", sock, sk);
395
396 if (msg->msg_flags & MSG_OOB)
397 return -EOPNOTSUPP;
398
399 if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
400 return -EINVAL;
401
402 if (len < 4 || len > HCI_MAX_FRAME_SIZE)
403 return -EINVAL;
404
405 lock_sock(sk);
406
407 if (!(hdev = hci_pi(sk)->hdev)) {
408 err = -EBADFD;
409 goto done;
410 }
411
412 if (!(skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
413 goto done;
414
415 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
416 err = -EFAULT;
417 goto drop;
418 }
419
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700420 bt_cb(skb)->pkt_type = *((unsigned char *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 skb_pull(skb, 1);
422 skb->dev = (void *) hdev;
423
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700424 if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
Marcel Holtmann1ebb9252005-11-08 09:57:21 -0800425 u16 opcode = __le16_to_cpu(get_unaligned((__le16 *) skb->data));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 u16 ogf = hci_opcode_ogf(opcode);
427 u16 ocf = hci_opcode_ocf(opcode);
428
429 if (((ogf > HCI_SFLT_MAX_OGF) ||
430 !hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) &&
431 !capable(CAP_NET_RAW)) {
432 err = -EPERM;
433 goto drop;
434 }
435
436 if (test_bit(HCI_RAW, &hdev->flags) || (ogf == OGF_VENDOR_CMD)) {
437 skb_queue_tail(&hdev->raw_q, skb);
438 hci_sched_tx(hdev);
439 } else {
440 skb_queue_tail(&hdev->cmd_q, skb);
441 hci_sched_cmd(hdev);
442 }
443 } else {
444 if (!capable(CAP_NET_RAW)) {
445 err = -EPERM;
446 goto drop;
447 }
448
449 skb_queue_tail(&hdev->raw_q, skb);
450 hci_sched_tx(hdev);
451 }
452
453 err = len;
454
455done:
456 release_sock(sk);
457 return err;
458
459drop:
460 kfree_skb(skb);
461 goto done;
462}
463
464static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int len)
465{
466 struct hci_ufilter uf = { .opcode = 0 };
467 struct sock *sk = sock->sk;
468 int err = 0, opt = 0;
469
470 BT_DBG("sk %p, opt %d", sk, optname);
471
472 lock_sock(sk);
473
474 switch (optname) {
475 case HCI_DATA_DIR:
476 if (get_user(opt, (int __user *)optval)) {
477 err = -EFAULT;
478 break;
479 }
480
481 if (opt)
482 hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
483 else
484 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
485 break;
486
487 case HCI_TIME_STAMP:
488 if (get_user(opt, (int __user *)optval)) {
489 err = -EFAULT;
490 break;
491 }
492
493 if (opt)
494 hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
495 else
496 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
497 break;
498
499 case HCI_FILTER:
500 len = min_t(unsigned int, len, sizeof(uf));
501 if (copy_from_user(&uf, optval, len)) {
502 err = -EFAULT;
503 break;
504 }
505
506 if (!capable(CAP_NET_RAW)) {
507 uf.type_mask &= hci_sec_filter.type_mask;
508 uf.event_mask[0] &= *((u32 *) hci_sec_filter.event_mask + 0);
509 uf.event_mask[1] &= *((u32 *) hci_sec_filter.event_mask + 1);
510 }
511
512 {
513 struct hci_filter *f = &hci_pi(sk)->filter;
514
515 f->type_mask = uf.type_mask;
516 f->opcode = uf.opcode;
517 *((u32 *) f->event_mask + 0) = uf.event_mask[0];
518 *((u32 *) f->event_mask + 1) = uf.event_mask[1];
519 }
520 break;
521
522 default:
523 err = -ENOPROTOOPT;
524 break;
525 }
526
527 release_sock(sk);
528 return err;
529}
530
531static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
532{
533 struct hci_ufilter uf;
534 struct sock *sk = sock->sk;
535 int len, opt;
536
537 if (get_user(len, optlen))
538 return -EFAULT;
539
540 switch (optname) {
541 case HCI_DATA_DIR:
542 if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
543 opt = 1;
544 else
545 opt = 0;
546
547 if (put_user(opt, optval))
548 return -EFAULT;
549 break;
550
551 case HCI_TIME_STAMP:
552 if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
553 opt = 1;
554 else
555 opt = 0;
556
557 if (put_user(opt, optval))
558 return -EFAULT;
559 break;
560
561 case HCI_FILTER:
562 {
563 struct hci_filter *f = &hci_pi(sk)->filter;
564
565 uf.type_mask = f->type_mask;
566 uf.opcode = f->opcode;
567 uf.event_mask[0] = *((u32 *) f->event_mask + 0);
568 uf.event_mask[1] = *((u32 *) f->event_mask + 1);
569 }
570
571 len = min_t(unsigned int, len, sizeof(uf));
572 if (copy_to_user(optval, &uf, len))
573 return -EFAULT;
574 break;
575
576 default:
577 return -ENOPROTOOPT;
578 break;
579 }
580
581 return 0;
582}
583
Eric Dumazet90ddc4f2005-12-22 12:49:22 -0800584static const struct proto_ops hci_sock_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 .family = PF_BLUETOOTH,
586 .owner = THIS_MODULE,
587 .release = hci_sock_release,
588 .bind = hci_sock_bind,
589 .getname = hci_sock_getname,
590 .sendmsg = hci_sock_sendmsg,
591 .recvmsg = hci_sock_recvmsg,
592 .ioctl = hci_sock_ioctl,
593 .poll = datagram_poll,
594 .listen = sock_no_listen,
595 .shutdown = sock_no_shutdown,
596 .setsockopt = hci_sock_setsockopt,
597 .getsockopt = hci_sock_getsockopt,
598 .connect = sock_no_connect,
599 .socketpair = sock_no_socketpair,
600 .accept = sock_no_accept,
601 .mmap = sock_no_mmap
602};
603
604static struct proto hci_sk_proto = {
605 .name = "HCI",
606 .owner = THIS_MODULE,
607 .obj_size = sizeof(struct hci_pinfo)
608};
609
610static int hci_sock_create(struct socket *sock, int protocol)
611{
612 struct sock *sk;
613
614 BT_DBG("sock %p", sock);
615
616 if (sock->type != SOCK_RAW)
617 return -ESOCKTNOSUPPORT;
618
619 sock->ops = &hci_sock_ops;
620
621 sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &hci_sk_proto, 1);
622 if (!sk)
623 return -ENOMEM;
624
625 sock_init_data(sock, sk);
626
627 sock_reset_flag(sk, SOCK_ZAPPED);
628
629 sk->sk_protocol = protocol;
630
631 sock->state = SS_UNCONNECTED;
632 sk->sk_state = BT_OPEN;
633
634 bt_sock_link(&hci_sk_list, sk);
635 return 0;
636}
637
638static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
639{
640 struct hci_dev *hdev = (struct hci_dev *) ptr;
641 struct hci_ev_si_device ev;
642
643 BT_DBG("hdev %s event %ld", hdev->name, event);
644
645 /* Send event to sockets */
646 ev.event = event;
647 ev.dev_id = hdev->id;
648 hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
649
650 if (event == HCI_DEV_UNREG) {
651 struct sock *sk;
652 struct hlist_node *node;
653
654 /* Detach sockets from device */
655 read_lock(&hci_sk_list.lock);
656 sk_for_each(sk, node, &hci_sk_list.head) {
657 bh_lock_sock(sk);
658 if (hci_pi(sk)->hdev == hdev) {
659 hci_pi(sk)->hdev = NULL;
660 sk->sk_err = EPIPE;
661 sk->sk_state = BT_OPEN;
662 sk->sk_state_change(sk);
663
664 hci_dev_put(hdev);
665 }
666 bh_unlock_sock(sk);
667 }
668 read_unlock(&hci_sk_list.lock);
669 }
670
671 return NOTIFY_DONE;
672}
673
674static struct net_proto_family hci_sock_family_ops = {
675 .family = PF_BLUETOOTH,
676 .owner = THIS_MODULE,
677 .create = hci_sock_create,
678};
679
680static struct notifier_block hci_sock_nblock = {
681 .notifier_call = hci_sock_dev_event
682};
683
684int __init hci_sock_init(void)
685{
686 int err;
687
688 err = proto_register(&hci_sk_proto, 0);
689 if (err < 0)
690 return err;
691
692 err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
693 if (err < 0)
694 goto error;
695
696 hci_register_notifier(&hci_sock_nblock);
697
698 BT_INFO("HCI socket layer initialized");
699
700 return 0;
701
702error:
703 BT_ERR("HCI socket registration failed");
704 proto_unregister(&hci_sk_proto);
705 return err;
706}
707
708int __exit hci_sock_cleanup(void)
709{
710 if (bt_sock_unregister(BTPROTO_HCI) < 0)
711 BT_ERR("HCI socket unregistration failed");
712
713 hci_unregister_notifier(&hci_sock_nblock);
714
715 proto_unregister(&hci_sk_proto);
716
717 return 0;
718}