diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2015-11-11 01:30:45 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-11-19 11:50:31 -0500 |
commit | 2154d3f4fb83c812a161c4910948dd876997e111 (patch) | |
tree | 0f9151acfc4bcf72165911bcc25713a08faf3a9b /net/bluetooth/hci_request.c | |
parent | e68f072b7396574df5324e1cf93e4b0c92460735 (diff) |
Bluetooth: Move Stop Discovery to req_workqueue
Since discovery also deals with LE scanning it makes sense to move it
behind the same req_workqueue as other LE scanning changes. This also
simplifies the logic since we do many of the actions in a synchronous
manner.
Part of this refactoring is moving hci_req_stop_discovery() to
hci_request.c. At the same time the function receives support for
properly handling the STOPPING state since that's the state we'll be
in when stopping through the 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 | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index da1e30b85e77..3219ee66faad 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c | |||
@@ -1221,6 +1221,62 @@ static void start_discovery(struct hci_dev *hdev, u8 *status) | |||
1221 | timeout); | 1221 | timeout); |
1222 | } | 1222 | } |
1223 | 1223 | ||
1224 | bool hci_req_stop_discovery(struct hci_request *req) | ||
1225 | { | ||
1226 | struct hci_dev *hdev = req->hdev; | ||
1227 | struct discovery_state *d = &hdev->discovery; | ||
1228 | struct hci_cp_remote_name_req_cancel cp; | ||
1229 | struct inquiry_entry *e; | ||
1230 | bool ret = false; | ||
1231 | |||
1232 | BT_DBG("%s state %u", hdev->name, hdev->discovery.state); | ||
1233 | |||
1234 | if (d->state == DISCOVERY_FINDING || d->state == DISCOVERY_STOPPING) { | ||
1235 | if (test_bit(HCI_INQUIRY, &hdev->flags)) | ||
1236 | hci_req_add(req, HCI_OP_INQUIRY_CANCEL, 0, NULL); | ||
1237 | |||
1238 | if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) { | ||
1239 | cancel_delayed_work(&hdev->le_scan_disable); | ||
1240 | hci_req_add_le_scan_disable(req); | ||
1241 | } | ||
1242 | |||
1243 | ret = true; | ||
1244 | } else { | ||
1245 | /* Passive scanning */ | ||
1246 | if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) { | ||
1247 | hci_req_add_le_scan_disable(req); | ||
1248 | ret = true; | ||
1249 | } | ||
1250 | } | ||
1251 | |||
1252 | /* No further actions needed for LE-only discovery */ | ||
1253 | if (d->type == DISCOV_TYPE_LE) | ||
1254 | return ret; | ||
1255 | |||
1256 | if (d->state == DISCOVERY_RESOLVING || d->state == DISCOVERY_STOPPING) { | ||
1257 | e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, | ||
1258 | NAME_PENDING); | ||
1259 | if (!e) | ||
1260 | return ret; | ||
1261 | |||
1262 | bacpy(&cp.bdaddr, &e->data.bdaddr); | ||
1263 | hci_req_add(req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp), | ||
1264 | &cp); | ||
1265 | ret = true; | ||
1266 | } | ||
1267 | |||
1268 | return ret; | ||
1269 | } | ||
1270 | |||
1271 | static int stop_discovery(struct hci_request *req, unsigned long opt) | ||
1272 | { | ||
1273 | hci_dev_lock(req->hdev); | ||
1274 | hci_req_stop_discovery(req); | ||
1275 | hci_dev_unlock(req->hdev); | ||
1276 | |||
1277 | return 0; | ||
1278 | } | ||
1279 | |||
1224 | static void discov_update(struct work_struct *work) | 1280 | static void discov_update(struct work_struct *work) |
1225 | { | 1281 | { |
1226 | struct hci_dev *hdev = container_of(work, struct hci_dev, | 1282 | struct hci_dev *hdev = container_of(work, struct hci_dev, |
@@ -1236,6 +1292,12 @@ static void discov_update(struct work_struct *work) | |||
1236 | else | 1292 | else |
1237 | hci_discovery_set_state(hdev, DISCOVERY_FINDING); | 1293 | hci_discovery_set_state(hdev, DISCOVERY_FINDING); |
1238 | break; | 1294 | break; |
1295 | case DISCOVERY_STOPPING: | ||
1296 | hci_req_sync(hdev, stop_discovery, 0, HCI_CMD_TIMEOUT, &status); | ||
1297 | mgmt_stop_discovery_complete(hdev, status); | ||
1298 | if (!status) | ||
1299 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
1300 | break; | ||
1239 | case DISCOVERY_STOPPED: | 1301 | case DISCOVERY_STOPPED: |
1240 | default: | 1302 | default: |
1241 | return; | 1303 | return; |