aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-06-10 07:05:58 -0400
committerMarcel Holtmann <marcel@holtmann.org>2014-06-13 07:32:20 -0400
commit21a60d307ddc2180cfa542a995d943d1034cf5c5 (patch)
treef105655f9b27dfb3a799d4035d0dc77adeec1160 /net
parent50143a433b70e3145bcf8a4a4e54f0c11bdee32b (diff)
Bluetooth: Refactor discovery stopping into its own function
We'll need to reuse the same logic for stopping discovery also when cleaning up HCI state when powering off. This patch refactors the code out to its own function that can later (in a subsequent patch) be used also for the power off case. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Cc: stable@vger.kernel.org
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/mgmt.c93
1 files changed, 49 insertions, 44 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 0fce54412ffd..be6f03219121 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1047,6 +1047,43 @@ static void clean_up_hci_complete(struct hci_dev *hdev, u8 status)
1047 } 1047 }
1048} 1048}
1049 1049
1050static void hci_stop_discovery(struct hci_request *req)
1051{
1052 struct hci_dev *hdev = req->hdev;
1053 struct hci_cp_remote_name_req_cancel cp;
1054 struct inquiry_entry *e;
1055
1056 switch (hdev->discovery.state) {
1057 case DISCOVERY_FINDING:
1058 if (test_bit(HCI_INQUIRY, &hdev->flags)) {
1059 hci_req_add(req, HCI_OP_INQUIRY_CANCEL, 0, NULL);
1060 } else {
1061 cancel_delayed_work(&hdev->le_scan_disable);
1062 hci_req_add_le_scan_disable(req);
1063 }
1064
1065 break;
1066
1067 case DISCOVERY_RESOLVING:
1068 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
1069 NAME_PENDING);
1070 if (!e)
1071 return;
1072
1073 bacpy(&cp.bdaddr, &e->data.bdaddr);
1074 hci_req_add(req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp),
1075 &cp);
1076
1077 break;
1078
1079 default:
1080 /* Passive scanning */
1081 if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
1082 hci_req_add_le_scan_disable(req);
1083 break;
1084 }
1085}
1086
1050static int clean_up_hci_state(struct hci_dev *hdev) 1087static int clean_up_hci_state(struct hci_dev *hdev)
1051{ 1088{
1052 struct hci_request req; 1089 struct hci_request req;
@@ -3574,8 +3611,6 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
3574{ 3611{
3575 struct mgmt_cp_stop_discovery *mgmt_cp = data; 3612 struct mgmt_cp_stop_discovery *mgmt_cp = data;
3576 struct pending_cmd *cmd; 3613 struct pending_cmd *cmd;
3577 struct hci_cp_remote_name_req_cancel cp;
3578 struct inquiry_entry *e;
3579 struct hci_request req; 3614 struct hci_request req;
3580 int err; 3615 int err;
3581 3616
@@ -3605,52 +3640,22 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
3605 3640
3606 hci_req_init(&req, hdev); 3641 hci_req_init(&req, hdev);
3607 3642
3608 switch (hdev->discovery.state) { 3643 hci_stop_discovery(&req);
3609 case DISCOVERY_FINDING:
3610 if (test_bit(HCI_INQUIRY, &hdev->flags)) {
3611 hci_req_add(&req, HCI_OP_INQUIRY_CANCEL, 0, NULL);
3612 } else {
3613 cancel_delayed_work(&hdev->le_scan_disable);
3614
3615 hci_req_add_le_scan_disable(&req);
3616 }
3617
3618 break;
3619
3620 case DISCOVERY_RESOLVING:
3621 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
3622 NAME_PENDING);
3623 if (!e) {
3624 mgmt_pending_remove(cmd);
3625 err = cmd_complete(sk, hdev->id,
3626 MGMT_OP_STOP_DISCOVERY, 0,
3627 &mgmt_cp->type,
3628 sizeof(mgmt_cp->type));
3629 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
3630 goto unlock;
3631 }
3632
3633 bacpy(&cp.bdaddr, &e->data.bdaddr);
3634 hci_req_add(&req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp),
3635 &cp);
3636 3644
3637 break; 3645 err = hci_req_run(&req, stop_discovery_complete);
3638 3646 if (!err) {
3639 default: 3647 hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
3640 BT_DBG("unknown discovery state %u", hdev->discovery.state);
3641
3642 mgmt_pending_remove(cmd);
3643 err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY,
3644 MGMT_STATUS_FAILED, &mgmt_cp->type,
3645 sizeof(mgmt_cp->type));
3646 goto unlock; 3648 goto unlock;
3647 } 3649 }
3648 3650
3649 err = hci_req_run(&req, stop_discovery_complete); 3651 mgmt_pending_remove(cmd);
3650 if (err < 0) 3652
3651 mgmt_pending_remove(cmd); 3653 /* If no HCI commands were sent we're done */
3652 else 3654 if (err == -ENODATA) {
3653 hci_discovery_set_state(hdev, DISCOVERY_STOPPING); 3655 err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, 0,
3656 &mgmt_cp->type, sizeof(mgmt_cp->type));
3657 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
3658 }
3654 3659
3655unlock: 3660unlock:
3656 hci_dev_unlock(hdev); 3661 hci_dev_unlock(hdev);