aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2013-03-15 18:07:04 -0400
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>2013-03-18 13:02:06 -0400
commit2b76f4539c6a41c3dd2e73f9ca7e03bcff6c8774 (patch)
treefdfef316926bbce09f130850adf6aba0480c52b0
parentb3f2ca9446f63acf5ab8552a37c4cc90af64b816 (diff)
Bluetooth: Use an async request for mgmt_set_connectable
This patch changes the mgmt_set_connectable handler to use an async request for sending the required HCI command. This is necessary preparation for handling the fast connectable change that needs to be associated with disabling the connectable setting. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
-rw-r--r--net/bluetooth/mgmt.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 15305fa55067..a4f928ddc28a 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -996,11 +996,32 @@ failed:
996 return err; 996 return err;
997} 997}
998 998
999static void set_connectable_complete(struct hci_dev *hdev, u8 status)
1000{
1001 struct pending_cmd *cmd;
1002
1003 BT_DBG("status 0x%02x", status);
1004
1005 hci_dev_lock(hdev);
1006
1007 cmd = mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
1008 if (!cmd)
1009 goto unlock;
1010
1011 send_settings_rsp(cmd->sk, MGMT_OP_SET_CONNECTABLE, hdev);
1012
1013 mgmt_pending_remove(cmd);
1014
1015unlock:
1016 hci_dev_unlock(hdev);
1017}
1018
999static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, 1019static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
1000 u16 len) 1020 u16 len)
1001{ 1021{
1002 struct mgmt_mode *cp = data; 1022 struct mgmt_mode *cp = data;
1003 struct pending_cmd *cmd; 1023 struct pending_cmd *cmd;
1024 struct hci_request req;
1004 u8 scan; 1025 u8 scan;
1005 int err; 1026 int err;
1006 1027
@@ -1067,7 +1088,11 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
1067 cancel_delayed_work(&hdev->discov_off); 1088 cancel_delayed_work(&hdev->discov_off);
1068 } 1089 }
1069 1090
1070 err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); 1091 hci_req_init(&req, hdev);
1092
1093 hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
1094
1095 err = hci_req_run(&req, set_connectable_complete);
1071 if (err < 0) 1096 if (err < 0)
1072 mgmt_pending_remove(cmd); 1097 mgmt_pending_remove(cmd);
1073 1098
@@ -3328,7 +3353,7 @@ int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
3328 3353
3329int mgmt_connectable(struct hci_dev *hdev, u8 connectable) 3354int mgmt_connectable(struct hci_dev *hdev, u8 connectable)
3330{ 3355{
3331 struct cmd_lookup match = { NULL, hdev }; 3356 struct pending_cmd *cmd;
3332 bool changed = false; 3357 bool changed = false;
3333 int err = 0; 3358 int err = 0;
3334 3359
@@ -3340,14 +3365,10 @@ int mgmt_connectable(struct hci_dev *hdev, u8 connectable)
3340 changed = true; 3365 changed = true;
3341 } 3366 }
3342 3367
3343 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, settings_rsp, 3368 cmd = mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
3344 &match);
3345 3369
3346 if (changed) 3370 if (changed)
3347 err = new_settings(hdev, match.sk); 3371 err = new_settings(hdev, cmd ? cmd->sk : NULL);
3348
3349 if (match.sk)
3350 sock_put(match.sk);
3351 3372
3352 return err; 3373 return err;
3353} 3374}