aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Holland <samuel@sholland.org>2020-08-01 11:29:56 -0500
committerMarcel Holtmann <marcel@holtmann.org>2020-08-02 20:01:27 +0200
commit3b799254cf6f481460719023d7a18f46651e5e7f (patch)
tree5238dbbf0c635d33860202cb58f3fbefb3307731
parentBluetooth: hci_h5: Remove ignored flag HCI_UART_RESET_ON_INIT (diff)
downloadlinux-dev-3b799254cf6f481460719023d7a18f46651e5e7f.tar.xz
linux-dev-3b799254cf6f481460719023d7a18f46651e5e7f.zip
Bluetooth: hci_uart: Cancel init work before unregistering
If hci_uart_tty_close() or hci_uart_unregister_device() is called while hu->init_ready is scheduled, hci_register_dev() could be called after the hci_uart is torn down. Avoid this by ensuring the work is complete or canceled before checking the HCI_UART_REGISTERED flag. Fixes: 9f2aee848fe6 ("Bluetooth: Add delayed init sequence support for UART controllers") Signed-off-by: Samuel Holland <samuel@sholland.org> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--drivers/bluetooth/hci_ldisc.c1
-rw-r--r--drivers/bluetooth/hci_serdev.c2
2 files changed, 3 insertions, 0 deletions
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 85a30fb9177b..f83d67eafc9f 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -538,6 +538,7 @@ static void hci_uart_tty_close(struct tty_struct *tty)
clear_bit(HCI_UART_PROTO_READY, &hu->flags);
percpu_up_write(&hu->proto_lock);
+ cancel_work_sync(&hu->init_ready);
cancel_work_sync(&hu->write_work);
if (hdev) {
diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c
index 7b233312e723..3977bba485c2 100644
--- a/drivers/bluetooth/hci_serdev.c
+++ b/drivers/bluetooth/hci_serdev.c
@@ -355,6 +355,8 @@ void hci_uart_unregister_device(struct hci_uart *hu)
struct hci_dev *hdev = hu->hdev;
clear_bit(HCI_UART_PROTO_READY, &hu->flags);
+
+ cancel_work_sync(&hu->init_ready);
if (test_bit(HCI_UART_REGISTERED, &hu->flags))
hci_unregister_dev(hdev);
hci_free_dev(hdev);