Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+23 -17
+23 -17
drivers/bluetooth/btusb.c
··· 35 35 #include <net/bluetooth/bluetooth.h> 36 36 #include <net/bluetooth/hci_core.h> 37 37 38 - #define VERSION "0.4" 38 + #define VERSION "0.5" 39 39 40 40 static int ignore_dga; 41 41 static int ignore_csr; ··· 171 171 172 172 __u8 cmdreq_type; 173 173 174 + unsigned int sco_num; 174 175 int isoc_altsetting; 175 176 int suspend_count; 176 177 }; ··· 497 496 return 0; 498 497 499 498 err = btusb_submit_intr_urb(hdev, GFP_KERNEL); 499 + if (err < 0) 500 + goto failed; 501 + 502 + err = btusb_submit_bulk_urb(hdev, GFP_KERNEL); 500 503 if (err < 0) { 501 - clear_bit(BTUSB_INTR_RUNNING, &data->flags); 502 - clear_bit(HCI_RUNNING, &hdev->flags); 504 + usb_kill_anchored_urbs(&data->intr_anchor); 505 + goto failed; 503 506 } 504 507 508 + set_bit(BTUSB_BULK_RUNNING, &data->flags); 509 + btusb_submit_bulk_urb(hdev, GFP_KERNEL); 510 + 511 + return 0; 512 + 513 + failed: 514 + clear_bit(BTUSB_INTR_RUNNING, &data->flags); 515 + clear_bit(HCI_RUNNING, &hdev->flags); 505 516 return err; 506 517 } 507 518 ··· 668 655 669 656 BT_DBG("%s evt %d", hdev->name, evt); 670 657 671 - if (hdev->conn_hash.acl_num > 0) { 672 - if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) { 673 - if (btusb_submit_bulk_urb(hdev, GFP_ATOMIC) < 0) 674 - clear_bit(BTUSB_BULK_RUNNING, &data->flags); 675 - else 676 - btusb_submit_bulk_urb(hdev, GFP_ATOMIC); 677 - } 678 - } else { 679 - clear_bit(BTUSB_BULK_RUNNING, &data->flags); 680 - usb_unlink_anchored_urbs(&data->bulk_anchor); 658 + if (hdev->conn_hash.sco_num != data->sco_num) { 659 + data->sco_num = hdev->conn_hash.sco_num; 660 + schedule_work(&data->work); 681 661 } 682 - 683 - schedule_work(&data->work); 684 662 } 685 663 686 664 static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting) ··· 986 982 } 987 983 988 984 if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) { 989 - if (btusb_submit_bulk_urb(hdev, GFP_NOIO) < 0) 985 + err = btusb_submit_bulk_urb(hdev, GFP_NOIO); 986 + if (err < 0) { 990 987 clear_bit(BTUSB_BULK_RUNNING, &data->flags); 991 - else 988 + return err; 989 + } else 992 990 btusb_submit_bulk_urb(hdev, GFP_NOIO); 993 991 } 994 992