]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/bluetooth/hci_core.c
Bluetooth: Add support setup stage internal notification event
[mirror_ubuntu-bionic-kernel.git] / net / bluetooth / hci_core.c
index d2b3dd32d6cf1c6469b9fc728c62a625ac1c9b67..ac5cb251f9fb5037a5e34f31f71afdca01b646eb 100644 (file)
@@ -162,6 +162,16 @@ static ssize_t vendor_diag_write(struct file *file, const char __user *user_buf,
        if (strtobool(buf, &enable))
                return -EINVAL;
 
+       /* When the diagnostic flags are not persistent and the transport
+        * is not active, then there is no need for the vendor callback.
+        *
+        * Instead just store the desired value. If needed the setting
+        * will be programmed when the controller gets powered on.
+        */
+       if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
+           !test_bit(HCI_RUNNING, &hdev->flags))
+               goto done;
+
        hci_req_lock(hdev);
        err = hdev->set_diag(hdev, enable);
        hci_req_unlock(hdev);
@@ -169,6 +179,7 @@ static ssize_t vendor_diag_write(struct file *file, const char __user *user_buf,
        if (err < 0)
                return err;
 
+done:
        if (enable)
                hci_dev_set_flag(hdev, HCI_VENDOR_DIAG);
        else
@@ -1450,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);
 
@@ -1494,6 +1507,14 @@ static int hci_dev_do_open(struct hci_dev *hdev)
                        ret = __hci_init(hdev);
        }
 
+       /* If the HCI Reset command is clearing all diagnostic settings,
+        * then they need to be reprogrammed after the init procedure
+        * completed.
+        */
+       if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
+           hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag)
+               ret = hdev->set_diag(hdev, true);
+
        clear_bit(HCI_INIT, &hdev->flags);
 
        if (!ret) {
@@ -2930,13 +2951,6 @@ struct hci_conn_params *hci_explicit_connect_lookup(struct hci_dev *hdev,
                        return param;
        }
 
-       list_for_each_entry(param, &hdev->pend_le_reports, action) {
-               if (bacmp(&param->addr, addr) == 0 &&
-                   param->addr_type == addr_type &&
-                   param->explicit_connect)
-                       return param;
-       }
-
        return NULL;
 }
 
@@ -3562,14 +3576,15 @@ EXPORT_SYMBOL(hci_recv_frame);
 /* Receive diagnostic message from HCI drivers */
 int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb)
 {
+       /* Mark as diagnostic packet */
+       bt_cb(skb)->pkt_type = HCI_DIAG_PKT;
+
        /* Time stamp */
        __net_timestamp(skb);
 
-       /* Mark as diagnostic packet and send to monitor */
-       bt_cb(skb)->pkt_type = HCI_DIAG_PKT;
-       hci_send_to_monitor(hdev, skb);
+       skb_queue_tail(&hdev->rx_q, skb);
+       queue_work(hdev->workqueue, &hdev->rx_work);
 
-       kfree_skb(skb);
        return 0;
 }
 EXPORT_SYMBOL(hci_recv_diag);