Re: [PATCH v2] Bluetooth: MGMT: Fix discovery stuck after a failed Stop Discovery
From: Luiz Augusto von Dentz
Date: Tue Oct 27 2026 - 14:00:26 EST
Hi Kevin,
On Tue, Oct 27, 2026 at 1:27 PM Kevin Dewald <kevin@xxxxxxxxxxxxx> wrote:
>
> Stop Discovery moves the discovery to DISCOVERY_STOPPING, and
> stop_discovery_complete() only moves it on to DISCOVERY_STOPPED when
> stopping succeeded. When it fails, for example because LE Set Scan
> Enable times out, nothing else moves the discovery out of
> DISCOVERY_STOPPING, as the LE scan timeout was cancelled before the
> scan was disabled. Until the controller is powered off, every Start
> Discovery then fails with Busy, and hci_update_passive_scan_sync()
> skips background scanning, so devices set to auto-connect are not
> connected anymore.
>
> Move the discovery to DISCOVERY_STOPPED also when stopping it failed,
> as start_discovery_complete() does when starting fails. This sends
> Discovering (disabled), and the passive scan update disables the scan
> again if it is still enabled.
>
> Fixes: 0e05bba6f6f8 ("Bluetooth: Update stop_discovery to use HCI request")
> Assisted-by: Claude:claude-opus-5.5
> Signed-off-by: Kevin Dewald <kevin@xxxxxxxxxxxxx>
> ---
> Changes in v2:
> - Add the missing Signed-off-by. v1 went out three times without it,
> sorry for the noise.
> - v1: https://lore.kernel.org/linux-bluetooth/20261027171913.82628-1-kevin@xxxxxxxxxxxxx/
>
> Reproduced in test-runner with a new mgmt-tester case, "Stop Discovery -
> Scan Disable Failed 1", in which the emulator answers LE Set Scan Enable
> (disable) with Unspecified Error: without this patch no Discovering
> (disabled) event is sent, the scan is left enabled and Start Discovery
> fails with Busy one second later (3 of 3 runs); with it the scan is
> disabled again and Start Discovery succeeds (3 of 3). Freezing the
> emulated controller while bluetoothd stops discovering gives the same
> result through the HCI command timeout. The other kernel testers pass as
> before. Only tested with the emulator, not with real controllers. I can
> send the mgmt-tester case to BlueZ if you want it.
Ok, but this is not the expected behavior, I can agree if the error
indicates the scan has already stopped; otherwise, we should probably
fail and restore the discovery state won't be, or starting it again
may fail because the controller state in sync with the discovery
state.
> hci_pause_discovery_sync() has the same pattern on suspend, which I have
> not reproduced.
>
> net/bluetooth/mgmt.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> index 3cb4f9ece8..06595175d9 100644
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -6322,8 +6322,11 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err)
> cmd->param, 1);
> mgmt_pending_free(cmd);
>
> - if (!err)
> - hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
> + /* Leave DISCOVERY_STOPPING also when stopping failed, since nothing
> + * else moves the discovery out of it: Start Discovery would keep
> + * failing with Busy and passive scanning would not be resumed.
> + */
> + hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
> }
>
> static int stop_discovery_sync(struct hci_dev *hdev, void *data)
>
> base-commit: 47d4d9f67e92d56ef3965f2727f9c98a5a611368
> --
> 2.53.0
>
--
Luiz Augusto von Dentz