aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-02-04 11:41:38 -0500
committerMarcel Holtmann <marcel@holtmann.org>2009-02-27 00:14:36 -0500
commit43c2e57f94c15744495fee564610aa24602b3824 (patch)
tree529c710c2bccd2825f1bcc5d3c248a852aac92f4 /drivers
parent6e1031a40029492c10509e8c3dcac9b611438ccb (diff)
Bluetooth: Submit bulk URBs along with interrupt URBs
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@holtmann.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bluetooth/btusb.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index b5fbda6d490a..e70c57ee4221 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -35,7 +35,7 @@
35#include <net/bluetooth/bluetooth.h> 35#include <net/bluetooth/bluetooth.h>
36#include <net/bluetooth/hci_core.h> 36#include <net/bluetooth/hci_core.h>
37 37
38#define VERSION "0.4" 38#define VERSION "0.5"
39 39
40static int ignore_dga; 40static int ignore_dga;
41static int ignore_csr; 41static int ignore_csr;
@@ -171,6 +171,7 @@ struct btusb_data {
171 171
172 __u8 cmdreq_type; 172 __u8 cmdreq_type;
173 173
174 unsigned int sco_num;
174 int isoc_altsetting; 175 int isoc_altsetting;
175 int suspend_count; 176 int suspend_count;
176}; 177};
@@ -496,11 +497,23 @@ static int btusb_open(struct hci_dev *hdev)
496 return 0; 497 return 0;
497 498
498 err = btusb_submit_intr_urb(hdev, GFP_KERNEL); 499 err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
500 if (err < 0)
501 goto failed;
502
503 err = btusb_submit_bulk_urb(hdev, GFP_KERNEL);
499 if (err < 0) { 504 if (err < 0) {
500 clear_bit(BTUSB_INTR_RUNNING, &data->flags); 505 usb_kill_anchored_urbs(&data->intr_anchor);
501 clear_bit(HCI_RUNNING, &hdev->flags); 506 goto failed;
502 } 507 }
503 508
509 set_bit(BTUSB_BULK_RUNNING, &data->flags);
510 btusb_submit_bulk_urb(hdev, GFP_KERNEL);
511
512 return 0;
513
514failed:
515 clear_bit(BTUSB_INTR_RUNNING, &data->flags);
516 clear_bit(HCI_RUNNING, &hdev->flags);
504 return err; 517 return err;
505} 518}
506 519
@@ -655,19 +668,10 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
655 668
656 BT_DBG("%s evt %d", hdev->name, evt); 669 BT_DBG("%s evt %d", hdev->name, evt);
657 670
658 if (hdev->conn_hash.acl_num > 0) { 671 if (hdev->conn_hash.sco_num != data->sco_num) {
659 if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) { 672 data->sco_num = hdev->conn_hash.sco_num;
660 if (btusb_submit_bulk_urb(hdev, GFP_ATOMIC) < 0) 673 schedule_work(&data->work);
661 clear_bit(BTUSB_BULK_RUNNING, &data->flags);
662 else
663 btusb_submit_bulk_urb(hdev, GFP_ATOMIC);
664 }
665 } else {
666 clear_bit(BTUSB_BULK_RUNNING, &data->flags);
667 usb_unlink_anchored_urbs(&data->bulk_anchor);
668 } 674 }
669
670 schedule_work(&data->work);
671} 675}
672 676
673static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting) 677static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting)
@@ -982,9 +986,11 @@ static int btusb_resume(struct usb_interface *intf)
982 } 986 }
983 987
984 if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) { 988 if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
985 if (btusb_submit_bulk_urb(hdev, GFP_NOIO) < 0) 989 err = btusb_submit_bulk_urb(hdev, GFP_NOIO);
990 if (err < 0) {
986 clear_bit(BTUSB_BULK_RUNNING, &data->flags); 991 clear_bit(BTUSB_BULK_RUNNING, &data->flags);
987 else 992 return err;
993 } else
988 btusb_submit_bulk_urb(hdev, GFP_NOIO); 994 btusb_submit_bulk_urb(hdev, GFP_NOIO);
989 } 995 }
990 996