summaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_core.c
diff options
context:
space:
mode:
authorMarcel Holtmann2014-07-05 10:48:02 +0200
committerJohan Hedberg2014-07-05 14:48:14 +0200
commit0ebca7d6819a24b7518d518f89597cf7c7854094 (patch)
tree1f45c77c90a4ec55a4430d966b45c025ddfdbc98 /net/bluetooth/hci_core.c
parentBluetooth: Use a more simpler style for HCI event callbacks (diff)
downloadkernel-qcow2-linux-0ebca7d6819a24b7518d518f89597cf7c7854094.tar.gz
kernel-qcow2-linux-0ebca7d6819a24b7518d518f89597cf7c7854094.tar.xz
kernel-qcow2-linux-0ebca7d6819a24b7518d518f89597cf7c7854094.zip
Bluetooth: Run special init procedure for unconfigured controllers
For an unconfigured controller it is required to read at least the local version information. If the set_bdaddr driver callback is provideded, then also the local Bluetooth address will be read. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth/hci_core.c')
-rw-r--r--net/bluetooth/hci_core.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b29f3938e6b3..f996e2c4815c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1791,6 +1791,35 @@ static int __hci_init(struct hci_dev *hdev)
return 0;
}
+static void hci_init0_req(struct hci_request *req, unsigned long opt)
+{
+ struct hci_dev *hdev = req->hdev;
+
+ BT_DBG("%s %ld", hdev->name, opt);
+
+ /* Reset */
+ if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks))
+ hci_reset_req(req, 0);
+
+ /* Read Local Version */
+ hci_req_add(req, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
+
+ /* Read BD Address */
+ if (hdev->set_bdaddr)
+ hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
+}
+
+static int __hci_unconf_init(struct hci_dev *hdev)
+{
+ int err;
+
+ err = __hci_req_sync(hdev, hci_init0_req, 0, HCI_INIT_TIMEOUT);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
static void hci_scan_req(struct hci_request *req, unsigned long opt)
{
__u8 scan = opt;
@@ -2259,6 +2288,17 @@ static int hci_dev_do_open(struct hci_dev *hdev)
if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks))
set_bit(HCI_UNCONFIGURED, &hdev->dev_flags);
+
+ /* For an unconfigured controller it is required to
+ * read at least the version information provided by
+ * the Read Local Version Information command.
+ *
+ * If the set_bdaddr driver callback is provided, then
+ * also the original Bluetooth public device address
+ * will be read using the Read BD Address command.
+ */
+ if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags))
+ ret = __hci_unconf_init(hdev);
}
/* If public address change is configured, ensure that the