Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[firefly-linux-kernel-4.4.55.git] / net / bluetooth / hci_sock.c
index ff02cf5e77ccdd576d2f42f78f2c4715e3a47d5e..6d94616af3129b3519c914c3458eb30cad40de05 100644 (file)
@@ -49,7 +49,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
-static int enable_mgmt;
+static bool enable_mgmt;
 
 /* ----- HCI socket interface ----- */
 
@@ -183,21 +183,35 @@ static int hci_sock_release(struct socket *sock)
 static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg)
 {
        bdaddr_t bdaddr;
+       int err;
 
        if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
                return -EFAULT;
 
-       return hci_blacklist_add(hdev, &bdaddr);
+       hci_dev_lock(hdev);
+
+       err = hci_blacklist_add(hdev, &bdaddr);
+
+       hci_dev_unlock(hdev);
+
+       return err;
 }
 
 static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
 {
        bdaddr_t bdaddr;
+       int err;
 
        if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
                return -EFAULT;
 
-       return hci_blacklist_del(hdev, &bdaddr);
+       hci_dev_lock(hdev);
+
+       err = hci_blacklist_del(hdev, &bdaddr);
+
+       hci_dev_unlock(hdev);
+
+       return err;
 }
 
 /* Ioctls that require bound socket */
@@ -329,8 +343,11 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
        if (haddr.hci_channel > HCI_CHANNEL_CONTROL)
                return -EINVAL;
 
-       if (haddr.hci_channel == HCI_CHANNEL_CONTROL && !enable_mgmt)
-               return -EINVAL;
+       if (haddr.hci_channel == HCI_CHANNEL_CONTROL) {
+               if (!enable_mgmt)
+                       return -EINVAL;
+               set_bit(HCI_PI_MGMT_INIT, &hci_pi(sk)->flags);
+       }
 
        lock_sock(sk);
 
@@ -521,10 +538,10 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 
                if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) {
                        skb_queue_tail(&hdev->raw_q, skb);
-                       tasklet_schedule(&hdev->tx_task);
+                       queue_work(hdev->workqueue, &hdev->tx_work);
                } else {
                        skb_queue_tail(&hdev->cmd_q, skb);
-                       tasklet_schedule(&hdev->cmd_task);
+                       queue_work(hdev->workqueue, &hdev->cmd_work);
                }
        } else {
                if (!capable(CAP_NET_RAW)) {
@@ -533,7 +550,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                }
 
                skb_queue_tail(&hdev->raw_q, skb);
-               tasklet_schedule(&hdev->tx_task);
+               queue_work(hdev->workqueue, &hdev->tx_work);
        }
 
        err = len;