Commit b14202af authored by Jonas Dreßler's avatar Jonas Dreßler Committed by Luiz Augusto von Dentz

Bluetooth: Add new state HCI_POWERING_DOWN

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: default avatarJonas Dreßler <verdre@v0yd.nl>
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent fee054b7
...@@ -372,6 +372,7 @@ enum { ...@@ -372,6 +372,7 @@ enum {
HCI_SETUP, HCI_SETUP,
HCI_CONFIG, HCI_CONFIG,
HCI_DEBUGFS_CREATED, HCI_DEBUGFS_CREATED,
HCI_POWERING_DOWN,
HCI_AUTO_OFF, HCI_AUTO_OFF,
HCI_RFKILLED, HCI_RFKILLED,
HCI_MGMT, HCI_MGMT,
......
...@@ -5403,27 +5403,33 @@ static int hci_power_off_sync(struct hci_dev *hdev) ...@@ -5403,27 +5403,33 @@ static int hci_power_off_sync(struct hci_dev *hdev)
if (!test_bit(HCI_UP, &hdev->flags)) if (!test_bit(HCI_UP, &hdev->flags))
return 0; return 0;
hci_dev_set_flag(hdev, HCI_POWERING_DOWN);
if (test_bit(HCI_ISCAN, &hdev->flags) || if (test_bit(HCI_ISCAN, &hdev->flags) ||
test_bit(HCI_PSCAN, &hdev->flags)) { test_bit(HCI_PSCAN, &hdev->flags)) {
err = hci_write_scan_enable_sync(hdev, 0x00); err = hci_write_scan_enable_sync(hdev, 0x00);
if (err) if (err)
return err; goto out;
} }
err = hci_clear_adv_sync(hdev, NULL, false); err = hci_clear_adv_sync(hdev, NULL, false);
if (err) if (err)
return err; goto out;
err = hci_stop_discovery_sync(hdev); err = hci_stop_discovery_sync(hdev);
if (err) if (err)
return err; goto out;
/* Terminated due to Power Off */ /* Terminated due to Power Off */
err = hci_disconnect_all_sync(hdev, HCI_ERROR_REMOTE_POWER_OFF); err = hci_disconnect_all_sync(hdev, HCI_ERROR_REMOTE_POWER_OFF);
if (err) 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) int hci_set_powered_sync(struct hci_dev *hdev, u8 val)
......
...@@ -1390,6 +1390,14 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -1390,6 +1390,14 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
hci_dev_lock(hdev); 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)) { if (pending_find(MGMT_OP_SET_POWERED, hdev)) {
err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED, err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED,
MGMT_STATUS_BUSY); MGMT_STATUS_BUSY);
...@@ -9748,6 +9756,9 @@ bool mgmt_powering_down(struct hci_dev *hdev) ...@@ -9748,6 +9756,9 @@ bool mgmt_powering_down(struct hci_dev *hdev)
struct mgmt_pending_cmd *cmd; struct mgmt_pending_cmd *cmd;
struct mgmt_mode *cp; struct mgmt_mode *cp;
if (hci_dev_test_flag(hdev, HCI_POWERING_DOWN))
return true;
cmd = pending_find(MGMT_OP_SET_POWERED, hdev); cmd = pending_find(MGMT_OP_SET_POWERED, hdev);
if (!cmd) if (!cmd)
return false; return false;
...@@ -10055,6 +10066,9 @@ void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) ...@@ -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 /* If this is a HCI command related to powering on the
* HCI dev don't send any mgmt signals. * 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)) if (pending_find(MGMT_OP_SET_POWERED, hdev))
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment