linux/net/bluetooth/hci_sock.c
<<
>>
Prefs
   1/*
   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
  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 */
  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
  86static struct bt_sock_list hci_sk_list = {
  87        .lock = __RW_LOCK_UNLOCKED(hci_sk_list.lock)
  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
 113                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))
 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
 145static 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 */
 174static 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 HCIGETCONNINFO:
 197                return hci_get_conn_info(hdev, (void __user *) arg);
 198
 199        case HCIGETAUTHINFO:
 200                return hci_get_auth_info(hdev, (void __user *) arg);
 201
 202        default:
 203                if (hdev->ioctl)
 204                        return hdev->ioctl(hdev, cmd, arg);
 205                return -EINVAL;
 206        }
 207}
 208
 209static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 210{
 211        struct sock *sk = sock->sk;
 212        void __user *argp = (void __user *) arg;
 213        int err;
 214
 215        BT_DBG("cmd %x arg %lx", cmd, arg);
 216
 217        switch (cmd) {
 218        case HCIGETDEVLIST:
 219                return hci_get_dev_list(argp);
 220
 221        case HCIGETDEVINFO:
 222                return hci_get_dev_info(argp);
 223
 224        case HCIGETCONNLIST:
 225                return hci_get_conn_list(argp);
 226
 227        case HCIDEVUP:
 228                if (!capable(CAP_NET_ADMIN))
 229                        return -EACCES;
 230                return hci_dev_open(arg);
 231
 232        case HCIDEVDOWN:
 233                if (!capable(CAP_NET_ADMIN))
 234                        return -EACCES;
 235                return hci_dev_close(arg);
 236
 237        case HCIDEVRESET:
 238                if (!capable(CAP_NET_ADMIN))
 239                        return -EACCES;
 240                return hci_dev_reset(arg);
 241
 242        case HCIDEVRESTAT:
 243                if (!capable(CAP_NET_ADMIN))
 244                        return -EACCES;
 245                return hci_dev_reset_stat(arg);
 246
 247        case HCISETSCAN:
 248        case HCISETAUTH:
 249        case HCISETENCRYPT:
 250        case HCISETPTYPE:
 251        case HCISETLINKPOL:
 252        case HCISETLINKMODE:
 253        case HCISETACLMTU:
 254        case HCISETSCOMTU:
 255                if (!capable(CAP_NET_ADMIN))
 256                        return -EACCES;
 257                return hci_dev_cmd(cmd, argp);
 258
 259        case HCIINQUIRY:
 260                return hci_inquiry(argp);
 261
 262        default:
 263                lock_sock(sk);
 264                err = hci_sock_bound_ioctl(sk, cmd, arg);
 265                release_sock(sk);
 266                return err;
 267        }
 268}
 269
 270static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
 271{
 272        struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
 273        struct sock *sk = sock->sk;
 274        struct hci_dev *hdev = NULL;
 275        int err = 0;
 276
 277        BT_DBG("sock %p sk %p", sock, sk);
 278
 279        if (!haddr || haddr->hci_family != AF_BLUETOOTH)
 280                return -EINVAL;
 281
 282        lock_sock(sk);
 283
 284        if (hci_pi(sk)->hdev) {
 285                err = -EALREADY;
 286                goto done;
 287        }
 288
 289        if (haddr->hci_dev != HCI_DEV_NONE) {
 290                if (!(hdev = hci_dev_get(haddr->hci_dev))) {
 291                        err = -ENODEV;
 292                        goto done;
 293                }
 294
 295                atomic_inc(&hdev->promisc);
 296        }
 297
 298        hci_pi(sk)->hdev = hdev;
 299        sk->sk_state = BT_BOUND;
 300
 301done:
 302        release_sock(sk);
 303        return err;
 304}
 305
 306static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
 307{
 308        struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
 309        struct sock *sk = sock->sk;
 310        struct hci_dev *hdev = hci_pi(sk)->hdev;
 311
 312        BT_DBG("sock %p sk %p", sock, sk);
 313
 314        if (!hdev)
 315                return -EBADFD;
 316
 317        lock_sock(sk);
 318
 319        *addr_len = sizeof(*haddr);
 320        haddr->hci_family = AF_BLUETOOTH;
 321        haddr->hci_dev    = hdev->id;
 322
 323        release_sock(sk);
 324        return 0;
 325}
 326
 327static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
 328{
 329        __u32 mask = hci_pi(sk)->cmsg_mask;
 330
 331        if (mask & HCI_CMSG_DIR) {
 332                int incoming = bt_cb(skb)->incoming;
 333                put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(incoming), &incoming);
 334        }
 335
 336        if (mask & HCI_CMSG_TSTAMP) {
 337                struct timeval tv;
 338                void *data;
 339                int len;
 340
 341                skb_get_timestamp(skb, &tv);
 342
 343                data = &tv;
 344                len = sizeof(tv);
 345#ifdef CONFIG_COMPAT
 346                if (msg->msg_flags & MSG_CMSG_COMPAT) {
 347                        struct compat_timeval ctv;
 348                        ctv.tv_sec = tv.tv_sec;
 349                        ctv.tv_usec = tv.tv_usec;
 350                        data = &ctv;
 351                        len = sizeof(ctv);
 352                }
 353#endif
 354
 355                put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, len, data);
 356        }
 357}
 358
 359static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 360                                struct msghdr *msg, size_t len, int flags)
 361{
 362        int noblock = flags & MSG_DONTWAIT;
 363        struct sock *sk = sock->sk;
 364        struct sk_buff *skb;
 365        int copied, err;
 366
 367        BT_DBG("sock %p, sk %p", sock, sk);
 368
 369        if (flags & (MSG_OOB))
 370                return -EOPNOTSUPP;
 371
 372        if (sk->sk_state == BT_CLOSED)
 373                return 0;
 374
 375        if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
 376                return err;
 377
 378        msg->msg_namelen = 0;
 379
 380        copied = skb->len;
 381        if (len < copied) {
 382                msg->msg_flags |= MSG_TRUNC;
 383                copied = len;
 384        }
 385
 386        skb_reset_transport_header(skb);
 387        err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 388
 389        hci_sock_cmsg(sk, msg, skb);
 390
 391        skb_free_datagram(sk, skb);
 392
 393        return err ? : copied;
 394}
 395
 396static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 397                            struct msghdr *msg, size_t len)
 398{
 399        struct sock *sk = sock->sk;
 400        struct hci_dev *hdev;
 401        struct sk_buff *skb;
 402        int err;
 403
 404        BT_DBG("sock %p sk %p", sock, sk);
 405
 406        if (msg->msg_flags & MSG_OOB)
 407                return -EOPNOTSUPP;
 408
 409        if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
 410                return -EINVAL;
 411
 412        if (len < 4 || len > HCI_MAX_FRAME_SIZE)
 413                return -EINVAL;
 414
 415        lock_sock(sk);
 416
 417        if (!(hdev = hci_pi(sk)->hdev)) {
 418                err = -EBADFD;
 419                goto done;
 420        }
 421
 422        if (!(skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
 423                goto done;
 424
 425        if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
 426                err = -EFAULT;
 427                goto drop;
 428        }
 429
 430        bt_cb(skb)->pkt_type = *((unsigned char *) skb->data);
 431        skb_pull(skb, 1);
 432        skb->dev = (void *) hdev;
 433
 434        if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
 435                u16 opcode = get_unaligned_le16(skb->data);
 436                u16 ogf = hci_opcode_ogf(opcode);
 437                u16 ocf = hci_opcode_ocf(opcode);
 438
 439                if (((ogf > HCI_SFLT_MAX_OGF) ||
 440                                !hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) &&
 441                                        !capable(CAP_NET_RAW)) {
 442                        err = -EPERM;
 443                        goto drop;
 444                }
 445
 446                if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) {
 447                        skb_queue_tail(&hdev->raw_q, skb);
 448                        hci_sched_tx(hdev);
 449                } else {
 450                        skb_queue_tail(&hdev->cmd_q, skb);
 451                        hci_sched_cmd(hdev);
 452                }
 453        } else {
 454                if (!capable(CAP_NET_RAW)) {
 455                        err = -EPERM;
 456                        goto drop;
 457                }
 458
 459                skb_queue_tail(&hdev->raw_q, skb);
 460                hci_sched_tx(hdev);
 461        }
 462
 463        err = len;
 464
 465done:
 466        release_sock(sk);
 467        return err;
 468
 469drop:
 470        kfree_skb(skb);
 471        goto done;
 472}
 473
 474static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int len)
 475{
 476        struct hci_ufilter uf = { .opcode = 0 };
 477        struct sock *sk = sock->sk;
 478        int err = 0, opt = 0;
 479
 480        BT_DBG("sk %p, opt %d", sk, optname);
 481
 482        lock_sock(sk);
 483
 484        switch (optname) {
 485        case HCI_DATA_DIR:
 486                if (get_user(opt, (int __user *)optval)) {
 487                        err = -EFAULT;
 488                        break;
 489                }
 490
 491                if (opt)
 492                        hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
 493                else
 494                        hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
 495                break;
 496
 497        case HCI_TIME_STAMP:
 498                if (get_user(opt, (int __user *)optval)) {
 499                        err = -EFAULT;
 500                        break;
 501                }
 502
 503                if (opt)
 504                        hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
 505                else
 506                        hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
 507                break;
 508
 509        case HCI_FILTER:
 510                {
 511                        struct hci_filter *f = &hci_pi(sk)->filter;
 512
 513                        uf.type_mask = f->type_mask;
 514                        uf.opcode    = f->opcode;
 515                        uf.event_mask[0] = *((u32 *) f->event_mask + 0);
 516                        uf.event_mask[1] = *((u32 *) f->event_mask + 1);
 517                }
 518
 519                len = min_t(unsigned int, len, sizeof(uf));
 520                if (copy_from_user(&uf, optval, len)) {
 521                        err = -EFAULT;
 522                        break;
 523                }
 524
 525                if (!capable(CAP_NET_RAW)) {
 526                        uf.type_mask &= hci_sec_filter.type_mask;
 527                        uf.event_mask[0] &= *((u32 *) hci_sec_filter.event_mask + 0);
 528                        uf.event_mask[1] &= *((u32 *) hci_sec_filter.event_mask + 1);
 529                }
 530
 531                {
 532                        struct hci_filter *f = &hci_pi(sk)->filter;
 533
 534                        f->type_mask = uf.type_mask;
 535                        f->opcode    = uf.opcode;
 536                        *((u32 *) f->event_mask + 0) = uf.event_mask[0];
 537                        *((u32 *) f->event_mask + 1) = uf.event_mask[1];
 538                }
 539                break;
 540
 541        default:
 542                err = -ENOPROTOOPT;
 543                break;
 544        }
 545
 546        release_sock(sk);
 547        return err;
 548}
 549
 550static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
 551{
 552        struct hci_ufilter uf;
 553        struct sock *sk = sock->sk;
 554        int len, opt;
 555
 556        if (get_user(len, optlen))
 557                return -EFAULT;
 558
 559        switch (optname) {
 560        case HCI_DATA_DIR:
 561                if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
 562                        opt = 1;
 563                else
 564                        opt = 0;
 565
 566                if (put_user(opt, optval))
 567                        return -EFAULT;
 568                break;
 569
 570        case HCI_TIME_STAMP:
 571                if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
 572                        opt = 1;
 573                else
 574                        opt = 0;
 575
 576                if (put_user(opt, optval))
 577                        return -EFAULT;
 578                break;
 579
 580        case HCI_FILTER:
 581                {
 582                        struct hci_filter *f = &hci_pi(sk)->filter;
 583
 584                        uf.type_mask = f->type_mask;
 585                        uf.opcode    = f->opcode;
 586                        uf.event_mask[0] = *((u32 *) f->event_mask + 0);
 587                        uf.event_mask[1] = *((u32 *) f->event_mask + 1);
 588                }
 589
 590                len = min_t(unsigned int, len, sizeof(uf));
 591                if (copy_to_user(optval, &uf, len))
 592                        return -EFAULT;
 593                break;
 594
 595        default:
 596                return -ENOPROTOOPT;
 597                break;
 598        }
 599
 600        return 0;
 601}
 602
 603static const struct proto_ops hci_sock_ops = {
 604        .family         = PF_BLUETOOTH,
 605        .owner          = THIS_MODULE,
 606        .release        = hci_sock_release,
 607        .bind           = hci_sock_bind,
 608        .getname        = hci_sock_getname,
 609        .sendmsg        = hci_sock_sendmsg,
 610        .recvmsg        = hci_sock_recvmsg,
 611        .ioctl          = hci_sock_ioctl,
 612        .poll           = datagram_poll,
 613        .listen         = sock_no_listen,
 614        .shutdown       = sock_no_shutdown,
 615        .setsockopt     = hci_sock_setsockopt,
 616        .getsockopt     = hci_sock_getsockopt,
 617        .connect        = sock_no_connect,
 618        .socketpair     = sock_no_socketpair,
 619        .accept         = sock_no_accept,
 620        .mmap           = sock_no_mmap
 621};
 622
 623static struct proto hci_sk_proto = {
 624        .name           = "HCI",
 625        .owner          = THIS_MODULE,
 626        .obj_size       = sizeof(struct hci_pinfo)
 627};
 628
 629static int hci_sock_create(struct net *net, struct socket *sock, int protocol)
 630{
 631        struct sock *sk;
 632
 633        BT_DBG("sock %p", sock);
 634
 635        if (sock->type != SOCK_RAW)
 636                return -ESOCKTNOSUPPORT;
 637
 638        sock->ops = &hci_sock_ops;
 639
 640        sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto);
 641        if (!sk)
 642                return -ENOMEM;
 643
 644        sock_init_data(sock, sk);
 645
 646        sock_reset_flag(sk, SOCK_ZAPPED);
 647
 648        sk->sk_protocol = protocol;
 649
 650        sock->state = SS_UNCONNECTED;
 651        sk->sk_state = BT_OPEN;
 652
 653        bt_sock_link(&hci_sk_list, sk);
 654        return 0;
 655}
 656
 657static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
 658{
 659        struct hci_dev *hdev = (struct hci_dev *) ptr;
 660        struct hci_ev_si_device ev;
 661
 662        BT_DBG("hdev %s event %ld", hdev->name, event);
 663
 664        /* Send event to sockets */
 665        ev.event  = event;
 666        ev.dev_id = hdev->id;
 667        hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
 668
 669        if (event == HCI_DEV_UNREG) {
 670                struct sock *sk;
 671                struct hlist_node *node;
 672
 673                /* Detach sockets from device */
 674                read_lock(&hci_sk_list.lock);
 675                sk_for_each(sk, node, &hci_sk_list.head) {
 676                        local_bh_disable();
 677                        bh_lock_sock_nested(sk);
 678                        if (hci_pi(sk)->hdev == hdev) {
 679                                hci_pi(sk)->hdev = NULL;
 680                                sk->sk_err = EPIPE;
 681                                sk->sk_state = BT_OPEN;
 682                                sk->sk_state_change(sk);
 683
 684                                hci_dev_put(hdev);
 685                        }
 686                        bh_unlock_sock(sk);
 687                        local_bh_enable();
 688                }
 689                read_unlock(&hci_sk_list.lock);
 690        }
 691
 692        return NOTIFY_DONE;
 693}
 694
 695static struct net_proto_family hci_sock_family_ops = {
 696        .family = PF_BLUETOOTH,
 697        .owner  = THIS_MODULE,
 698        .create = hci_sock_create,
 699};
 700
 701static struct notifier_block hci_sock_nblock = {
 702        .notifier_call = hci_sock_dev_event
 703};
 704
 705int __init hci_sock_init(void)
 706{
 707        int err;
 708
 709        err = proto_register(&hci_sk_proto, 0);
 710        if (err < 0)
 711                return err;
 712
 713        err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
 714        if (err < 0)
 715                goto error;
 716
 717        hci_register_notifier(&hci_sock_nblock);
 718
 719        BT_INFO("HCI socket layer initialized");
 720
 721        return 0;
 722
 723error:
 724        BT_ERR("HCI socket registration failed");
 725        proto_unregister(&hci_sk_proto);
 726        return err;
 727}
 728
 729void __exit hci_sock_cleanup(void)
 730{
 731        if (bt_sock_unregister(BTPROTO_HCI) < 0)
 732                BT_ERR("HCI socket unregistration failed");
 733
 734        hci_unregister_notifier(&hci_sock_nblock);
 735
 736        proto_unregister(&hci_sk_proto);
 737}
 738
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.