Commit 2250abad authored by Benjamin Berg's avatar Benjamin Berg Committed by Luiz Augusto von Dentz
Browse files

Bluetooth: hci_core: Cancel sync command if sending a frame failed



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: default avatarBenjamin Berg <bberg@redhat.com>
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 914b08b3
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -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;

@@ -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 */
@@ -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