drivers/bluetooth/btusb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
If USB autosuspend occurs while discovery is active, the ongoing
HCI operation may not complete successfully. On some devices, this
can leave discovery.state stuck in DISCOVERY_FINDING.
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
---
drivers/bluetooth/btusb.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index ded09e94d296..565e276be3b2 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -4469,10 +4469,11 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
BT_DBG("intf %p", intf);
- /* Don't auto-suspend if there are connections; external suspend calls
- * shall never fail.
+ /* Don't auto-suspend if there are connections or discovery in
+ * progress; external suspend calls shall never fail.
*/
- if (PMSG_IS_AUTO(message) && hci_conn_count(data->hdev))
+ if (PMSG_IS_AUTO(message) &&
+ (hci_conn_count(data->hdev) || hci_discovery_active(data->hdev)))
return -EBUSY;
if (data->suspend_count++)
--
2.25.1
在 2026/1/8 10:06, Linmao Li 写道:
> If USB autosuspend occurs while discovery is active, the ongoing
> HCI operation may not complete successfully. On some devices, this
> can leave discovery.state stuck in DISCOVERY_FINDING.
>
> Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
> ---
> drivers/bluetooth/btusb.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> index ded09e94d296..565e276be3b2 100644
> --- a/drivers/bluetooth/btusb.c
> +++ b/drivers/bluetooth/btusb.c
> @@ -4469,10 +4469,11 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
>
> BT_DBG("intf %p", intf);
>
> - /* Don't auto-suspend if there are connections; external suspend calls
> - * shall never fail.
> + /* Don't auto-suspend if there are connections or discovery in
> + * progress; external suspend calls shall never fail.
> */
> - if (PMSG_IS_AUTO(message) && hci_conn_count(data->hdev))
> + if (PMSG_IS_AUTO(message) &&
> + (hci_conn_count(data->hdev) || hci_discovery_active(data->hdev)))
> return -EBUSY;
>
> if (data->suspend_count++)
Hi Luiz,
I found that hci_discovery_active() is not exported, so btusb as a
module cannot use it:
ERROR: modpost: "hci_discovery_active" [drivers/bluetooth/btusb.ko]
undefined!
Should I send a separate patch to export hci_discovery_active(), or
revert to v1 using test_bit(HCI_INQUIRY) and hci_dev_test_flag(HCI_LE_SCAN)?
Best regards,
Linmao
Hi Linmao,
On Wed, Jan 7, 2026 at 9:53 PM Linmao Li <lilinmao@kylinos.cn> wrote:
>
> 在 2026/1/8 10:06, Linmao Li 写道:
>
> > If USB autosuspend occurs while discovery is active, the ongoing
> > HCI operation may not complete successfully. On some devices, this
> > can leave discovery.state stuck in DISCOVERY_FINDING.
> >
> > Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
> > ---
> > drivers/bluetooth/btusb.c | 7 ++++---
> > 1 file changed, 4 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> > index ded09e94d296..565e276be3b2 100644
> > --- a/drivers/bluetooth/btusb.c
> > +++ b/drivers/bluetooth/btusb.c
> > @@ -4469,10 +4469,11 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
> >
> > BT_DBG("intf %p", intf);
> >
> > - /* Don't auto-suspend if there are connections; external suspend calls
> > - * shall never fail.
> > + /* Don't auto-suspend if there are connections or discovery in
> > + * progress; external suspend calls shall never fail.
> > */
> > - if (PMSG_IS_AUTO(message) && hci_conn_count(data->hdev))
> > + if (PMSG_IS_AUTO(message) &&
> > + (hci_conn_count(data->hdev) || hci_discovery_active(data->hdev)))
> > return -EBUSY;
> >
> > if (data->suspend_count++)
> Hi Luiz,
>
> I found that hci_discovery_active() is not exported, so btusb as a
> module cannot use it:
>
> ERROR: modpost: "hci_discovery_active" [drivers/bluetooth/btusb.ko]
> undefined!
>
> Should I send a separate patch to export hci_discovery_active(), or
> revert to v1 using test_bit(HCI_INQUIRY) and hci_dev_test_flag(HCI_LE_SCAN)?
Just add a patch exporting it.
--
Luiz Augusto von Dentz
This series fixes an issue where USB autosuspend during discovery
can leave the HCI state machine in an inconsistent state.
v3:
- Export hci_discovery_active() in patch 1
- Use hci_discovery_active() in btusb in patch 2
v2:
- Use hci_discovery_active() instead of testing individual bits
(Luiz Augusto von Dentz)
Linmao Li (2):
Bluetooth: hci_core: Export hci_discovery_active
Bluetooth: btusb: Reject autosuspend if discovery is active
drivers/bluetooth/btusb.c | 7 ++++---
net/bluetooth/hci_core.c | 1 +
2 files changed, 5 insertions(+), 3 deletions(-)
--
2.25.1
Export hci_discovery_active() so it can be used by bluetooth
drivers built as modules.
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
---
net/bluetooth/hci_core.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8ccec73dce45..b069607b145b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -117,6 +117,7 @@ bool hci_discovery_active(struct hci_dev *hdev)
return false;
}
}
+EXPORT_SYMBOL(hci_discovery_active);
void hci_discovery_set_state(struct hci_dev *hdev, int state)
{
--
2.25.1
If USB autosuspend occurs while discovery is active, the ongoing
HCI operation may not complete successfully. On some devices, this
can leave discovery.state stuck in DISCOVERY_FINDING.
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
---
drivers/bluetooth/btusb.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index ded09e94d296..565e276be3b2 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -4469,10 +4469,11 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
BT_DBG("intf %p", intf);
- /* Don't auto-suspend if there are connections; external suspend calls
- * shall never fail.
+ /* Don't auto-suspend if there are connections or discovery in
+ * progress; external suspend calls shall never fail.
*/
- if (PMSG_IS_AUTO(message) && hci_conn_count(data->hdev))
+ if (PMSG_IS_AUTO(message) &&
+ (hci_conn_count(data->hdev) || hci_discovery_active(data->hdev)))
return -EBUSY;
if (data->suspend_count++)
--
2.25.1
© 2016 - 2026 Red Hat, Inc.