[PATCH] Bluetooth: Submit bulk URBs along with interrupt URBs

Stefan Bader stefan.bader at canonical.com
Mon Mar 30 09:18:44 UTC 2009


From: Marcel Holtmann <marcel at holtmann.org>

Bug: #268502

commit 43c2e57f94c15744495fee564610aa24602b3824 upstream

Submitting the bulk URBs for ACL data transfers only on demand has no
real benefit compared to just submit them when a Bluetooth device gets
opened. So when submitting the interrupt URBs for HCI events, just
submit the bulk URBs, too.

This solves a problem with some Bluetooth USB dongles that has been
reported over the last few month. These devices require that the bulk
URBs are actually present. These devices are really broken, but there
is nothing we can do about it.

Signed-off-by: Marcel Holtmann <marcel at holtmann.org>
Signed-off-by: Brian Rogers <brian at xyzw.org>
Signed-off-by: Stefan Bader <stefan.bader at canonical.com>
---
 drivers/bluetooth/btusb.c |   35 ++++++++++++++++++++---------------
 1 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 3b0545b..d4ec9a9 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -41,6 +41,7 @@
 #define BT_DBG(D...)
 #endif
 
+/* Backported patch would update version from 0.4 to 0.5 */
 #define VERSION "0.3"
 
 static int ignore_dga;
@@ -200,6 +201,7 @@ struct btusb_data {
 	struct usb_endpoint_descriptor *isoc_tx_ep;
 	struct usb_endpoint_descriptor *isoc_rx_ep;
 
+	unsigned int sco_num;
 	int isoc_altsetting;
 };
 
@@ -524,11 +526,23 @@ static int btusb_open(struct hci_dev *hdev)
 		return 0;
 
 	err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
+	if (err < 0)
+		goto failed;
+
+	err = btusb_submit_bulk_urb(hdev, GFP_KERNEL);
 	if (err < 0) {
-		clear_bit(BTUSB_INTR_RUNNING, &data->flags);
-		clear_bit(HCI_RUNNING, &hdev->flags);
+		usb_kill_anchored_urbs(&data->intr_anchor);
+		goto failed;
 	}
 
+	set_bit(BTUSB_BULK_RUNNING, &data->flags);
+	btusb_submit_bulk_urb(hdev, GFP_KERNEL);
+
+	return 0
+
+failed:
+	clear_bit(BTUSB_INTR_RUNNING, &data->flags);
+	clear_bit(HCI_RUNNING, &hdev->flags);
 	return err;
 }
 
@@ -683,19 +697,10 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
 
 	BT_DBG("%s evt %d", hdev->name, evt);
 
-	if (hdev->conn_hash.acl_num > 0) {
-		if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
-			if (btusb_submit_bulk_urb(hdev, GFP_ATOMIC) < 0)
-				clear_bit(BTUSB_BULK_RUNNING, &data->flags);
-			else
-				btusb_submit_bulk_urb(hdev, GFP_ATOMIC);
-		}
-	} else {
-		clear_bit(BTUSB_BULK_RUNNING, &data->flags);
-		usb_unlink_anchored_urbs(&data->bulk_anchor);
-	}
-
-	schedule_work(&data->work);
+	if (hdev->conn_hash.sco_num != data->sco_num) {
+		data->sco_num = hdev->conn_hash.sco_num;
+		schedule_work(&data->work);
+        }
 }
 
 static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting)
-- 
1.5.4.3





More information about the kernel-team mailing list