OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [net/] [bluetooth/] [hci_sock.c] - Blame information for rev 11

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.