diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2014-02-28 02:33:44 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-02-28 02:41:07 -0500 |
commit | a3172b7eb4a2719711187cfca12097d2326e85a7 (patch) | |
tree | fc5191af513e40eac0ba1af3728fe7a0afe120be /net/bluetooth/mgmt.c | |
parent | c9910d0fb4fc2ede468b26d45a1d50c309897770 (diff) |
Bluetooth: Add timer to force power off
If some of the cleanup commands caused by mgmt_set_powered(off) never
complete we should still force the adapter to be powered down. This is
rather easy to do since hdev->power_off is already a delayed work
struct. This patch schedules this delayed work if at least one HCI
command was sent by the cleanup procedure.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r-- | net/bluetooth/mgmt.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 73b6ff817796..e7c87231b9ea 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -1031,8 +1031,10 @@ static void clean_up_hci_complete(struct hci_dev *hdev, u8 status) | |||
1031 | { | 1031 | { |
1032 | BT_DBG("%s status 0x%02x", hdev->name, status); | 1032 | BT_DBG("%s status 0x%02x", hdev->name, status); |
1033 | 1033 | ||
1034 | if (hci_conn_count(hdev) == 0) | 1034 | if (hci_conn_count(hdev) == 0) { |
1035 | cancel_delayed_work(&hdev->power_off); | ||
1035 | queue_work(hdev->req_workqueue, &hdev->power_off.work); | 1036 | queue_work(hdev->req_workqueue, &hdev->power_off.work); |
1037 | } | ||
1036 | } | 1038 | } |
1037 | 1039 | ||
1038 | static int clean_up_hci_state(struct hci_dev *hdev) | 1040 | static int clean_up_hci_state(struct hci_dev *hdev) |
@@ -1139,9 +1141,13 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data, | |||
1139 | } else { | 1141 | } else { |
1140 | /* Disconnect connections, stop scans, etc */ | 1142 | /* Disconnect connections, stop scans, etc */ |
1141 | err = clean_up_hci_state(hdev); | 1143 | err = clean_up_hci_state(hdev); |
1144 | if (!err) | ||
1145 | queue_delayed_work(hdev->req_workqueue, &hdev->power_off, | ||
1146 | HCI_POWER_OFF_TIMEOUT); | ||
1142 | 1147 | ||
1143 | /* ENODATA means there were no HCI commands queued */ | 1148 | /* ENODATA means there were no HCI commands queued */ |
1144 | if (err == -ENODATA) { | 1149 | if (err == -ENODATA) { |
1150 | cancel_delayed_work(&hdev->power_off); | ||
1145 | queue_work(hdev->req_workqueue, &hdev->power_off.work); | 1151 | queue_work(hdev->req_workqueue, &hdev->power_off.work); |
1146 | err = 0; | 1152 | err = 0; |
1147 | } | 1153 | } |
@@ -5147,8 +5153,10 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
5147 | /* The connection is still in hci_conn_hash so test for 1 | 5153 | /* The connection is still in hci_conn_hash so test for 1 |
5148 | * instead of 0 to know if this is the last one. | 5154 | * instead of 0 to know if this is the last one. |
5149 | */ | 5155 | */ |
5150 | if (!cp->val && hci_conn_count(hdev) == 1) | 5156 | if (!cp->val && hci_conn_count(hdev) == 1) { |
5157 | cancel_delayed_work(&hdev->power_off); | ||
5151 | queue_work(hdev->req_workqueue, &hdev->power_off.work); | 5158 | queue_work(hdev->req_workqueue, &hdev->power_off.work); |
5159 | } | ||
5152 | } | 5160 | } |
5153 | 5161 | ||
5154 | if (!mgmt_connected) | 5162 | if (!mgmt_connected) |
@@ -5217,8 +5225,10 @@ void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
5217 | /* The connection is still in hci_conn_hash so test for 1 | 5225 | /* The connection is still in hci_conn_hash so test for 1 |
5218 | * instead of 0 to know if this is the last one. | 5226 | * instead of 0 to know if this is the last one. |
5219 | */ | 5227 | */ |
5220 | if (!cp->val && hci_conn_count(hdev) == 1) | 5228 | if (!cp->val && hci_conn_count(hdev) == 1) { |
5229 | cancel_delayed_work(&hdev->power_off); | ||
5221 | queue_work(hdev->req_workqueue, &hdev->power_off.work); | 5230 | queue_work(hdev->req_workqueue, &hdev->power_off.work); |
5231 | } | ||
5222 | } | 5232 | } |
5223 | 5233 | ||
5224 | bacpy(&ev.addr.bdaddr, bdaddr); | 5234 | bacpy(&ev.addr.bdaddr, bdaddr); |