diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2015-11-22 09:24:44 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-12-09 18:51:48 -0500 |
commit | aed1a8851db022c3bd22af41a343068b8c6e40c1 (patch) | |
tree | 74efd21f8ee36965782e8394cb0e8ee70aa598aa /net/bluetooth/hci_request.c | |
parent | 14bf5eac7a4f4bf0729ff8eb358de4fab967cee1 (diff) |
Bluetooth: Move discoverable changes to hdev->req_workqueue
The discoverable mode is intrinsically linked with the connectable
mode e.g. through sharing the same HCI command (Write Scan Enable) for
BR/EDR. It makes therefore sense to move it to hci_request.c and run
the changes through the same hdev->req_workqueue.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/hci_request.c')
-rw-r--r-- | net/bluetooth/hci_request.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index e5e827b762b9..8f72218ed805 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c | |||
@@ -1351,6 +1351,68 @@ void __hci_req_update_class(struct hci_request *req) | |||
1351 | hci_req_add(req, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod); | 1351 | hci_req_add(req, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod); |
1352 | } | 1352 | } |
1353 | 1353 | ||
1354 | static void write_iac(struct hci_request *req) | ||
1355 | { | ||
1356 | struct hci_dev *hdev = req->hdev; | ||
1357 | struct hci_cp_write_current_iac_lap cp; | ||
1358 | |||
1359 | if (!hci_dev_test_flag(hdev, HCI_DISCOVERABLE)) | ||
1360 | return; | ||
1361 | |||
1362 | if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE)) { | ||
1363 | /* Limited discoverable mode */ | ||
1364 | cp.num_iac = min_t(u8, hdev->num_iac, 2); | ||
1365 | cp.iac_lap[0] = 0x00; /* LIAC */ | ||
1366 | cp.iac_lap[1] = 0x8b; | ||
1367 | cp.iac_lap[2] = 0x9e; | ||
1368 | cp.iac_lap[3] = 0x33; /* GIAC */ | ||
1369 | cp.iac_lap[4] = 0x8b; | ||
1370 | cp.iac_lap[5] = 0x9e; | ||
1371 | } else { | ||
1372 | /* General discoverable mode */ | ||
1373 | cp.num_iac = 1; | ||
1374 | cp.iac_lap[0] = 0x33; /* GIAC */ | ||
1375 | cp.iac_lap[1] = 0x8b; | ||
1376 | cp.iac_lap[2] = 0x9e; | ||
1377 | } | ||
1378 | |||
1379 | hci_req_add(req, HCI_OP_WRITE_CURRENT_IAC_LAP, | ||
1380 | (cp.num_iac * 3) + 1, &cp); | ||
1381 | } | ||
1382 | |||
1383 | static int discoverable_update(struct hci_request *req, unsigned long opt) | ||
1384 | { | ||
1385 | struct hci_dev *hdev = req->hdev; | ||
1386 | |||
1387 | hci_dev_lock(hdev); | ||
1388 | |||
1389 | if (hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) { | ||
1390 | write_iac(req); | ||
1391 | __hci_req_update_scan(req); | ||
1392 | __hci_req_update_class(req); | ||
1393 | } | ||
1394 | |||
1395 | /* Advertising instances don't use the global discoverable setting, so | ||
1396 | * only update AD if advertising was enabled using Set Advertising. | ||
1397 | */ | ||
1398 | if (hci_dev_test_flag(hdev, HCI_ADVERTISING)) | ||
1399 | __hci_req_update_adv_data(req, HCI_ADV_CURRENT); | ||
1400 | |||
1401 | hci_dev_unlock(hdev); | ||
1402 | |||
1403 | return 0; | ||
1404 | } | ||
1405 | |||
1406 | static void discoverable_update_work(struct work_struct *work) | ||
1407 | { | ||
1408 | struct hci_dev *hdev = container_of(work, struct hci_dev, | ||
1409 | discoverable_update); | ||
1410 | u8 status; | ||
1411 | |||
1412 | hci_req_sync(hdev, discoverable_update, 0, HCI_CMD_TIMEOUT, &status); | ||
1413 | mgmt_set_discoverable_complete(hdev, status); | ||
1414 | } | ||
1415 | |||
1354 | void __hci_abort_conn(struct hci_request *req, struct hci_conn *conn, | 1416 | void __hci_abort_conn(struct hci_request *req, struct hci_conn *conn, |
1355 | u8 reason) | 1417 | u8 reason) |
1356 | { | 1418 | { |
@@ -1867,6 +1929,7 @@ void hci_request_setup(struct hci_dev *hdev) | |||
1867 | INIT_WORK(&hdev->bg_scan_update, bg_scan_update); | 1929 | INIT_WORK(&hdev->bg_scan_update, bg_scan_update); |
1868 | INIT_WORK(&hdev->scan_update, scan_update_work); | 1930 | INIT_WORK(&hdev->scan_update, scan_update_work); |
1869 | INIT_WORK(&hdev->connectable_update, connectable_update_work); | 1931 | INIT_WORK(&hdev->connectable_update, connectable_update_work); |
1932 | INIT_WORK(&hdev->discoverable_update, discoverable_update_work); | ||
1870 | INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); | 1933 | INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); |
1871 | INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart_work); | 1934 | INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart_work); |
1872 | INIT_DELAYED_WORK(&hdev->adv_instance_expire, adv_timeout_expire); | 1935 | INIT_DELAYED_WORK(&hdev->adv_instance_expire, adv_timeout_expire); |
@@ -1880,6 +1943,7 @@ void hci_request_cancel_all(struct hci_dev *hdev) | |||
1880 | cancel_work_sync(&hdev->bg_scan_update); | 1943 | cancel_work_sync(&hdev->bg_scan_update); |
1881 | cancel_work_sync(&hdev->scan_update); | 1944 | cancel_work_sync(&hdev->scan_update); |
1882 | cancel_work_sync(&hdev->connectable_update); | 1945 | cancel_work_sync(&hdev->connectable_update); |
1946 | cancel_work_sync(&hdev->discoverable_update); | ||
1883 | cancel_delayed_work_sync(&hdev->le_scan_disable); | 1947 | cancel_delayed_work_sync(&hdev->le_scan_disable); |
1884 | cancel_delayed_work_sync(&hdev->le_scan_restart); | 1948 | cancel_delayed_work_sync(&hdev->le_scan_restart); |
1885 | 1949 | ||