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