Skip to content

Commit

Permalink
Bluetooth: Add new state HCI_POWERING_DOWN
Browse files Browse the repository at this point in the history
Add a new state HCI_POWERING_DOWN that indicates that the device is
currently powering down, this will be useful for the next commit.

Signed-off-by: Jonas Dreßler <verdre@v0yd.nl>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
  • Loading branch information
Jonas Dreßler authored and Luiz Augusto von Dentz committed Mar 6, 2024
1 parent fee054b commit b14202a
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 5 deletions.
1 change: 1 addition & 0 deletions include/net/bluetooth/hci.h
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ enum {
HCI_SETUP,
HCI_CONFIG,
HCI_DEBUGFS_CREATED,
HCI_POWERING_DOWN,
HCI_AUTO_OFF,
HCI_RFKILLED,
HCI_MGMT,
Expand Down
16 changes: 11 additions & 5 deletions net/bluetooth/hci_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -5403,27 +5403,33 @@ static int hci_power_off_sync(struct hci_dev *hdev)
if (!test_bit(HCI_UP, &hdev->flags))
return 0;

hci_dev_set_flag(hdev, HCI_POWERING_DOWN);

if (test_bit(HCI_ISCAN, &hdev->flags) ||
test_bit(HCI_PSCAN, &hdev->flags)) {
err = hci_write_scan_enable_sync(hdev, 0x00);
if (err)
return err;
goto out;
}

err = hci_clear_adv_sync(hdev, NULL, false);
if (err)
return err;
goto out;

err = hci_stop_discovery_sync(hdev);
if (err)
return err;
goto out;

/* Terminated due to Power Off */
err = hci_disconnect_all_sync(hdev, HCI_ERROR_REMOTE_POWER_OFF);
if (err)
return err;
goto out;

err = hci_dev_close_sync(hdev);

return hci_dev_close_sync(hdev);
out:
hci_dev_clear_flag(hdev, HCI_POWERING_DOWN);
return err;
}

int hci_set_powered_sync(struct hci_dev *hdev, u8 val)
Expand Down
14 changes: 14 additions & 0 deletions net/bluetooth/mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1390,6 +1390,14 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,

hci_dev_lock(hdev);

if (!cp->val) {
if (hci_dev_test_flag(hdev, HCI_POWERING_DOWN)) {
err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED,
MGMT_STATUS_BUSY);
goto failed;
}
}

if (pending_find(MGMT_OP_SET_POWERED, hdev)) {
err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED,
MGMT_STATUS_BUSY);
Expand Down Expand Up @@ -9748,6 +9756,9 @@ bool mgmt_powering_down(struct hci_dev *hdev)
struct mgmt_pending_cmd *cmd;
struct mgmt_mode *cp;

if (hci_dev_test_flag(hdev, HCI_POWERING_DOWN))
return true;

cmd = pending_find(MGMT_OP_SET_POWERED, hdev);
if (!cmd)
return false;
Expand Down Expand Up @@ -10055,6 +10066,9 @@ void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status)
/* If this is a HCI command related to powering on the
* HCI dev don't send any mgmt signals.
*/
if (hci_dev_test_flag(hdev, HCI_POWERING_DOWN))
return;

if (pending_find(MGMT_OP_SET_POWERED, hdev))
return;
}
Expand Down

0 comments on commit b14202a

Please sign in to comment.