Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetoot...
[cascardo/linux.git] / net / bluetooth / hci_sock.c
index 2c245fd..cb4bc48 100644 (file)
@@ -46,9 +46,9 @@ struct hci_pinfo {
        unsigned short    channel;
 };
 
-static inline int hci_test_bit(int nr, void *addr)
+static inline int hci_test_bit(int nr, const void *addr)
 {
-       return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
+       return *((const __u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
 }
 
 /* Security filter */
@@ -183,12 +183,13 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
        kfree_skb(skb_copy);
 }
 
-/* Send frame to control socket */
-void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk)
+/* Send frame to sockets with specific channel */
+void hci_send_to_channel(unsigned short channel, struct sk_buff *skb,
+                        struct sock *skip_sk)
 {
        struct sock *sk;
 
-       BT_DBG("len %d", skb->len);
+       BT_DBG("channel %u len %d", channel, skb->len);
 
        read_lock(&hci_sk_list.lock);
 
@@ -202,7 +203,7 @@ void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk)
                if (sk->sk_state != BT_BOUND)
                        continue;
 
-               if (hci_pi(sk)->channel != HCI_CHANNEL_CONTROL)
+               if (hci_pi(sk)->channel != channel)
                        continue;
 
                nskb = skb_clone(skb, GFP_ATOMIC);
@@ -219,8 +220,8 @@ void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk)
 /* Send frame to monitor socket */
 void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct sock *sk;
        struct sk_buff *skb_copy = NULL;
+       struct hci_mon_hdr *hdr;
        __le16 opcode;
 
        if (!atomic_read(&monitor_promisc))
@@ -251,74 +252,21 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
                return;
        }
 
-       read_lock(&hci_sk_list.lock);
-
-       sk_for_each(sk, &hci_sk_list.head) {
-               struct sk_buff *nskb;
-
-               if (sk->sk_state != BT_BOUND)
-                       continue;
-
-               if (hci_pi(sk)->channel != HCI_CHANNEL_MONITOR)
-                       continue;
-
-               if (!skb_copy) {
-                       struct hci_mon_hdr *hdr;
-
-                       /* Create a private copy with headroom */
-                       skb_copy = __pskb_copy_fclone(skb, HCI_MON_HDR_SIZE,
-                                                     GFP_ATOMIC, true);
-                       if (!skb_copy)
-                               continue;
-
-                       /* Put header before the data */
-                       hdr = (void *) skb_push(skb_copy, HCI_MON_HDR_SIZE);
-                       hdr->opcode = opcode;
-                       hdr->index = cpu_to_le16(hdev->id);
-                       hdr->len = cpu_to_le16(skb->len);
-               }
-
-               nskb = skb_clone(skb_copy, GFP_ATOMIC);
-               if (!nskb)
-                       continue;
-
-               if (sock_queue_rcv_skb(sk, nskb))
-                       kfree_skb(nskb);
-       }
+       /* Create a private copy with headroom */
+       skb_copy = __pskb_copy_fclone(skb, HCI_MON_HDR_SIZE, GFP_ATOMIC, true);
+       if (!skb_copy)
+               return;
 
-       read_unlock(&hci_sk_list.lock);
+       /* Put header before the data */
+       hdr = (void *) skb_push(skb_copy, HCI_MON_HDR_SIZE);
+       hdr->opcode = opcode;
+       hdr->index = cpu_to_le16(hdev->id);
+       hdr->len = cpu_to_le16(skb->len);
 
+       hci_send_to_channel(HCI_CHANNEL_MONITOR, skb_copy, NULL);
        kfree_skb(skb_copy);
 }
 
-static void send_monitor_event(struct sk_buff *skb)
-{
-       struct sock *sk;
-
-       BT_DBG("len %d", skb->len);
-
-       read_lock(&hci_sk_list.lock);
-
-       sk_for_each(sk, &hci_sk_list.head) {
-               struct sk_buff *nskb;
-
-               if (sk->sk_state != BT_BOUND)
-                       continue;
-
-               if (hci_pi(sk)->channel != HCI_CHANNEL_MONITOR)
-                       continue;
-
-               nskb = skb_clone(skb, GFP_ATOMIC);
-               if (!nskb)
-                       continue;
-
-               if (sock_queue_rcv_skb(sk, nskb))
-                       kfree_skb(nskb);
-       }
-
-       read_unlock(&hci_sk_list.lock);
-}
-
 static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event)
 {
        struct hci_mon_hdr *hdr;
@@ -422,7 +370,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event)
 
                skb = create_monitor_event(hdev, event);
                if (skb) {
-                       send_monitor_event(skb);
+                       hci_send_to_channel(HCI_CHANNEL_MONITOR, skb, NULL);
                        kfree_skb(skb);
                }
        }
@@ -851,8 +799,8 @@ static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg,
        }
 }
 
-static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
-                           struct msghdr *msg, size_t len, int flags)
+static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+                           int flags)
 {
        int noblock = flags & MSG_DONTWAIT;
        struct sock *sk = sock->sk;
@@ -896,8 +844,8 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        return err ? : copied;
 }
 
-static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
-                           struct msghdr *msg, size_t len)
+static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
+                           size_t len)
 {
        struct sock *sk = sock->sk;
        struct hci_dev *hdev;
@@ -990,7 +938,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                        /* Stand-alone HCI commands must be flagged as
                         * single-command requests.
                         */
-                       bt_cb(skb)->req.start = true;
+                       bt_cb(skb)->req_start = 1;
 
                        skb_queue_tail(&hdev->cmd_q, skb);
                        queue_work(hdev->workqueue, &hdev->cmd_work);
@@ -1230,6 +1178,8 @@ int __init hci_sock_init(void)
 {
        int err;
 
+       BUILD_BUG_ON(sizeof(struct sockaddr_hci) > sizeof(struct sockaddr));
+
        err = proto_register(&hci_sk_proto, 0);
        if (err < 0)
                return err;