diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2014-07-08 09:05:06 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-07-08 09:09:46 -0400 |
commit | 23a48093b53999f8539144db1d9567964a84655c (patch) | |
tree | 2e440c55e8d1f962d1371ca53141a3b5c14025de /net/bluetooth/mgmt.c | |
parent | 34722277045f84d0ee618865d02030a44b1ed257 (diff) |
Bluetooth: Fix setting STOPPING state for discovery
If any of the HCI commands from the hci_stop_discovery function were
successfully sent we need to set the discovery state to STOPPING. The
Stop Discovery code was already handling this, but the code in
clean_up_hci_state was not. This patch updates the hci_stop_discovery to
return a bool to indicate whether it queued any commands and the
clean_up_hci_state() function respectively to look at the return value
and call hci_discovery_set_state() if necessary.
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 | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 944e6463fd61..a4232bc237f3 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -1251,7 +1251,7 @@ static void clean_up_hci_complete(struct hci_dev *hdev, u8 status) | |||
1251 | } | 1251 | } |
1252 | } | 1252 | } |
1253 | 1253 | ||
1254 | static void hci_stop_discovery(struct hci_request *req) | 1254 | static bool hci_stop_discovery(struct hci_request *req) |
1255 | { | 1255 | { |
1256 | struct hci_dev *hdev = req->hdev; | 1256 | struct hci_dev *hdev = req->hdev; |
1257 | struct hci_cp_remote_name_req_cancel cp; | 1257 | struct hci_cp_remote_name_req_cancel cp; |
@@ -1266,32 +1266,39 @@ static void hci_stop_discovery(struct hci_request *req) | |||
1266 | hci_req_add_le_scan_disable(req); | 1266 | hci_req_add_le_scan_disable(req); |
1267 | } | 1267 | } |
1268 | 1268 | ||
1269 | break; | 1269 | return true; |
1270 | 1270 | ||
1271 | case DISCOVERY_RESOLVING: | 1271 | case DISCOVERY_RESOLVING: |
1272 | e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, | 1272 | e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, |
1273 | NAME_PENDING); | 1273 | NAME_PENDING); |
1274 | if (!e) | 1274 | if (!e) |
1275 | return; | 1275 | break; |
1276 | 1276 | ||
1277 | bacpy(&cp.bdaddr, &e->data.bdaddr); | 1277 | bacpy(&cp.bdaddr, &e->data.bdaddr); |
1278 | hci_req_add(req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp), | 1278 | hci_req_add(req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp), |
1279 | &cp); | 1279 | &cp); |
1280 | 1280 | ||
1281 | break; | 1281 | return true; |
1282 | 1282 | ||
1283 | default: | 1283 | default: |
1284 | /* Passive scanning */ | 1284 | /* Passive scanning */ |
1285 | if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) | 1285 | if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) { |
1286 | hci_req_add_le_scan_disable(req); | 1286 | hci_req_add_le_scan_disable(req); |
1287 | return true; | ||
1288 | } | ||
1289 | |||
1287 | break; | 1290 | break; |
1288 | } | 1291 | } |
1292 | |||
1293 | return false; | ||
1289 | } | 1294 | } |
1290 | 1295 | ||
1291 | static int clean_up_hci_state(struct hci_dev *hdev) | 1296 | static int clean_up_hci_state(struct hci_dev *hdev) |
1292 | { | 1297 | { |
1293 | struct hci_request req; | 1298 | struct hci_request req; |
1294 | struct hci_conn *conn; | 1299 | struct hci_conn *conn; |
1300 | bool discov_stopped; | ||
1301 | int err; | ||
1295 | 1302 | ||
1296 | hci_req_init(&req, hdev); | 1303 | hci_req_init(&req, hdev); |
1297 | 1304 | ||
@@ -1304,7 +1311,7 @@ static int clean_up_hci_state(struct hci_dev *hdev) | |||
1304 | if (test_bit(HCI_LE_ADV, &hdev->dev_flags)) | 1311 | if (test_bit(HCI_LE_ADV, &hdev->dev_flags)) |
1305 | disable_advertising(&req); | 1312 | disable_advertising(&req); |
1306 | 1313 | ||
1307 | hci_stop_discovery(&req); | 1314 | discov_stopped = hci_stop_discovery(&req); |
1308 | 1315 | ||
1309 | list_for_each_entry(conn, &hdev->conn_hash.list, list) { | 1316 | list_for_each_entry(conn, &hdev->conn_hash.list, list) { |
1310 | struct hci_cp_disconnect dc; | 1317 | struct hci_cp_disconnect dc; |
@@ -1338,7 +1345,11 @@ static int clean_up_hci_state(struct hci_dev *hdev) | |||
1338 | } | 1345 | } |
1339 | } | 1346 | } |
1340 | 1347 | ||
1341 | return hci_req_run(&req, clean_up_hci_complete); | 1348 | err = hci_req_run(&req, clean_up_hci_complete); |
1349 | if (!err && discov_stopped) | ||
1350 | hci_discovery_set_state(hdev, DISCOVERY_STOPPING); | ||
1351 | |||
1352 | return err; | ||
1342 | } | 1353 | } |
1343 | 1354 | ||
1344 | static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data, | 1355 | static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data, |