Re: [PATCH] Bluetooth: hci_sync: Split hci_dev_open_sync

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Marcel,

On Tue, Apr 5, 2022 at 2:52 PM Luiz Augusto von Dentz
<luiz.dentz@xxxxxxxxx> wrote:
>
> From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>
>
> This splits hci_dev_open_sync so each stage is handle by its own
> function so it is easier to identify each stage.
>
> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>
> ---
>  net/bluetooth/hci_sync.c | 255 ++++++++++++++++++++++-----------------
>  1 file changed, 141 insertions(+), 114 deletions(-)
>
> diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
> index 5610ec1242d6..2d3b9adbd215 100644
> --- a/net/bluetooth/hci_sync.c
> +++ b/net/bluetooth/hci_sync.c
> @@ -3849,9 +3849,148 @@ static const struct {
>                          "advertised, but not supported.")
>  };
>
> -int hci_dev_open_sync(struct hci_dev *hdev)
> +/* This function handles hdev setup stage:
> + *
> + * Calls hdev->setup
> + * Setup address if HCI_QUIRK_USE_BDADDR_PROPERTY is set.
> + */
> +static int hci_dev_setup_sync(struct hci_dev *hdev)
>  {
>         int ret = 0;
> +       bool invalid_bdaddr;
> +       size_t i;
> +
> +       if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
> +           !test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks))
> +               return 0;
> +
> +       bt_dev_dbg(hdev, "");
> +
> +       hci_sock_dev_event(hdev, HCI_DEV_SETUP);
> +
> +       if (hdev->setup)
> +               ret = hdev->setup(hdev);
> +
> +       for (i = 0; i < ARRAY_SIZE(hci_broken_table); i++) {
> +               if (test_bit(hci_broken_table[i].quirk, &hdev->quirks))
> +                       bt_dev_warn(hdev, "%s", hci_broken_table[i].desc);
> +       }
> +
> +       /* The transport driver can set the quirk to mark the
> +        * BD_ADDR invalid before creating the HCI device or in
> +        * its setup callback.
> +        */
> +       invalid_bdaddr = test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
> +
> +       if (!ret) {
> +               if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) {
> +                       if (!bacmp(&hdev->public_addr, BDADDR_ANY))
> +                               hci_dev_get_bd_addr_from_property(hdev);
> +
> +                       if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
> +                           hdev->set_bdaddr) {
> +                               ret = hdev->set_bdaddr(hdev,
> +                                                      &hdev->public_addr);
> +
> +                               /* If setting of the BD_ADDR from the device
> +                                * property succeeds, then treat the address
> +                                * as valid even if the invalid BD_ADDR
> +                                * quirk indicates otherwise.
> +                                */
> +                               if (!ret)
> +                                       invalid_bdaddr = false;
> +                       }
> +               }
> +       }
> +
> +       /* The transport driver can set these quirks before
> +        * creating the HCI device or in its setup callback.
> +        *
> +        * For the invalid BD_ADDR quirk it is possible that
> +        * it becomes a valid address if the bootloader does
> +        * provide it (see above).
> +        *
> +        * In case any of them is set, the controller has to
> +        * start up as unconfigured.
> +        */
> +       if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
> +           invalid_bdaddr)
> +               hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
> +
> +       /* For an unconfigured controller it is required to
> +        * read at least the version information provided by
> +        * the Read Local Version Information command.
> +        *
> +        * If the set_bdaddr driver callback is provided, then
> +        * also the original Bluetooth public device address
> +        * will be read using the Read BD Address command.
> +        */
> +       if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
> +               return hci_unconf_init_sync(hdev);
> +
> +       return ret;
> +}
> +
> +/* This function handles hdev init stage:
> + *
> + * Calls hci_dev_setup_sync to perform setup stage
> + * Calls hci_init_sync to perform HCI command init sequence
> + */
> +static int hci_dev_init_sync(struct hci_dev *hdev)
> +{
> +       int ret;
> +
> +       bt_dev_dbg(hdev, "");
> +
> +       atomic_set(&hdev->cmd_cnt, 1);
> +       set_bit(HCI_INIT, &hdev->flags);
> +
> +       ret = hci_dev_setup_sync(hdev);
> +
> +       if (hci_dev_test_flag(hdev, HCI_CONFIG)) {
> +               /* If public address change is configured, ensure that
> +                * the address gets programmed. If the driver does not
> +                * support changing the public address, fail the power
> +                * on procedure.
> +                */
> +               if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
> +                   hdev->set_bdaddr)
> +                       ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
> +               else
> +                       ret = -EADDRNOTAVAIL;
> +       }
> +
> +       if (!ret) {
> +               if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
> +                   !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
> +                       ret = hci_init_sync(hdev);
> +                       if (!ret && hdev->post_init)
> +                               ret = hdev->post_init(hdev);
> +               }
> +       }
> +
> +       /* If the HCI Reset command is clearing all diagnostic settings,
> +        * then they need to be reprogrammed after the init procedure
> +        * completed.
> +        */
> +       if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
> +           !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
> +           hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag)
> +               ret = hdev->set_diag(hdev, true);
> +
> +       if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
> +               msft_do_open(hdev);
> +               aosp_do_open(hdev);
> +       }
> +
> +       clear_bit(HCI_INIT, &hdev->flags);
> +
> +       return ret;
> +}
> +
> +int hci_dev_open_sync(struct hci_dev *hdev)
> +{
> +       int ret;
>
>         bt_dev_dbg(hdev, "");
>
> @@ -3904,119 +4043,7 @@ int hci_dev_open_sync(struct hci_dev *hdev)
>         set_bit(HCI_RUNNING, &hdev->flags);
>         hci_sock_dev_event(hdev, HCI_DEV_OPEN);
>
> -       atomic_set(&hdev->cmd_cnt, 1);
> -       set_bit(HCI_INIT, &hdev->flags);
> -
> -       if (hci_dev_test_flag(hdev, HCI_SETUP) ||
> -           test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) {
> -               bool invalid_bdaddr;
> -               size_t i;
> -
> -               hci_sock_dev_event(hdev, HCI_DEV_SETUP);
> -
> -               if (hdev->setup)
> -                       ret = hdev->setup(hdev);
> -
> -               for (i = 0; i < ARRAY_SIZE(hci_broken_table); i++) {
> -                       if (test_bit(hci_broken_table[i].quirk, &hdev->quirks))
> -                               bt_dev_warn(hdev, "%s",
> -                                           hci_broken_table[i].desc);
> -               }
> -
> -               /* The transport driver can set the quirk to mark the
> -                * BD_ADDR invalid before creating the HCI device or in
> -                * its setup callback.
> -                */
> -               invalid_bdaddr = test_bit(HCI_QUIRK_INVALID_BDADDR,
> -                                         &hdev->quirks);
> -
> -               if (ret)
> -                       goto setup_failed;
> -
> -               if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) {
> -                       if (!bacmp(&hdev->public_addr, BDADDR_ANY))
> -                               hci_dev_get_bd_addr_from_property(hdev);
> -
> -                       if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
> -                           hdev->set_bdaddr) {
> -                               ret = hdev->set_bdaddr(hdev,
> -                                                      &hdev->public_addr);
> -
> -                               /* If setting of the BD_ADDR from the device
> -                                * property succeeds, then treat the address
> -                                * as valid even if the invalid BD_ADDR
> -                                * quirk indicates otherwise.
> -                                */
> -                               if (!ret)
> -                                       invalid_bdaddr = false;
> -                       }
> -               }
> -
> -setup_failed:
> -               /* The transport driver can set these quirks before
> -                * creating the HCI device or in its setup callback.
> -                *
> -                * For the invalid BD_ADDR quirk it is possible that
> -                * it becomes a valid address if the bootloader does
> -                * provide it (see above).
> -                *
> -                * In case any of them is set, the controller has to
> -                * start up as unconfigured.
> -                */
> -               if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
> -                   invalid_bdaddr)
> -                       hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
> -
> -               /* For an unconfigured controller it is required to
> -                * read at least the version information provided by
> -                * the Read Local Version Information command.
> -                *
> -                * If the set_bdaddr driver callback is provided, then
> -                * also the original Bluetooth public device address
> -                * will be read using the Read BD Address command.
> -                */
> -               if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
> -                       ret = hci_unconf_init_sync(hdev);
> -       }
> -
> -       if (hci_dev_test_flag(hdev, HCI_CONFIG)) {
> -               /* If public address change is configured, ensure that
> -                * the address gets programmed. If the driver does not
> -                * support changing the public address, fail the power
> -                * on procedure.
> -                */
> -               if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
> -                   hdev->set_bdaddr)
> -                       ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
> -               else
> -                       ret = -EADDRNOTAVAIL;
> -       }
> -
> -       if (!ret) {
> -               if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
> -                   !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
> -                       ret = hci_init_sync(hdev);
> -                       if (!ret && hdev->post_init)
> -                               ret = hdev->post_init(hdev);
> -               }
> -       }
> -
> -       /* If the HCI Reset command is clearing all diagnostic settings,
> -        * then they need to be reprogrammed after the init procedure
> -        * completed.
> -        */
> -       if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
> -           !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
> -           hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag)
> -               ret = hdev->set_diag(hdev, true);
> -
> -       if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
> -               msft_do_open(hdev);
> -               aosp_do_open(hdev);
> -       }
> -
> -       clear_bit(HCI_INIT, &hdev->flags);
> -
> +       ret = hci_dev_init_sync(hdev);
>         if (!ret) {
>                 hci_dev_hold(hdev);
>                 hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
> --
> 2.35.1

Any feedback on these changes?

-- 
Luiz Augusto von Dentz



[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux