[PATCH] bluetooth: retry reset for devices that fail

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From af61f0663f095599003290b13ad6fadee1d4fb25 Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oliver@xxxxxxxxxx>
Date: Tue, 6 Jul 2010 08:08:42 +0200
Subject: [PATCH] bluetooth: retry reset for devices that fail

Some devices fail to reset properly at the first attempt to reset
them under unknown circumstances. Failures can be identified by
an invalid btaddr. Retry in those cases.

Signed-off-by: Oliver Neukum <oneukum@xxxxxxx>
---
 net/bluetooth/hci_core.c |   48 ++++++++++++++++++++++++++-------------------
 1 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 2f768de..c47f73d 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -180,11 +180,17 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
 	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
 }
 
+static int verify_valid_bdaddr(struct hci_dev *hdev)
+{
+	return !bacmp(&hdev->bdaddr, BDADDR_ANY);
+}
+
 static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
 {
 	struct sk_buff *skb;
 	__le16 param;
 	__u8 flt_type;
+	int retries = 4;
 
 	BT_DBG("%s %ld", hdev->name, opt);
 
@@ -202,33 +208,35 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
 
 	/* Mandatory initialization */
 
-	/* Reset */
-	if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks))
-			hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
+	do {
+		/* Reset */
+		if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks))
+				hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
 
-	/* Read Local Supported Features */
-	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
+		/* Read Local Supported Features */
+		hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
 
-	/* Read Local Version */
-	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
+		/* Read Local Version */
+		hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
 
-	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
-	hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
+		/* Read Buffer Size (ACL mtu, max pkt, etc.) */
+		hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
 
 #if 0
-	/* Host buffer size */
-	{
-		struct hci_cp_host_buffer_size cp;
-		cp.acl_mtu = cpu_to_le16(HCI_MAX_ACL_SIZE);
-		cp.sco_mtu = HCI_MAX_SCO_SIZE;
-		cp.acl_max_pkt = cpu_to_le16(0xffff);
-		cp.sco_max_pkt = cpu_to_le16(0xffff);
-		hci_send_cmd(hdev, HCI_OP_HOST_BUFFER_SIZE, sizeof(cp), &cp);
-	}
+		/* Host buffer size */
+		{
+			struct hci_cp_host_buffer_size cp;
+			cp.acl_mtu = cpu_to_le16(HCI_MAX_ACL_SIZE);
+			cp.sco_mtu = HCI_MAX_SCO_SIZE;
+			cp.acl_max_pkt = cpu_to_le16(0xffff);
+			cp.sco_max_pkt = cpu_to_le16(0xffff);
+			hci_send_cmd(hdev, HCI_OP_HOST_BUFFER_SIZE, sizeof(cp), &cp);
+		}
 #endif
 
-	/* Read BD Address */
-	hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
+		/* Read BD Address */
+		hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
+	} while(!verify_valid_bdaddr(hdev) && retries--);
 
 	/* Read Class of Device */
 	hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux