diff options
author | Benjamin Berg <bberg@redhat.com> | 2021-12-03 15:59:02 +0100 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2021-12-03 10:41:59 -0800 |
commit | c97a747efc93f94a4ad6c707972dfbf8d774edf9 (patch) | |
tree | 9b720088b82a16bfcabb17ed8bb529091f7e1ba8 /drivers/bluetooth/btusb.c | |
parent | 2250abadd3508d6961f1aa56cf8cff59f0196cb8 (diff) | |
download | linux-c97a747efc93f94a4ad6c707972dfbf8d774edf9.tar.bz2 |
Bluetooth: btusb: Cancel sync commands for certain URB errors
Cancel sync commands when transmission of URBs fail. This is done for
both failures to send a command URB and also when the interrupt URB used
to retrieve a response fails.
This approach is sufficient to quickly deal with certain errors such as
a device being disconnected while synchronous commands are done during
initialization.
Signed-off-by: Benjamin Berg <bberg@redhat.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'drivers/bluetooth/btusb.c')
-rw-r--r-- | drivers/bluetooth/btusb.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index ab169fc673ea..d9067a8fad60 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -933,6 +933,8 @@ static void btusb_intr_complete(struct urb *urb) if (err != -EPERM && err != -ENODEV) bt_dev_err(hdev, "urb %p failed to resubmit (%d)", urb, -err); + if (err != -EPERM) + hci_cmd_sync_cancel(hdev, -err); usb_unanchor_urb(urb); } } @@ -976,6 +978,8 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags) if (err != -EPERM && err != -ENODEV) bt_dev_err(hdev, "urb %p submission failed (%d)", urb, -err); + if (err != -EPERM) + hci_cmd_sync_cancel(hdev, -err); usb_unanchor_urb(urb); } @@ -1331,10 +1335,13 @@ static void btusb_tx_complete(struct urb *urb) if (!test_bit(HCI_RUNNING, &hdev->flags)) goto done; - if (!urb->status) + if (!urb->status) { hdev->stat.byte_tx += urb->transfer_buffer_length; - else + } else { + if (hci_skb_pkt_type(skb) == HCI_COMMAND_PKT) + hci_cmd_sync_cancel(hdev, -urb->status); hdev->stat.err_tx++; + } done: spin_lock_irqsave(&data->txlock, flags); |