diff options
Diffstat (limited to 'net/bluetooth/hci_request.c')
-rw-r--r-- | net/bluetooth/hci_request.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index e639671f54bd..78c026b4ffa1 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c | |||
@@ -637,7 +637,7 @@ static bool disconnected_whitelist_entries(struct hci_dev *hdev) | |||
637 | return false; | 637 | return false; |
638 | } | 638 | } |
639 | 639 | ||
640 | void __hci_update_page_scan(struct hci_request *req) | 640 | void __hci_req_update_scan(struct hci_request *req) |
641 | { | 641 | { |
642 | struct hci_dev *hdev = req->hdev; | 642 | struct hci_dev *hdev = req->hdev; |
643 | u8 scan; | 643 | u8 scan; |
@@ -657,22 +657,29 @@ void __hci_update_page_scan(struct hci_request *req) | |||
657 | else | 657 | else |
658 | scan = SCAN_DISABLED; | 658 | scan = SCAN_DISABLED; |
659 | 659 | ||
660 | if (test_bit(HCI_PSCAN, &hdev->flags) == !!(scan & SCAN_PAGE)) | ||
661 | return; | ||
662 | |||
663 | if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE)) | 660 | if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE)) |
664 | scan |= SCAN_INQUIRY; | 661 | scan |= SCAN_INQUIRY; |
665 | 662 | ||
663 | if (test_bit(HCI_PSCAN, &hdev->flags) == !!(scan & SCAN_PAGE) && | ||
664 | test_bit(HCI_ISCAN, &hdev->flags) == !!(scan & SCAN_INQUIRY)) | ||
665 | return; | ||
666 | |||
666 | hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); | 667 | hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); |
667 | } | 668 | } |
668 | 669 | ||
669 | void hci_update_page_scan(struct hci_dev *hdev) | 670 | static int update_scan(struct hci_request *req, unsigned long opt) |
670 | { | 671 | { |
671 | struct hci_request req; | 672 | hci_dev_lock(req->hdev); |
673 | __hci_req_update_scan(req); | ||
674 | hci_dev_unlock(req->hdev); | ||
675 | return 0; | ||
676 | } | ||
672 | 677 | ||
673 | hci_req_init(&req, hdev); | 678 | static void scan_update_work(struct work_struct *work) |
674 | __hci_update_page_scan(&req); | 679 | { |
675 | hci_req_run(&req, NULL); | 680 | struct hci_dev *hdev = container_of(work, struct hci_dev, scan_update); |
681 | |||
682 | hci_req_sync(hdev, update_scan, 0, HCI_CMD_TIMEOUT, NULL); | ||
676 | } | 683 | } |
677 | 684 | ||
678 | /* This function controls the background scanning based on hdev->pend_le_conns | 685 | /* This function controls the background scanning based on hdev->pend_le_conns |
@@ -1270,6 +1277,7 @@ void hci_request_setup(struct hci_dev *hdev) | |||
1270 | { | 1277 | { |
1271 | INIT_WORK(&hdev->discov_update, discov_update); | 1278 | INIT_WORK(&hdev->discov_update, discov_update); |
1272 | INIT_WORK(&hdev->bg_scan_update, bg_scan_update); | 1279 | INIT_WORK(&hdev->bg_scan_update, bg_scan_update); |
1280 | INIT_WORK(&hdev->scan_update, scan_update_work); | ||
1273 | INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); | 1281 | INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); |
1274 | INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart_work); | 1282 | INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart_work); |
1275 | } | 1283 | } |
@@ -1280,6 +1288,7 @@ void hci_request_cancel_all(struct hci_dev *hdev) | |||
1280 | 1288 | ||
1281 | cancel_work_sync(&hdev->discov_update); | 1289 | cancel_work_sync(&hdev->discov_update); |
1282 | cancel_work_sync(&hdev->bg_scan_update); | 1290 | cancel_work_sync(&hdev->bg_scan_update); |
1291 | cancel_work_sync(&hdev->scan_update); | ||
1283 | cancel_delayed_work_sync(&hdev->le_scan_disable); | 1292 | cancel_delayed_work_sync(&hdev->le_scan_disable); |
1284 | cancel_delayed_work_sync(&hdev->le_scan_restart); | 1293 | cancel_delayed_work_sync(&hdev->le_scan_restart); |
1285 | } | 1294 | } |