Skip to content

Commit

Permalink
Bluetooth: hci_core: Cancel sync command if sending a frame failed
Browse files Browse the repository at this point in the history
If sending a frame failed any sync command associated with it will never
be completed. As such, cancel any such command immediately to avoid
timing out.

Signed-off-by: Benjamin Berg <bberg@redhat.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  • Loading branch information
Benjamin Berg authored and Luiz Augusto von Dentz committed Dec 3, 2021
1 parent 914b08b commit 2250aba
Showing 1 changed file with 11 additions and 3 deletions.
14 changes: 11 additions & 3 deletions net/bluetooth/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2906,7 +2906,7 @@ int hci_unregister_cb(struct hci_cb *cb)
}
EXPORT_SYMBOL(hci_unregister_cb);

static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
static int hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
int err;

Expand All @@ -2929,14 +2929,17 @@ static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)

if (!test_bit(HCI_RUNNING, &hdev->flags)) {
kfree_skb(skb);
return;
return -EINVAL;
}

err = hdev->send(hdev, skb);
if (err < 0) {
bt_dev_err(hdev, "sending frame failed (%d)", err);
kfree_skb(skb);
return err;
}

return 0;
}

/* Send HCI command */
Expand Down Expand Up @@ -3843,10 +3846,15 @@ static void hci_cmd_work(struct work_struct *work)

hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
if (hdev->sent_cmd) {
int res;
if (hci_req_status_pend(hdev))
hci_dev_set_flag(hdev, HCI_CMD_PENDING);
atomic_dec(&hdev->cmd_cnt);
hci_send_frame(hdev, skb);

res = hci_send_frame(hdev, skb);
if (res < 0)
hci_cmd_sync_cancel(hdev, -res);

if (test_bit(HCI_RESET, &hdev->flags))
cancel_delayed_work(&hdev->cmd_timer);
else
Expand Down

0 comments on commit 2250aba

Please sign in to comment.