From: Benjamin Berg <bberg@xxxxxxxxxx> Call the TX failure handler when transmission of URBs fail. This is done both for failures to send an 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@xxxxxxxxxx> --- drivers/bluetooth/btusb.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 75c83768c257..0c4fe89c6573 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -924,6 +924,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_tx_error(hdev, -err); usb_unanchor_urb(urb); } } @@ -967,6 +969,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_tx_error(hdev, -err); usb_unanchor_urb(urb); } @@ -1322,10 +1326,12 @@ 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 { + hci_tx_error(hdev, -urb->status); hdev->stat.err_tx++; + } done: spin_lock_irqsave(&data->txlock, flags); @@ -1348,10 +1354,12 @@ static void btusb_isoc_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 { + hci_tx_error(hdev, -urb->status); hdev->stat.err_tx++; + } done: kfree(urb->setup_packet); -- 2.31.1