aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2013-10-11 09:44:12 -0700
committerJohan Hedberg <johan.hedberg@intel.com>2013-10-11 19:48:11 +0200
commit3a6afbd2171a1e92c22d1a9eb54adf1474d938f1 (patch)
tree560d79b246129fe8a386af774bec7cfefe71c6c9
parent14b49b9a49f0d80ef9a3ce7991b373f93016f5e4 (diff)
downloadwl12xx-3a6afbd2171a1e92c22d1a9eb54adf1474d938f1.tar.gz
Bluetooth: Fix endless loop with HCI_QUIRK_RESET_ON_CLOSE
Really early versions of the Bluetooth specification were unclear with the behavior of HCI Reset for USB devices. They assumed that also an USB reset needs to be issued. Later Bluetooth specifications cleared this out and it is safe to call HCI Reset without affecting the transport. For old devices that misbehave, the HCI_QUIRK_RESET_ON_CLOSE quirk was introduced to postpone the HCI Reset until the device was no longer in use. One of these devices is the Digianswer BPA-105 Bluetooth Protocol Analyzer. The only problem now is that with the quirk set, the HCI Reset is also executed at the end of the setup phase. So the controller gets configured and then it disconnects from the USB bus, connects again, gets configured and of course disconnects again. This game goes on forever. For devices that need HCI_QUIRK_RESET_ON_CLOSE it is important that the HCI Reset is not executed after the setup phase. In specific when HCI_AUTO_OFF is set, do not call HCI Reset when closing the device. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
-rw-r--r--net/bluetooth/hci_core.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 1910dc2d33cf70..8f70a35b4d0eb2 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1378,6 +1378,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
skb_queue_purge(&hdev->cmd_q);
atomic_set(&hdev->cmd_cnt, 1);
if (!test_bit(HCI_RAW, &hdev->flags) &&
+ !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
set_bit(HCI_INIT, &hdev->flags);
__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);