diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2014-07-05 10:48:02 +0200 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2014-07-05 15:48:14 +0300 |
commit | 0ebca7d6819a24b7518d518f89597cf7c7854094 (patch) | |
tree | 1f45c77c90a4ec55a4430d966b45c025ddfdbc98 /net | |
parent | 45296acd91b14d32d7d023a08baaf285a0ea2193 (diff) | |
download | linux-0ebca7d6819a24b7518d518f89597cf7c7854094.tar.gz linux-0ebca7d6819a24b7518d518f89597cf7c7854094.tar.bz2 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')
-rw-r--r-- | net/bluetooth/hci_core.c | 40 |
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 |