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>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
static int ignore_dga;
static int ignore_csr;
static int ignore_dga;
static int ignore_csr;
int isoc_altsetting;
int suspend_count;
};
int isoc_altsetting;
int suspend_count;
};
return 0;
err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
return 0;
err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
+ if (err < 0)
+ goto failed;
+
+ err = btusb_submit_bulk_urb(hdev, GFP_KERNEL);
- 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);
BT_DBG("%s evt %d", hdev->name, 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);
+ if (hdev->conn_hash.sco_num != data->sco_num) {
+ data->sco_num = hdev->conn_hash.sco_num;
+ schedule_work(&data->work);
-
- schedule_work(&data->work);
}
static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting)
}
static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting)
}
if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
}
if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
- if (btusb_submit_bulk_urb(hdev, GFP_NOIO) < 0)
+ err = btusb_submit_bulk_urb(hdev, GFP_NOIO);
+ if (err < 0) {
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
btusb_submit_bulk_urb(hdev, GFP_NOIO);
}
btusb_submit_bulk_urb(hdev, GFP_NOIO);
}