drm/panel: add support for Sharp F402 2048x1536 panel
[firefly-linux-kernel-4.4.55.git] / net / bluetooth / hci_sock.c
index 9bd7d959e384c74504a06ed27e0eef0d61dbf70e..b1eb8c09a66016c2cbcca79dcf3bb533bb85ec02 100644 (file)
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/hci_mon.h>
+#include <net/bluetooth/mgmt.h>
+
+#include "mgmt_util.h"
+
+static LIST_HEAD(mgmt_chan_list);
+static DEFINE_MUTEX(mgmt_chan_list_lock);
 
 static atomic_t monitor_promisc = ATOMIC_INIT(0);
 
 /* ----- HCI socket interface ----- */
 
-static inline int hci_test_bit(int nr, void *addr)
+/* Socket info */
+#define hci_pi(sk) ((struct hci_pinfo *) sk)
+
+struct hci_pinfo {
+       struct bt_sock    bt;
+       struct hci_dev    *hdev;
+       struct hci_filter filter;
+       __u32             cmsg_mask;
+       unsigned short    channel;
+       unsigned long     flags;
+};
+
+void hci_sock_set_flag(struct sock *sk, int nr)
+{
+       set_bit(nr, &hci_pi(sk)->flags);
+}
+
+void hci_sock_clear_flag(struct sock *sk, int nr)
+{
+       clear_bit(nr, &hci_pi(sk)->flags);
+}
+
+int hci_sock_test_flag(struct sock *sk, int nr)
 {
-       return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
+       return test_bit(nr, &hci_pi(sk)->flags);
+}
+
+unsigned short hci_sock_get_channel(struct sock *sk)
+{
+       return hci_pi(sk)->channel;
+}
+
+static inline int hci_test_bit(int nr, const void *addr)
+{
+       return *((const __u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
 }
 
 /* Security filter */
-static struct hci_sec_filter hci_sec_filter = {
+#define HCI_SFLT_MAX_OGF  5
+
+struct hci_sec_filter {
+       __u32 type_mask;
+       __u32 event_mask[2];
+       __u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4];
+};
+
+static const struct hci_sec_filter hci_sec_filter = {
        /* Packet types */
        0x10,
        /* Events */
@@ -66,6 +112,43 @@ static struct bt_sock_list hci_sk_list = {
        .lock = __RW_LOCK_UNLOCKED(hci_sk_list.lock)
 };
 
+static bool is_filtered_packet(struct sock *sk, struct sk_buff *skb)
+{
+       struct hci_filter *flt;
+       int flt_type, flt_event;
+
+       /* Apply filter */
+       flt = &hci_pi(sk)->filter;
+
+       flt_type = bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS;
+
+       if (!test_bit(flt_type, &flt->type_mask))
+               return true;
+
+       /* Extra filter for event packets only */
+       if (bt_cb(skb)->pkt_type != HCI_EVENT_PKT)
+               return false;
+
+       flt_event = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
+
+       if (!hci_test_bit(flt_event, &flt->event_mask))
+               return true;
+
+       /* Check filter only when opcode is set */
+       if (!flt->opcode)
+               return false;
+
+       if (flt_event == HCI_EV_CMD_COMPLETE &&
+           flt->opcode != get_unaligned((__le16 *)(skb->data + 3)))
+               return true;
+
+       if (flt_event == HCI_EV_CMD_STATUS &&
+           flt->opcode != get_unaligned((__le16 *)(skb->data + 4)))
+               return true;
+
+       return false;
+}
+
 /* Send frame to RAW socket */
 void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
 {
@@ -77,7 +160,6 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
        read_lock(&hci_sk_list.lock);
 
        sk_for_each(sk, &hci_sk_list.head) {
-               struct hci_filter *flt;
                struct sk_buff *nskb;
 
                if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev)
@@ -87,36 +169,29 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
                if (skb->sk == sk)
                        continue;
 
-               if (hci_pi(sk)->channel != HCI_CHANNEL_RAW)
-                       continue;
-
-               /* Apply filter */
-               flt = &hci_pi(sk)->filter;
-
-               if (!test_bit((bt_cb(skb)->pkt_type == HCI_VENDOR_PKT) ?
-                             0 : (bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS),
-                             &flt->type_mask))
-                       continue;
-
-               if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) {
-                       int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
-
-                       if (!hci_test_bit(evt, &flt->event_mask))
+               if (hci_pi(sk)->channel == HCI_CHANNEL_RAW) {
+                       if (bt_cb(skb)->pkt_type != HCI_COMMAND_PKT &&
+                           bt_cb(skb)->pkt_type != HCI_EVENT_PKT &&
+                           bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT &&
+                           bt_cb(skb)->pkt_type != HCI_SCODATA_PKT)
                                continue;
-
-                       if (flt->opcode &&
-                           ((evt == HCI_EV_CMD_COMPLETE &&
-                             flt->opcode !=
-                             get_unaligned((__le16 *)(skb->data + 3))) ||
-                            (evt == HCI_EV_CMD_STATUS &&
-                             flt->opcode !=
-                             get_unaligned((__le16 *)(skb->data + 4)))))
+                       if (is_filtered_packet(sk, skb))
+                               continue;
+               } else if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
+                       if (!bt_cb(skb)->incoming)
+                               continue;
+                       if (bt_cb(skb)->pkt_type != HCI_EVENT_PKT &&
+                           bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT &&
+                           bt_cb(skb)->pkt_type != HCI_SCODATA_PKT)
                                continue;
+               } else {
+                       /* Don't send frame to other channel types */
+                       continue;
                }
 
                if (!skb_copy) {
                        /* Create a private copy with headroom */
-                       skb_copy = __pskb_copy(skb, 1, GFP_ATOMIC);
+                       skb_copy = __pskb_copy_fclone(skb, 1, GFP_ATOMIC, true);
                        if (!skb_copy)
                                continue;
 
@@ -137,18 +212,23 @@ 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,
+                        int flag, 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);
 
        sk_for_each(sk, &hci_sk_list.head) {
                struct sk_buff *nskb;
 
+               /* Ignore socket without the flag set */
+               if (!hci_sock_test_flag(sk, flag))
+                       continue;
+
                /* Skip the original socket */
                if (sk == skip_sk)
                        continue;
@@ -156,7 +236,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);
@@ -173,8 +253,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))
@@ -184,99 +264,51 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
 
        switch (bt_cb(skb)->pkt_type) {
        case HCI_COMMAND_PKT:
-               opcode = __constant_cpu_to_le16(HCI_MON_COMMAND_PKT);
+               opcode = cpu_to_le16(HCI_MON_COMMAND_PKT);
                break;
        case HCI_EVENT_PKT:
-               opcode = __constant_cpu_to_le16(HCI_MON_EVENT_PKT);
+               opcode = cpu_to_le16(HCI_MON_EVENT_PKT);
                break;
        case HCI_ACLDATA_PKT:
                if (bt_cb(skb)->incoming)
-                       opcode = __constant_cpu_to_le16(HCI_MON_ACL_RX_PKT);
+                       opcode = cpu_to_le16(HCI_MON_ACL_RX_PKT);
                else
-                       opcode = __constant_cpu_to_le16(HCI_MON_ACL_TX_PKT);
+                       opcode = cpu_to_le16(HCI_MON_ACL_TX_PKT);
                break;
        case HCI_SCODATA_PKT:
                if (bt_cb(skb)->incoming)
-                       opcode = __constant_cpu_to_le16(HCI_MON_SCO_RX_PKT);
+                       opcode = cpu_to_le16(HCI_MON_SCO_RX_PKT);
                else
-                       opcode = __constant_cpu_to_le16(HCI_MON_SCO_TX_PKT);
+                       opcode = cpu_to_le16(HCI_MON_SCO_TX_PKT);
+               break;
+       case HCI_DIAG_PKT:
+               opcode = cpu_to_le16(HCI_MON_VENDOR_DIAG);
                break;
        default:
                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(skb, HCI_MON_HDR_SIZE,
-                                              GFP_ATOMIC);
-                       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,
+                           HCI_SOCK_TRUSTED, 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;
        struct hci_mon_new_index *ni;
+       struct hci_mon_index_info *ii;
        struct sk_buff *skb;
        __le16 opcode;
 
@@ -286,13 +318,13 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event)
                if (!skb)
                        return NULL;
 
-               ni = (void *) skb_put(skb, HCI_MON_NEW_INDEX_SIZE);
+               ni = (void *)skb_put(skb, HCI_MON_NEW_INDEX_SIZE);
                ni->type = hdev->dev_type;
                ni->bus = hdev->bus;
                bacpy(&ni->bdaddr, &hdev->bdaddr);
                memcpy(ni->name, hdev->name, 8);
 
-               opcode = __constant_cpu_to_le16(HCI_MON_NEW_INDEX);
+               opcode = cpu_to_le16(HCI_MON_NEW_INDEX);
                break;
 
        case HCI_DEV_UNREG:
@@ -300,7 +332,41 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event)
                if (!skb)
                        return NULL;
 
-               opcode = __constant_cpu_to_le16(HCI_MON_DEL_INDEX);
+               opcode = cpu_to_le16(HCI_MON_DEL_INDEX);
+               break;
+
+       case HCI_DEV_SETUP:
+               if (hdev->manufacturer == 0xffff)
+                       return NULL;
+
+               /* fall through */
+
+       case HCI_DEV_UP:
+               skb = bt_skb_alloc(HCI_MON_INDEX_INFO_SIZE, GFP_ATOMIC);
+               if (!skb)
+                       return NULL;
+
+               ii = (void *)skb_put(skb, HCI_MON_INDEX_INFO_SIZE);
+               bacpy(&ii->bdaddr, &hdev->bdaddr);
+               ii->manufacturer = cpu_to_le16(hdev->manufacturer);
+
+               opcode = cpu_to_le16(HCI_MON_INDEX_INFO);
+               break;
+
+       case HCI_DEV_OPEN:
+               skb = bt_skb_alloc(0, GFP_ATOMIC);
+               if (!skb)
+                       return NULL;
+
+               opcode = cpu_to_le16(HCI_MON_OPEN_INDEX);
+               break;
+
+       case HCI_DEV_CLOSE:
+               skb = bt_skb_alloc(0, GFP_ATOMIC);
+               if (!skb)
+                       return NULL;
+
+               opcode = cpu_to_le16(HCI_MON_CLOSE_INDEX);
                break;
 
        default:
@@ -332,6 +398,28 @@ static void send_monitor_replay(struct sock *sk)
 
                if (sock_queue_rcv_skb(sk, skb))
                        kfree_skb(skb);
+
+               if (!test_bit(HCI_RUNNING, &hdev->flags))
+                       continue;
+
+               skb = create_monitor_event(hdev, HCI_DEV_OPEN);
+               if (!skb)
+                       continue;
+
+               if (sock_queue_rcv_skb(sk, skb))
+                       kfree_skb(skb);
+
+               if (test_bit(HCI_UP, &hdev->flags))
+                       skb = create_monitor_event(hdev, HCI_DEV_UP);
+               else if (hci_dev_test_flag(hdev, HCI_SETUP))
+                       skb = create_monitor_event(hdev, HCI_DEV_SETUP);
+               else
+                       skb = NULL;
+
+               if (skb) {
+                       if (sock_queue_rcv_skb(sk, skb))
+                               kfree_skb(skb);
+               }
        }
 
        read_unlock(&hci_dev_list_lock);
@@ -360,32 +448,34 @@ static void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
        __net_timestamp(skb);
 
        bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
-       skb->dev = (void *) hdev;
        hci_send_to_sock(hdev, skb);
        kfree_skb(skb);
 }
 
 void hci_sock_dev_event(struct hci_dev *hdev, int event)
 {
-       struct hci_ev_si_device ev;
-
        BT_DBG("hdev %s event %d", hdev->name, event);
 
-       /* Send event to monitor */
        if (atomic_read(&monitor_promisc)) {
                struct sk_buff *skb;
 
+               /* Send event to monitor */
                skb = create_monitor_event(hdev, event);
                if (skb) {
-                       send_monitor_event(skb);
+                       hci_send_to_channel(HCI_CHANNEL_MONITOR, skb,
+                                           HCI_SOCK_TRUSTED, NULL);
                        kfree_skb(skb);
                }
        }
 
-       /* Send event to sockets */
-       ev.event  = event;
-       ev.dev_id = hdev->id;
-       hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
+       if (event <= HCI_DEV_DOWN) {
+               struct hci_ev_si_device ev;
+
+               /* Send event to sockets */
+               ev.event  = event;
+               ev.dev_id = hdev->id;
+               hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
+       }
 
        if (event == HCI_DEV_UNREG) {
                struct sock *sk;
@@ -408,6 +498,56 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event)
        }
 }
 
+static struct hci_mgmt_chan *__hci_mgmt_chan_find(unsigned short channel)
+{
+       struct hci_mgmt_chan *c;
+
+       list_for_each_entry(c, &mgmt_chan_list, list) {
+               if (c->channel == channel)
+                       return c;
+       }
+
+       return NULL;
+}
+
+static struct hci_mgmt_chan *hci_mgmt_chan_find(unsigned short channel)
+{
+       struct hci_mgmt_chan *c;
+
+       mutex_lock(&mgmt_chan_list_lock);
+       c = __hci_mgmt_chan_find(channel);
+       mutex_unlock(&mgmt_chan_list_lock);
+
+       return c;
+}
+
+int hci_mgmt_chan_register(struct hci_mgmt_chan *c)
+{
+       if (c->channel < HCI_CHANNEL_CONTROL)
+               return -EINVAL;
+
+       mutex_lock(&mgmt_chan_list_lock);
+       if (__hci_mgmt_chan_find(c->channel)) {
+               mutex_unlock(&mgmt_chan_list_lock);
+               return -EALREADY;
+       }
+
+       list_add_tail(&c->list, &mgmt_chan_list);
+
+       mutex_unlock(&mgmt_chan_list_lock);
+
+       return 0;
+}
+EXPORT_SYMBOL(hci_mgmt_chan_register);
+
+void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c)
+{
+       mutex_lock(&mgmt_chan_list_lock);
+       list_del(&c->list);
+       mutex_unlock(&mgmt_chan_list_lock);
+}
+EXPORT_SYMBOL(hci_mgmt_chan_unregister);
+
 static int hci_sock_release(struct socket *sock)
 {
        struct sock *sk = sock->sk;
@@ -426,6 +566,21 @@ static int hci_sock_release(struct socket *sock)
        bt_sock_unlink(&hci_sk_list, sk);
 
        if (hdev) {
+               if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
+                       /* When releasing an user channel exclusive access,
+                        * call hci_dev_do_close directly instead of calling
+                        * hci_dev_close to ensure the exclusive access will
+                        * be released and the controller brought back down.
+                        *
+                        * The checking of HCI_AUTO_OFF is not needed in this
+                        * case since it will have been cleared already when
+                        * opening the user channel.
+                        */
+                       hci_dev_do_close(hdev);
+                       hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
+                       mgmt_index_added(hdev);
+               }
+
                atomic_dec(&hdev->promisc);
                hci_dev_put(hdev);
        }
@@ -449,7 +604,7 @@ static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg)
 
        hci_dev_lock(hdev);
 
-       err = hci_blacklist_add(hdev, &bdaddr, 0);
+       err = hci_bdaddr_list_add(&hdev->blacklist, &bdaddr, BDADDR_BREDR);
 
        hci_dev_unlock(hdev);
 
@@ -466,7 +621,7 @@ static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
 
        hci_dev_lock(hdev);
 
-       err = hci_blacklist_del(hdev, &bdaddr, 0);
+       err = hci_bdaddr_list_del(&hdev->blacklist, &bdaddr, BDADDR_BREDR);
 
        hci_dev_unlock(hdev);
 
@@ -482,20 +637,20 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
        if (!hdev)
                return -EBADFD;
 
+       if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
+               return -EBUSY;
+
+       if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
+               return -EOPNOTSUPP;
+
+       if (hdev->dev_type != HCI_BREDR)
+               return -EOPNOTSUPP;
+
        switch (cmd) {
        case HCISETRAW:
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
-
-               if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
-                       return -EPERM;
-
-               if (arg)
-                       set_bit(HCI_RAW, &hdev->flags);
-               else
-                       clear_bit(HCI_RAW, &hdev->flags);
-
-               return 0;
+               return -EOPNOTSUPP;
 
        case HCIGETCONNINFO:
                return hci_get_conn_info(hdev, (void __user *) arg);
@@ -512,23 +667,29 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
                return hci_sock_blacklist_del(hdev, (void __user *) arg);
-
-       default:
-               if (hdev->ioctl)
-                       return hdev->ioctl(hdev, cmd, arg);
-               return -EINVAL;
        }
+
+       return -ENOIOCTLCMD;
 }
 
 static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
                          unsigned long arg)
 {
-       struct sock *sk = sock->sk;
        void __user *argp = (void __user *) arg;
+       struct sock *sk = sock->sk;
        int err;
 
        BT_DBG("cmd %x arg %lx", cmd, arg);
 
+       lock_sock(sk);
+
+       if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
+               err = -EBADFD;
+               goto done;
+       }
+
+       release_sock(sk);
+
        switch (cmd) {
        case HCIGETDEVLIST:
                return hci_get_dev_list(argp);
@@ -573,13 +734,15 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
 
        case HCIINQUIRY:
                return hci_inquiry(argp);
-
-       default:
-               lock_sock(sk);
-               err = hci_sock_bound_ioctl(sk, cmd, arg);
-               release_sock(sk);
-               return err;
        }
+
+       lock_sock(sk);
+
+       err = hci_sock_bound_ioctl(sk, cmd, arg);
+
+done:
+       release_sock(sk);
+       return err;
 }
 
 static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
@@ -629,8 +792,13 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
                hci_pi(sk)->hdev = hdev;
                break;
 
-       case HCI_CHANNEL_CONTROL:
-               if (haddr.hci_dev != HCI_DEV_NONE) {
+       case HCI_CHANNEL_USER:
+               if (hci_pi(sk)->hdev) {
+                       err = -EALREADY;
+                       goto done;
+               }
+
+               if (haddr.hci_dev == HCI_DEV_NONE) {
                        err = -EINVAL;
                        goto done;
                }
@@ -640,6 +808,52 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
                        goto done;
                }
 
+               hdev = hci_dev_get(haddr.hci_dev);
+               if (!hdev) {
+                       err = -ENODEV;
+                       goto done;
+               }
+
+               if (test_bit(HCI_INIT, &hdev->flags) ||
+                   hci_dev_test_flag(hdev, HCI_SETUP) ||
+                   hci_dev_test_flag(hdev, HCI_CONFIG) ||
+                   (!hci_dev_test_flag(hdev, HCI_AUTO_OFF) &&
+                    test_bit(HCI_UP, &hdev->flags))) {
+                       err = -EBUSY;
+                       hci_dev_put(hdev);
+                       goto done;
+               }
+
+               if (hci_dev_test_and_set_flag(hdev, HCI_USER_CHANNEL)) {
+                       err = -EUSERS;
+                       hci_dev_put(hdev);
+                       goto done;
+               }
+
+               mgmt_index_removed(hdev);
+
+               err = hci_dev_open(hdev->id);
+               if (err) {
+                       if (err == -EALREADY) {
+                               /* In case the transport is already up and
+                                * running, clear the error here.
+                                *
+                                * This can happen when opening an user
+                                * channel and HCI_AUTO_OFF grace period
+                                * is still active.
+                                */
+                               err = 0;
+                       } else {
+                               hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
+                               mgmt_index_added(hdev);
+                               hci_dev_put(hdev);
+                               goto done;
+                       }
+               }
+
+               atomic_inc(&hdev->promisc);
+
+               hci_pi(sk)->hdev = hdev;
                break;
 
        case HCI_CHANNEL_MONITOR:
@@ -653,14 +867,51 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
                        goto done;
                }
 
+               /* The monitor interface is restricted to CAP_NET_RAW
+                * capabilities and with that implicitly trusted.
+                */
+               hci_sock_set_flag(sk, HCI_SOCK_TRUSTED);
+
                send_monitor_replay(sk);
 
                atomic_inc(&monitor_promisc);
                break;
 
        default:
-               err = -EINVAL;
-               goto done;
+               if (!hci_mgmt_chan_find(haddr.hci_channel)) {
+                       err = -EINVAL;
+                       goto done;
+               }
+
+               if (haddr.hci_dev != HCI_DEV_NONE) {
+                       err = -EINVAL;
+                       goto done;
+               }
+
+               /* Users with CAP_NET_ADMIN capabilities are allowed
+                * access to all management commands and events. For
+                * untrusted users the interface is restricted and
+                * also only untrusted events are sent.
+                */
+               if (capable(CAP_NET_ADMIN))
+                       hci_sock_set_flag(sk, HCI_SOCK_TRUSTED);
+
+               /* At the moment the index and unconfigured index events
+                * are enabled unconditionally. Setting them on each
+                * socket when binding keeps this functionality. They
+                * however might be cleared later and then sending of these
+                * events will be disabled, but that is then intentional.
+                *
+                * This also enables generic events that are safe to be
+                * received by untrusted users. Example for such events
+                * are changes to settings, class of device, name etc.
+                */
+               if (haddr.hci_channel == HCI_CHANNEL_CONTROL) {
+                       hci_sock_set_flag(sk, HCI_MGMT_INDEX_EVENTS);
+                       hci_sock_set_flag(sk, HCI_MGMT_UNCONF_INDEX_EVENTS);
+                       hci_sock_set_flag(sk, HCI_MGMT_GENERIC_EVENTS);
+               }
+               break;
        }
 
 
@@ -677,22 +928,30 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr,
 {
        struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
        struct sock *sk = sock->sk;
-       struct hci_dev *hdev = hci_pi(sk)->hdev;
+       struct hci_dev *hdev;
+       int err = 0;
 
        BT_DBG("sock %p sk %p", sock, sk);
 
-       if (!hdev)
-               return -EBADFD;
+       if (peer)
+               return -EOPNOTSUPP;
 
        lock_sock(sk);
 
+       hdev = hci_pi(sk)->hdev;
+       if (!hdev) {
+               err = -EBADFD;
+               goto done;
+       }
+
        *addr_len = sizeof(*haddr);
        haddr->hci_family = AF_BLUETOOTH;
        haddr->hci_dev    = hdev->id;
-       haddr->hci_channel= 0;
+       haddr->hci_channel= hci_pi(sk)->channel;
 
+done:
        release_sock(sk);
-       return 0;
+       return err;
 }
 
 static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg,
@@ -732,8 +991,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;
@@ -742,7 +1001,7 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 
        BT_DBG("sock %p, sk %p", sock, sk);
 
-       if (flags & (MSG_OOB))
+       if (flags & MSG_OOB)
                return -EOPNOTSUPP;
 
        if (sk->sk_state == BT_CLOSED)
@@ -752,8 +1011,6 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (!skb)
                return err;
 
-       msg->msg_namelen = 0;
-
        copied = skb->len;
        if (len < copied) {
                msg->msg_flags |= MSG_TRUNC;
@@ -761,16 +1018,20 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        }
 
        skb_reset_transport_header(skb);
-       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       err = skb_copy_datagram_msg(skb, 0, msg, copied);
 
        switch (hci_pi(sk)->channel) {
        case HCI_CHANNEL_RAW:
                hci_sock_cmsg(sk, msg, skb);
                break;
-       case HCI_CHANNEL_CONTROL:
+       case HCI_CHANNEL_USER:
        case HCI_CHANNEL_MONITOR:
                sock_recv_timestamp(msg, sk, skb);
                break;
+       default:
+               if (hci_mgmt_chan_find(hci_pi(sk)->channel))
+                       sock_recv_timestamp(msg, sk, skb);
+               break;
        }
 
        skb_free_datagram(sk, skb);
@@ -778,10 +1039,122 @@ 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_mgmt_cmd(struct hci_mgmt_chan *chan, struct sock *sk,
+                       struct msghdr *msg, size_t msglen)
+{
+       void *buf;
+       u8 *cp;
+       struct mgmt_hdr *hdr;
+       u16 opcode, index, len;
+       struct hci_dev *hdev = NULL;
+       const struct hci_mgmt_handler *handler;
+       bool var_len, no_hdev;
+       int err;
+
+       BT_DBG("got %zu bytes", msglen);
+
+       if (msglen < sizeof(*hdr))
+               return -EINVAL;
+
+       buf = kmalloc(msglen, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       if (memcpy_from_msg(buf, msg, msglen)) {
+               err = -EFAULT;
+               goto done;
+       }
+
+       hdr = buf;
+       opcode = __le16_to_cpu(hdr->opcode);
+       index = __le16_to_cpu(hdr->index);
+       len = __le16_to_cpu(hdr->len);
+
+       if (len != msglen - sizeof(*hdr)) {
+               err = -EINVAL;
+               goto done;
+       }
+
+       if (opcode >= chan->handler_count ||
+           chan->handlers[opcode].func == NULL) {
+               BT_DBG("Unknown op %u", opcode);
+               err = mgmt_cmd_status(sk, index, opcode,
+                                     MGMT_STATUS_UNKNOWN_COMMAND);
+               goto done;
+       }
+
+       handler = &chan->handlers[opcode];
+
+       if (!hci_sock_test_flag(sk, HCI_SOCK_TRUSTED) &&
+           !(handler->flags & HCI_MGMT_UNTRUSTED)) {
+               err = mgmt_cmd_status(sk, index, opcode,
+                                     MGMT_STATUS_PERMISSION_DENIED);
+               goto done;
+       }
+
+       if (index != MGMT_INDEX_NONE) {
+               hdev = hci_dev_get(index);
+               if (!hdev) {
+                       err = mgmt_cmd_status(sk, index, opcode,
+                                             MGMT_STATUS_INVALID_INDEX);
+                       goto done;
+               }
+
+               if (hci_dev_test_flag(hdev, HCI_SETUP) ||
+                   hci_dev_test_flag(hdev, HCI_CONFIG) ||
+                   hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
+                       err = mgmt_cmd_status(sk, index, opcode,
+                                             MGMT_STATUS_INVALID_INDEX);
+                       goto done;
+               }
+
+               if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
+                   !(handler->flags & HCI_MGMT_UNCONFIGURED)) {
+                       err = mgmt_cmd_status(sk, index, opcode,
+                                             MGMT_STATUS_INVALID_INDEX);
+                       goto done;
+               }
+       }
+
+       no_hdev = (handler->flags & HCI_MGMT_NO_HDEV);
+       if (no_hdev != !hdev) {
+               err = mgmt_cmd_status(sk, index, opcode,
+                                     MGMT_STATUS_INVALID_INDEX);
+               goto done;
+       }
+
+       var_len = (handler->flags & HCI_MGMT_VAR_LEN);
+       if ((var_len && len < handler->data_len) ||
+           (!var_len && len != handler->data_len)) {
+               err = mgmt_cmd_status(sk, index, opcode,
+                                     MGMT_STATUS_INVALID_PARAMS);
+               goto done;
+       }
+
+       if (hdev && chan->hdev_init)
+               chan->hdev_init(sk, hdev);
+
+       cp = buf + sizeof(*hdr);
+
+       err = handler->func(sk, hdev, cp, len);
+       if (err < 0)
+               goto done;
+
+       err = msglen;
+
+done:
+       if (hdev)
+               hci_dev_put(hdev);
+
+       kfree(buf);
+       return err;
+}
+
+static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
+                           size_t len)
 {
        struct sock *sk = sock->sk;
+       struct hci_mgmt_chan *chan;
        struct hci_dev *hdev;
        struct sk_buff *skb;
        int err;
@@ -801,15 +1174,20 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 
        switch (hci_pi(sk)->channel) {
        case HCI_CHANNEL_RAW:
+       case HCI_CHANNEL_USER:
                break;
-       case HCI_CHANNEL_CONTROL:
-               err = mgmt_control(sk, msg, len);
-               goto done;
        case HCI_CHANNEL_MONITOR:
                err = -EOPNOTSUPP;
                goto done;
        default:
-               err = -EINVAL;
+               mutex_lock(&mgmt_chan_list_lock);
+               chan = __hci_mgmt_chan_find(hci_pi(sk)->channel);
+               if (chan)
+                       err = hci_mgmt_cmd(chan, sk, msg, len);
+               else
+                       err = -EINVAL;
+
+               mutex_unlock(&mgmt_chan_list_lock);
                goto done;
        }
 
@@ -828,16 +1206,30 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
        if (!skb)
                goto done;
 
-       if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
+       if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
                err = -EFAULT;
                goto drop;
        }
 
        bt_cb(skb)->pkt_type = *((unsigned char *) skb->data);
        skb_pull(skb, 1);
-       skb->dev = (void *) hdev;
 
-       if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
+       if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
+               /* No permission check is needed for user channel
+                * since that gets enforced when binding the socket.
+                *
+                * However check that the packet type is valid.
+                */
+               if (bt_cb(skb)->pkt_type != HCI_COMMAND_PKT &&
+                   bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT &&
+                   bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) {
+                       err = -EINVAL;
+                       goto drop;
+               }
+
+               skb_queue_tail(&hdev->raw_q, skb);
+               queue_work(hdev->workqueue, &hdev->tx_work);
+       } else if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
                u16 opcode = get_unaligned_le16(skb->data);
                u16 ogf = hci_opcode_ogf(opcode);
                u16 ocf = hci_opcode_ocf(opcode);
@@ -850,14 +1242,14 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                        goto drop;
                }
 
-               if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) {
+               if (ogf == 0x3f) {
                        skb_queue_tail(&hdev->raw_q, skb);
                        queue_work(hdev->workqueue, &hdev->tx_work);
                } else {
-                       /* Stand-alone HCI commands must be flaged as
+                       /* Stand-alone HCI commands must be flagged as
                         * single-command requests.
                         */
-                       bt_cb(skb)->req.start = true;
+                       bt_cb(skb)->hci.req_start = true;
 
                        skb_queue_tail(&hdev->cmd_q, skb);
                        queue_work(hdev->workqueue, &hdev->cmd_work);
@@ -868,6 +1260,12 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                        goto drop;
                }
 
+               if (bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT &&
+                   bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) {
+                       err = -EINVAL;
+                       goto drop;
+               }
+
                skb_queue_tail(&hdev->raw_q, skb);
                queue_work(hdev->workqueue, &hdev->tx_work);
        }
@@ -895,7 +1293,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
        lock_sock(sk);
 
        if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
-               err = -EINVAL;
+               err = -EBADFD;
                goto done;
        }
 
@@ -981,7 +1379,7 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname,
        lock_sock(sk);
 
        if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
-               err = -EINVAL;
+               err = -EBADFD;
                goto done;
        }
 
@@ -1070,7 +1468,7 @@ static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
 
        sock->ops = &hci_sock_ops;
 
-       sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto);
+       sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, kern);
        if (!sk)
                return -ENOMEM;
 
@@ -1097,6 +1495,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;