Bluetooth: Add support setup stage internal notification event
authorMarcel Holtmann <marcel@holtmann.org>
Tue, 20 Oct 2015 00:30:47 +0000 (02:30 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Tue, 20 Oct 2015 22:49:23 +0000 (00:49 +0200)
Before the vendor specific setup stage is triggered call back into the
core to trigger an internal notification event. That event is used to
send an index update to the monitor interface. With that specific event
it is possible to update userspace with manufacturer information before
any HCI command has been executed. This is useful for early stage
debugging of vendor specific initialization sequences.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
include/net/bluetooth/hci.h
net/bluetooth/hci_core.c
net/bluetooth/hci_sock.c

index b59971c5cb71c2659ae278f0742cc3b28d745eaa..0205b80cc90b2d6d569c1ce517266fcb96ff2bf7 100644 (file)
@@ -46,6 +46,7 @@
 #define HCI_DEV_RESUME                 6
 #define HCI_DEV_OPEN                   7
 #define HCI_DEV_CLOSE                  8
+#define HCI_DEV_SETUP                  9
 
 /* HCI notify events */
 #define HCI_NOTIFY_CONN_ADD            1
index f33268004195be390da829a21699ec3850350c2d..ac5cb251f9fb5037a5e34f31f71afdca01b646eb 100644 (file)
@@ -1461,6 +1461,8 @@ static int hci_dev_do_open(struct hci_dev *hdev)
        set_bit(HCI_INIT, &hdev->flags);
 
        if (hci_dev_test_flag(hdev, HCI_SETUP)) {
+               hci_sock_dev_event(hdev, HCI_DEV_SETUP);
+
                if (hdev->setup)
                        ret = hdev->setup(hdev);
 
index 1f4665a124f663a79150d45521948a5eb69f9e49..b9327e8c2d34ee43b84ab7b23bf9132088560a09 100644 (file)
@@ -335,6 +335,12 @@ static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event)
                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)
@@ -403,15 +409,17 @@ static void send_monitor_replay(struct sock *sk)
                if (sock_queue_rcv_skb(sk, skb))
                        kfree_skb(skb);
 
-               if (!test_bit(HCI_UP, &hdev->flags))
-                       continue;
-
-               skb = create_monitor_event(hdev, HCI_DEV_UP);
-               if (!skb)
-                       continue;
+               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 (sock_queue_rcv_skb(sk, skb))
-                       kfree_skb(skb);
+               if (skb) {
+                       if (sock_queue_rcv_skb(sk, skb))
+                               kfree_skb(skb);
+               }
        }
 
        read_unlock(&hci_dev_list_lock);