2022-10-04 08:46:10

by Archie Pusaka

[permalink] [raw]
Subject: [PATCH] Bluetooth: btusb: Introduce generic USB reset

From: Archie Pusaka <[email protected]>

On cmd_timeout and there is no reset_gpio, reset the USB port as a
last resort.

Signed-off-by: Archie Pusaka <[email protected]>
Reviewed-by: Abhishek Pandit-Subedi <[email protected]>
Reviewed-by: Ying Hsu <[email protected]>

---

drivers/bluetooth/btusb.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 271963805a38..11040124ef79 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -696,6 +696,19 @@ struct btusb_data {
unsigned cmd_timeout_cnt;
};

+static void generic_usb_reset(struct hci_dev *hdev, struct btusb_data *data)
+{
+ int err;
+
+ bt_dev_err(hdev, "Resetting usb device.");
+ /* This is not an unbalanced PM reference since the device will reset */
+ err = usb_autopm_get_interface(data->intf);
+ if (!err)
+ usb_queue_reset_device(data->intf);
+ else
+ bt_dev_err(hdev, "Failed usb_autopm_get_interface: %d", err);
+}
+
static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
{
struct btusb_data *data = hci_get_drvdata(hdev);
@@ -705,7 +718,7 @@ static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
return;

if (!reset_gpio) {
- bt_dev_err(hdev, "No way to reset. Ignoring and continuing");
+ generic_usb_reset(hdev, data);
return;
}

@@ -736,7 +749,7 @@ static void btusb_rtl_cmd_timeout(struct hci_dev *hdev)
return;

if (!reset_gpio) {
- bt_dev_err(hdev, "No gpio to reset Realtek device, ignoring");
+ generic_usb_reset(hdev, data);
return;
}

@@ -761,7 +774,6 @@ static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
{
struct btusb_data *data = hci_get_drvdata(hdev);
struct gpio_desc *reset_gpio = data->reset_gpio;
- int err;

if (++data->cmd_timeout_cnt < 5)
return;
@@ -787,13 +799,7 @@ static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
return;
}

- bt_dev_err(hdev, "Multiple cmd timeouts seen. Resetting usb device.");
- /* This is not an unbalanced PM reference since the device will reset */
- err = usb_autopm_get_interface(data->intf);
- if (!err)
- usb_queue_reset_device(data->intf);
- else
- bt_dev_err(hdev, "Failed usb_autopm_get_interface with %d", err);
+ generic_usb_reset(hdev, data);
}

static inline void btusb_free_frags(struct btusb_data *data)
--
2.38.0.rc1.362.ged0d419d3c-goog


2022-10-04 09:28:49

by Paul Menzel

[permalink] [raw]
Subject: Re: [PATCH] Bluetooth: btusb: Introduce generic USB reset

Dear Archie,


Thank you for the patch.

Am 04.10.22 um 10:32 schrieb Archie Pusaka:
> From: Archie Pusaka <[email protected]>
>
> On cmd_timeout and there is no reset_gpio, reset the USB port as a

Maybe:

s/there is no/with no/g

> last resort.

Can you please document your test setup, and also mention that you
change the behavior of:

1. btusb_intel_cmd_timeout
2. btusb_rtl_cmd_timeout

[…]


Kind regards,

Paul


> Signed-off-by: Archie Pusaka <[email protected]>
> Reviewed-by: Abhishek Pandit-Subedi <[email protected]>
> Reviewed-by: Ying Hsu <[email protected]>
>
> ---
>
> drivers/bluetooth/btusb.c | 26 ++++++++++++++++----------
> 1 file changed, 16 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> index 271963805a38..11040124ef79 100644
> --- a/drivers/bluetooth/btusb.c
> +++ b/drivers/bluetooth/btusb.c
> @@ -696,6 +696,19 @@ struct btusb_data {
> unsigned cmd_timeout_cnt;
> };
>
> +static void generic_usb_reset(struct hci_dev *hdev, struct btusb_data *data)
> +{
> + int err;
> +
> + bt_dev_err(hdev, "Resetting usb device.");
> + /* This is not an unbalanced PM reference since the device will reset */
> + err = usb_autopm_get_interface(data->intf);
> + if (!err)
> + usb_queue_reset_device(data->intf);
> + else
> + bt_dev_err(hdev, "Failed usb_autopm_get_interface: %d", err);
> +}
> +
> static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
> {
> struct btusb_data *data = hci_get_drvdata(hdev);
> @@ -705,7 +718,7 @@ static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
> return;
>
> if (!reset_gpio) {
> - bt_dev_err(hdev, "No way to reset. Ignoring and continuing");
> + generic_usb_reset(hdev, data);
> return;
> }
>
> @@ -736,7 +749,7 @@ static void btusb_rtl_cmd_timeout(struct hci_dev *hdev)
> return;
>
> if (!reset_gpio) {
> - bt_dev_err(hdev, "No gpio to reset Realtek device, ignoring");
> + generic_usb_reset(hdev, data);
> return;
> }
>
> @@ -761,7 +774,6 @@ static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
> {
> struct btusb_data *data = hci_get_drvdata(hdev);
> struct gpio_desc *reset_gpio = data->reset_gpio;
> - int err;
>
> if (++data->cmd_timeout_cnt < 5)
> return;
> @@ -787,13 +799,7 @@ static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
> return;
> }
>
> - bt_dev_err(hdev, "Multiple cmd timeouts seen. Resetting usb device.");
> - /* This is not an unbalanced PM reference since the device will reset */
> - err = usb_autopm_get_interface(data->intf);
> - if (!err)
> - usb_queue_reset_device(data->intf);
> - else
> - bt_dev_err(hdev, "Failed usb_autopm_get_interface with %d", err);
> + generic_usb_reset(hdev, data);
> }
>
> static inline void btusb_free_frags(struct btusb_data *data)

2022-10-04 09:30:52

by bluez.test.bot

[permalink] [raw]
Subject: RE: Bluetooth: btusb: Introduce generic USB reset

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=682932

---Test result---

Test Summary:
CheckPatch PASS 1.62 seconds
GitLint PASS 0.74 seconds
SubjectPrefix PASS 0.63 seconds
BuildKernel PASS 42.93 seconds
BuildKernel32 PASS 39.54 seconds
Incremental Build with patchesPASS 55.77 seconds
TestRunner: Setup PASS 643.76 seconds
TestRunner: l2cap-tester PASS 19.50 seconds
TestRunner: iso-tester PASS 19.73 seconds
TestRunner: bnep-tester PASS 7.72 seconds
TestRunner: mgmt-tester PASS 124.90 seconds
TestRunner: rfcomm-tester PASS 12.48 seconds
TestRunner: sco-tester PASS 11.55 seconds
TestRunner: ioctl-tester PASS 13.47 seconds
TestRunner: smp-tester PASS 11.79 seconds
TestRunner: userchan-tester PASS 8.33 seconds



---
Regards,
Linux Bluetooth

2022-10-04 09:56:06

by Archie Pusaka

[permalink] [raw]
Subject: Re: [PATCH] Bluetooth: btusb: Introduce generic USB reset

Hi Paul,

On Tue, 4 Oct 2022 at 17:18, Paul Menzel <[email protected]> wrote:
>
> Dear Archie,
>
>
> Thank you for the patch.
>
> Am 04.10.22 um 10:32 schrieb Archie Pusaka:
> > From: Archie Pusaka <[email protected]>
> >
> > On cmd_timeout and there is no reset_gpio, reset the USB port as a
>
> Maybe:
>
> s/there is no/with no/g
>
> > last resort.
>
> Can you please document your test setup, and also mention that you
> change the behavior of:
>
> 1. btusb_intel_cmd_timeout
> 2. btusb_rtl_cmd_timeout
>
> […]
>
>
> Kind regards,
>
> Paul

Thanks for the input!
All done, uploaded v2. PTAL, thanks!

>
>
> > Signed-off-by: Archie Pusaka <[email protected]>
> > Reviewed-by: Abhishek Pandit-Subedi <[email protected]>
> > Reviewed-by: Ying Hsu <[email protected]>
> >
> > ---
> >
> > drivers/bluetooth/btusb.c | 26 ++++++++++++++++----------
> > 1 file changed, 16 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> > index 271963805a38..11040124ef79 100644
> > --- a/drivers/bluetooth/btusb.c
> > +++ b/drivers/bluetooth/btusb.c
> > @@ -696,6 +696,19 @@ struct btusb_data {
> > unsigned cmd_timeout_cnt;
> > };
> >
> > +static void generic_usb_reset(struct hci_dev *hdev, struct btusb_data *data)
> > +{
> > + int err;
> > +
> > + bt_dev_err(hdev, "Resetting usb device.");
> > + /* This is not an unbalanced PM reference since the device will reset */
> > + err = usb_autopm_get_interface(data->intf);
> > + if (!err)
> > + usb_queue_reset_device(data->intf);
> > + else
> > + bt_dev_err(hdev, "Failed usb_autopm_get_interface: %d", err);
> > +}
> > +
> > static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
> > {
> > struct btusb_data *data = hci_get_drvdata(hdev);
> > @@ -705,7 +718,7 @@ static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
> > return;
> >
> > if (!reset_gpio) {
> > - bt_dev_err(hdev, "No way to reset. Ignoring and continuing");
> > + generic_usb_reset(hdev, data);
> > return;
> > }
> >
> > @@ -736,7 +749,7 @@ static void btusb_rtl_cmd_timeout(struct hci_dev *hdev)
> > return;
> >
> > if (!reset_gpio) {
> > - bt_dev_err(hdev, "No gpio to reset Realtek device, ignoring");
> > + generic_usb_reset(hdev, data);
> > return;
> > }
> >
> > @@ -761,7 +774,6 @@ static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
> > {
> > struct btusb_data *data = hci_get_drvdata(hdev);
> > struct gpio_desc *reset_gpio = data->reset_gpio;
> > - int err;
> >
> > if (++data->cmd_timeout_cnt < 5)
> > return;
> > @@ -787,13 +799,7 @@ static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
> > return;
> > }
> >
> > - bt_dev_err(hdev, "Multiple cmd timeouts seen. Resetting usb device.");
> > - /* This is not an unbalanced PM reference since the device will reset */
> > - err = usb_autopm_get_interface(data->intf);
> > - if (!err)
> > - usb_queue_reset_device(data->intf);
> > - else
> > - bt_dev_err(hdev, "Failed usb_autopm_get_interface with %d", err);
> > + generic_usb_reset(hdev, data);
> > }
> >
> > static inline void btusb_free_frags(struct btusb_data *data)

Cheers,
Archie

2022-10-04 20:54:56

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH] Bluetooth: btusb: Introduce generic USB reset

Hi Archie,

On Tue, Oct 4, 2022 at 1:33 AM Archie Pusaka <[email protected]> wrote:
>
> From: Archie Pusaka <[email protected]>
>
> On cmd_timeout and there is no reset_gpio, reset the USB port as a
> last resort.
>
> Signed-off-by: Archie Pusaka <[email protected]>
> Reviewed-by: Abhishek Pandit-Subedi <[email protected]>
> Reviewed-by: Ying Hsu <[email protected]>
>
> ---
>
> drivers/bluetooth/btusb.c | 26 ++++++++++++++++----------
> 1 file changed, 16 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> index 271963805a38..11040124ef79 100644
> --- a/drivers/bluetooth/btusb.c
> +++ b/drivers/bluetooth/btusb.c
> @@ -696,6 +696,19 @@ struct btusb_data {
> unsigned cmd_timeout_cnt;
> };
>
> +static void generic_usb_reset(struct hci_dev *hdev, struct btusb_data *data)
> +{
> + int err;
> +
> + bt_dev_err(hdev, "Resetting usb device.");
> + /* This is not an unbalanced PM reference since the device will reset */
> + err = usb_autopm_get_interface(data->intf);
> + if (!err)
> + usb_queue_reset_device(data->intf);
> + else
> + bt_dev_err(hdev, "Failed usb_autopm_get_interface: %d", err);

Lets just have one line printed if it fails:

err = usb_autopm_get_interface(data->intf);
if (err) {
bt_dev_err(hdev, "Failed usb_autopm_get_interface: %d", err);
return;
}

bt_dev_err(hdev, "Resetting usb device.");
usb_queue_reset_device(data->intf);

> +}
> +
> static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
> {
> struct btusb_data *data = hci_get_drvdata(hdev);
> @@ -705,7 +718,7 @@ static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
> return;
>
> if (!reset_gpio) {
> - bt_dev_err(hdev, "No way to reset. Ignoring and continuing");
> + generic_usb_reset(hdev, data);

Lets call it btusb_reset since this is specific for the data->intf,
btw is this safe, or perhaps we want to refactor this to have it
callback based so each vendor can add it own specific hdev->reset
callback hardware reset with btusb_reset serving as default callback?
Also the logic of btusb_intel_cmd_timeout should probably be put
inside btintel.c and I don't think we need the gpio_desc reference to
be inside the btusb_data since we can call gpiod_get_optional during
the reset phase and immediately do gpiod_put after done using it.

> return;
> }
>
> @@ -736,7 +749,7 @@ static void btusb_rtl_cmd_timeout(struct hci_dev *hdev)
> return;
>
> if (!reset_gpio) {
> - bt_dev_err(hdev, "No gpio to reset Realtek device, ignoring");
> + generic_usb_reset(hdev, data);
> return;
> }
>
> @@ -761,7 +774,6 @@ static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
> {
> struct btusb_data *data = hci_get_drvdata(hdev);
> struct gpio_desc *reset_gpio = data->reset_gpio;
> - int err;
>
> if (++data->cmd_timeout_cnt < 5)
> return;
> @@ -787,13 +799,7 @@ static void btusb_qca_cmd_timeout(struct hci_dev *hdev)
> return;
> }
>
> - bt_dev_err(hdev, "Multiple cmd timeouts seen. Resetting usb device.");
> - /* This is not an unbalanced PM reference since the device will reset */
> - err = usb_autopm_get_interface(data->intf);
> - if (!err)
> - usb_queue_reset_device(data->intf);
> - else
> - bt_dev_err(hdev, "Failed usb_autopm_get_interface with %d", err);
> + generic_usb_reset(hdev, data);
> }
>
> static inline void btusb_free_frags(struct btusb_data *data)
> --
> 2.38.0.rc1.362.ged0d419d3c-goog
>


--
Luiz Augusto von Dentz