diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2011-11-08 13:40:14 -0500 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-11-09 09:33:26 -0500 |
commit | 744cf19eadcf4de914394e0eb227f94f4318f5e4 (patch) | |
tree | a8c06c43be956e5db8db1bc1e052b773626892c6 /net/bluetooth | |
parent | 4c659c3976e81f9def48993cd00988d53d7379f2 (diff) |
Bluetooth: Pass full hci_dev struct to mgmt callbacks
The current global pending command list in mgmt.c is racy. Possibly the
simplest way to fix it is to have per-hci dev lists instead of a global
one (all commands that need a pending struct are hci_dev specific).
This way the list can be protected using the already existing per-hci
dev lock. To enable this refactoring the first thing that needs to be
done is to ensure that the mgmt functions have access to the hci_dev
struct (instead of just the dev id).
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_core.c | 16 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 63 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 206 |
3 files changed, 145 insertions, 140 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 693c0dfc6b9d..e4b5c6345095 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -550,7 +550,7 @@ int hci_dev_open(__u16 dev) | |||
550 | set_bit(HCI_UP, &hdev->flags); | 550 | set_bit(HCI_UP, &hdev->flags); |
551 | hci_notify(hdev, HCI_DEV_UP); | 551 | hci_notify(hdev, HCI_DEV_UP); |
552 | if (!test_bit(HCI_SETUP, &hdev->flags)) | 552 | if (!test_bit(HCI_SETUP, &hdev->flags)) |
553 | mgmt_powered(hdev->id, 1); | 553 | mgmt_powered(hdev, 1); |
554 | } else { | 554 | } else { |
555 | /* Init failed, cleanup */ | 555 | /* Init failed, cleanup */ |
556 | tasklet_kill(&hdev->rx_task); | 556 | tasklet_kill(&hdev->rx_task); |
@@ -642,7 +642,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
642 | * and no tasks are scheduled. */ | 642 | * and no tasks are scheduled. */ |
643 | hdev->close(hdev); | 643 | hdev->close(hdev); |
644 | 644 | ||
645 | mgmt_powered(hdev->id, 0); | 645 | mgmt_powered(hdev, 0); |
646 | 646 | ||
647 | /* Clear flags */ | 647 | /* Clear flags */ |
648 | hdev->flags = 0; | 648 | hdev->flags = 0; |
@@ -947,7 +947,7 @@ static void hci_power_on(struct work_struct *work) | |||
947 | msecs_to_jiffies(AUTO_OFF_TIMEOUT)); | 947 | msecs_to_jiffies(AUTO_OFF_TIMEOUT)); |
948 | 948 | ||
949 | if (test_and_clear_bit(HCI_SETUP, &hdev->flags)) | 949 | if (test_and_clear_bit(HCI_SETUP, &hdev->flags)) |
950 | mgmt_index_added(hdev->id); | 950 | mgmt_index_added(hdev); |
951 | } | 951 | } |
952 | 952 | ||
953 | static void hci_power_off(struct work_struct *work) | 953 | static void hci_power_off(struct work_struct *work) |
@@ -1140,7 +1140,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, | |||
1140 | 1140 | ||
1141 | persistent = hci_persistent_key(hdev, conn, type, old_key_type); | 1141 | persistent = hci_persistent_key(hdev, conn, type, old_key_type); |
1142 | 1142 | ||
1143 | mgmt_new_link_key(hdev->id, key, persistent); | 1143 | mgmt_new_link_key(hdev, key, persistent); |
1144 | 1144 | ||
1145 | if (!persistent) { | 1145 | if (!persistent) { |
1146 | list_del(&key->list); | 1146 | list_del(&key->list); |
@@ -1183,7 +1183,7 @@ int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, | |||
1183 | memcpy(id->rand, rand, sizeof(id->rand)); | 1183 | memcpy(id->rand, rand, sizeof(id->rand)); |
1184 | 1184 | ||
1185 | if (new_key) | 1185 | if (new_key) |
1186 | mgmt_new_link_key(hdev->id, key, old_key_type); | 1186 | mgmt_new_link_key(hdev, key, old_key_type); |
1187 | 1187 | ||
1188 | return 0; | 1188 | return 0; |
1189 | } | 1189 | } |
@@ -1324,7 +1324,7 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1324 | 1324 | ||
1325 | list_add(&entry->list, &hdev->blacklist); | 1325 | list_add(&entry->list, &hdev->blacklist); |
1326 | 1326 | ||
1327 | return mgmt_device_blocked(hdev->id, bdaddr); | 1327 | return mgmt_device_blocked(hdev, bdaddr); |
1328 | } | 1328 | } |
1329 | 1329 | ||
1330 | int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr) | 1330 | int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr) |
@@ -1343,7 +1343,7 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1343 | list_del(&entry->list); | 1343 | list_del(&entry->list); |
1344 | kfree(entry); | 1344 | kfree(entry); |
1345 | 1345 | ||
1346 | return mgmt_device_unblocked(hdev->id, bdaddr); | 1346 | return mgmt_device_unblocked(hdev, bdaddr); |
1347 | } | 1347 | } |
1348 | 1348 | ||
1349 | static void hci_clear_adv_cache(unsigned long arg) | 1349 | static void hci_clear_adv_cache(unsigned long arg) |
@@ -1560,7 +1560,7 @@ void hci_unregister_dev(struct hci_dev *hdev) | |||
1560 | 1560 | ||
1561 | if (!test_bit(HCI_INIT, &hdev->flags) && | 1561 | if (!test_bit(HCI_INIT, &hdev->flags) && |
1562 | !test_bit(HCI_SETUP, &hdev->flags)) | 1562 | !test_bit(HCI_SETUP, &hdev->flags)) |
1563 | mgmt_index_removed(hdev->id); | 1563 | mgmt_index_removed(hdev); |
1564 | 1564 | ||
1565 | hci_notify(hdev, HCI_DEV_UNREG); | 1565 | hci_notify(hdev, HCI_DEV_UNREG); |
1566 | 1566 | ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 2fced8c43258..8303f8fa1821 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -60,7 +60,7 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) | |||
60 | 60 | ||
61 | clear_bit(HCI_INQUIRY, &hdev->flags); | 61 | clear_bit(HCI_INQUIRY, &hdev->flags); |
62 | 62 | ||
63 | mgmt_discovering(hdev->id, 0); | 63 | mgmt_discovering(hdev, 0); |
64 | 64 | ||
65 | hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); | 65 | hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); |
66 | 66 | ||
@@ -202,7 +202,7 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) | |||
202 | return; | 202 | return; |
203 | 203 | ||
204 | if (test_bit(HCI_MGMT, &hdev->flags)) | 204 | if (test_bit(HCI_MGMT, &hdev->flags)) |
205 | mgmt_set_local_name_complete(hdev->id, sent, status); | 205 | mgmt_set_local_name_complete(hdev, sent, status); |
206 | 206 | ||
207 | if (status) | 207 | if (status) |
208 | return; | 208 | return; |
@@ -283,7 +283,7 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
283 | param = *((__u8 *) sent); | 283 | param = *((__u8 *) sent); |
284 | 284 | ||
285 | if (status != 0) { | 285 | if (status != 0) { |
286 | mgmt_write_scan_failed(hdev->id, param, status); | 286 | mgmt_write_scan_failed(hdev, param, status); |
287 | hdev->discov_timeout = 0; | 287 | hdev->discov_timeout = 0; |
288 | goto done; | 288 | goto done; |
289 | } | 289 | } |
@@ -294,21 +294,21 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
294 | if (param & SCAN_INQUIRY) { | 294 | if (param & SCAN_INQUIRY) { |
295 | set_bit(HCI_ISCAN, &hdev->flags); | 295 | set_bit(HCI_ISCAN, &hdev->flags); |
296 | if (!old_iscan) | 296 | if (!old_iscan) |
297 | mgmt_discoverable(hdev->id, 1); | 297 | mgmt_discoverable(hdev, 1); |
298 | if (hdev->discov_timeout > 0) { | 298 | if (hdev->discov_timeout > 0) { |
299 | int to = msecs_to_jiffies(hdev->discov_timeout * 1000); | 299 | int to = msecs_to_jiffies(hdev->discov_timeout * 1000); |
300 | queue_delayed_work(hdev->workqueue, &hdev->discov_off, | 300 | queue_delayed_work(hdev->workqueue, &hdev->discov_off, |
301 | to); | 301 | to); |
302 | } | 302 | } |
303 | } else if (old_iscan) | 303 | } else if (old_iscan) |
304 | mgmt_discoverable(hdev->id, 0); | 304 | mgmt_discoverable(hdev, 0); |
305 | 305 | ||
306 | if (param & SCAN_PAGE) { | 306 | if (param & SCAN_PAGE) { |
307 | set_bit(HCI_PSCAN, &hdev->flags); | 307 | set_bit(HCI_PSCAN, &hdev->flags); |
308 | if (!old_pscan) | 308 | if (!old_pscan) |
309 | mgmt_connectable(hdev->id, 1); | 309 | mgmt_connectable(hdev, 1); |
310 | } else if (old_pscan) | 310 | } else if (old_pscan) |
311 | mgmt_connectable(hdev->id, 0); | 311 | mgmt_connectable(hdev, 0); |
312 | 312 | ||
313 | done: | 313 | done: |
314 | hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status); | 314 | hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status); |
@@ -835,7 +835,7 @@ static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
835 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 835 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
836 | 836 | ||
837 | if (test_bit(HCI_MGMT, &hdev->flags)) | 837 | if (test_bit(HCI_MGMT, &hdev->flags)) |
838 | mgmt_pin_code_reply_complete(hdev->id, &rp->bdaddr, rp->status); | 838 | mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); |
839 | 839 | ||
840 | if (rp->status != 0) | 840 | if (rp->status != 0) |
841 | return; | 841 | return; |
@@ -856,7 +856,7 @@ static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
856 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 856 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
857 | 857 | ||
858 | if (test_bit(HCI_MGMT, &hdev->flags)) | 858 | if (test_bit(HCI_MGMT, &hdev->flags)) |
859 | mgmt_pin_code_neg_reply_complete(hdev->id, &rp->bdaddr, | 859 | mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, |
860 | rp->status); | 860 | rp->status); |
861 | } | 861 | } |
862 | static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, | 862 | static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, |
@@ -886,7 +886,7 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
886 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 886 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
887 | 887 | ||
888 | if (test_bit(HCI_MGMT, &hdev->flags)) | 888 | if (test_bit(HCI_MGMT, &hdev->flags)) |
889 | mgmt_user_confirm_reply_complete(hdev->id, &rp->bdaddr, | 889 | mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, |
890 | rp->status); | 890 | rp->status); |
891 | } | 891 | } |
892 | 892 | ||
@@ -898,7 +898,7 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, | |||
898 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 898 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
899 | 899 | ||
900 | if (test_bit(HCI_MGMT, &hdev->flags)) | 900 | if (test_bit(HCI_MGMT, &hdev->flags)) |
901 | mgmt_user_confirm_neg_reply_complete(hdev->id, &rp->bdaddr, | 901 | mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, |
902 | rp->status); | 902 | rp->status); |
903 | } | 903 | } |
904 | 904 | ||
@@ -909,7 +909,7 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, | |||
909 | 909 | ||
910 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 910 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
911 | 911 | ||
912 | mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash, | 912 | mgmt_read_local_oob_data_reply_complete(hdev, rp->hash, |
913 | rp->randomizer, rp->status); | 913 | rp->randomizer, rp->status); |
914 | } | 914 | } |
915 | 915 | ||
@@ -986,13 +986,13 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | |||
986 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); | 986 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); |
987 | hci_conn_check_pending(hdev); | 987 | hci_conn_check_pending(hdev); |
988 | if (test_bit(HCI_MGMT, &hdev->flags)) | 988 | if (test_bit(HCI_MGMT, &hdev->flags)) |
989 | mgmt_inquiry_failed(hdev->id, status); | 989 | mgmt_inquiry_failed(hdev, status); |
990 | return; | 990 | return; |
991 | } | 991 | } |
992 | 992 | ||
993 | set_bit(HCI_INQUIRY, &hdev->flags); | 993 | set_bit(HCI_INQUIRY, &hdev->flags); |
994 | 994 | ||
995 | mgmt_discovering(hdev->id, 1); | 995 | mgmt_discovering(hdev, 1); |
996 | } | 996 | } |
997 | 997 | ||
998 | static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) | 998 | static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) |
@@ -1378,7 +1378,7 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
1378 | if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) | 1378 | if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) |
1379 | return; | 1379 | return; |
1380 | 1380 | ||
1381 | mgmt_discovering(hdev->id, 0); | 1381 | mgmt_discovering(hdev, 0); |
1382 | } | 1382 | } |
1383 | 1383 | ||
1384 | static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1384 | static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -1404,7 +1404,7 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff * | |||
1404 | data.rssi = 0x00; | 1404 | data.rssi = 0x00; |
1405 | data.ssp_mode = 0x00; | 1405 | data.ssp_mode = 0x00; |
1406 | hci_inquiry_cache_update(hdev, &data); | 1406 | hci_inquiry_cache_update(hdev, &data); |
1407 | mgmt_device_found(hdev->id, &info->bdaddr, ACL_LINK, | 1407 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, |
1408 | info->dev_class, 0, NULL); | 1408 | info->dev_class, 0, NULL); |
1409 | } | 1409 | } |
1410 | 1410 | ||
@@ -1439,7 +1439,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1439 | conn->state = BT_CONFIG; | 1439 | conn->state = BT_CONFIG; |
1440 | hci_conn_hold(conn); | 1440 | hci_conn_hold(conn); |
1441 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 1441 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
1442 | mgmt_connected(hdev->id, &ev->bdaddr, conn->type); | 1442 | mgmt_connected(hdev, &ev->bdaddr, conn->type); |
1443 | } else | 1443 | } else |
1444 | conn->state = BT_CONNECTED; | 1444 | conn->state = BT_CONNECTED; |
1445 | 1445 | ||
@@ -1471,7 +1471,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1471 | } else { | 1471 | } else { |
1472 | conn->state = BT_CLOSED; | 1472 | conn->state = BT_CLOSED; |
1473 | if (conn->type == ACL_LINK) | 1473 | if (conn->type == ACL_LINK) |
1474 | mgmt_connect_failed(hdev->id, &ev->bdaddr, conn->type, | 1474 | mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, |
1475 | ev->status); | 1475 | ev->status); |
1476 | } | 1476 | } |
1477 | 1477 | ||
@@ -1572,7 +1572,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
1572 | BT_DBG("%s status %d", hdev->name, ev->status); | 1572 | BT_DBG("%s status %d", hdev->name, ev->status); |
1573 | 1573 | ||
1574 | if (ev->status) { | 1574 | if (ev->status) { |
1575 | mgmt_disconnect_failed(hdev->id); | 1575 | mgmt_disconnect_failed(hdev); |
1576 | return; | 1576 | return; |
1577 | } | 1577 | } |
1578 | 1578 | ||
@@ -1585,7 +1585,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
1585 | conn->state = BT_CLOSED; | 1585 | conn->state = BT_CLOSED; |
1586 | 1586 | ||
1587 | if (conn->type == ACL_LINK || conn->type == LE_LINK) | 1587 | if (conn->type == ACL_LINK || conn->type == LE_LINK) |
1588 | mgmt_disconnected(hdev->id, &conn->dst, conn->type); | 1588 | mgmt_disconnected(hdev, &conn->dst, conn->type); |
1589 | 1589 | ||
1590 | hci_proto_disconn_cfm(conn, ev->reason); | 1590 | hci_proto_disconn_cfm(conn, ev->reason); |
1591 | hci_conn_del(conn); | 1591 | hci_conn_del(conn); |
@@ -1616,7 +1616,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1616 | conn->sec_level = conn->pending_sec_level; | 1616 | conn->sec_level = conn->pending_sec_level; |
1617 | } | 1617 | } |
1618 | } else { | 1618 | } else { |
1619 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); | 1619 | mgmt_auth_failed(hdev, &conn->dst, ev->status); |
1620 | } | 1620 | } |
1621 | 1621 | ||
1622 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); | 1622 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); |
@@ -1671,7 +1671,7 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb | |||
1671 | hci_dev_lock(hdev); | 1671 | hci_dev_lock(hdev); |
1672 | 1672 | ||
1673 | if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags)) | 1673 | if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags)) |
1674 | mgmt_remote_name(hdev->id, &ev->bdaddr, ev->name); | 1674 | mgmt_remote_name(hdev, &ev->bdaddr, ev->name); |
1675 | 1675 | ||
1676 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | 1676 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); |
1677 | if (!conn) | 1677 | if (!conn) |
@@ -2061,7 +2061,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2061 | 2061 | ||
2062 | case HCI_OP_DISCONNECT: | 2062 | case HCI_OP_DISCONNECT: |
2063 | if (ev->status != 0) | 2063 | if (ev->status != 0) |
2064 | mgmt_disconnect_failed(hdev->id); | 2064 | mgmt_disconnect_failed(hdev); |
2065 | break; | 2065 | break; |
2066 | 2066 | ||
2067 | case HCI_OP_LE_CREATE_CONN: | 2067 | case HCI_OP_LE_CREATE_CONN: |
@@ -2226,7 +2226,7 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff | |||
2226 | else | 2226 | else |
2227 | secure = 0; | 2227 | secure = 0; |
2228 | 2228 | ||
2229 | mgmt_pin_code_request(hdev->id, &ev->bdaddr, secure); | 2229 | mgmt_pin_code_request(hdev, &ev->bdaddr, secure); |
2230 | } | 2230 | } |
2231 | 2231 | ||
2232 | unlock: | 2232 | unlock: |
@@ -2409,7 +2409,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct | |||
2409 | data.rssi = info->rssi; | 2409 | data.rssi = info->rssi; |
2410 | data.ssp_mode = 0x00; | 2410 | data.ssp_mode = 0x00; |
2411 | hci_inquiry_cache_update(hdev, &data); | 2411 | hci_inquiry_cache_update(hdev, &data); |
2412 | mgmt_device_found(hdev->id, &info->bdaddr, ACL_LINK, | 2412 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, |
2413 | info->dev_class, info->rssi, | 2413 | info->dev_class, info->rssi, |
2414 | NULL); | 2414 | NULL); |
2415 | } | 2415 | } |
@@ -2426,7 +2426,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct | |||
2426 | data.rssi = info->rssi; | 2426 | data.rssi = info->rssi; |
2427 | data.ssp_mode = 0x00; | 2427 | data.ssp_mode = 0x00; |
2428 | hci_inquiry_cache_update(hdev, &data); | 2428 | hci_inquiry_cache_update(hdev, &data); |
2429 | mgmt_device_found(hdev->id, &info->bdaddr, ACL_LINK, | 2429 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, |
2430 | info->dev_class, info->rssi, | 2430 | info->dev_class, info->rssi, |
2431 | NULL); | 2431 | NULL); |
2432 | } | 2432 | } |
@@ -2569,7 +2569,7 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct | |||
2569 | data.rssi = info->rssi; | 2569 | data.rssi = info->rssi; |
2570 | data.ssp_mode = 0x01; | 2570 | data.ssp_mode = 0x01; |
2571 | hci_inquiry_cache_update(hdev, &data); | 2571 | hci_inquiry_cache_update(hdev, &data); |
2572 | mgmt_device_found(hdev->id, &info->bdaddr, ACL_LINK, | 2572 | mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, |
2573 | info->dev_class, info->rssi, info->data); | 2573 | info->dev_class, info->rssi, info->data); |
2574 | } | 2574 | } |
2575 | 2575 | ||
@@ -2726,7 +2726,7 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, | |||
2726 | } | 2726 | } |
2727 | 2727 | ||
2728 | confirm: | 2728 | confirm: |
2729 | mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey, | 2729 | mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey, |
2730 | confirm_hint); | 2730 | confirm_hint); |
2731 | 2731 | ||
2732 | unlock: | 2732 | unlock: |
@@ -2752,7 +2752,7 @@ static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_ | |||
2752 | * event gets always produced as initiator and is also mapped to | 2752 | * event gets always produced as initiator and is also mapped to |
2753 | * the mgmt_auth_failed event */ | 2753 | * the mgmt_auth_failed event */ |
2754 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0) | 2754 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0) |
2755 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); | 2755 | mgmt_auth_failed(hdev, &conn->dst, ev->status); |
2756 | 2756 | ||
2757 | hci_conn_put(conn); | 2757 | hci_conn_put(conn); |
2758 | 2758 | ||
@@ -2833,15 +2833,14 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
2833 | } | 2833 | } |
2834 | 2834 | ||
2835 | if (ev->status) { | 2835 | if (ev->status) { |
2836 | mgmt_connect_failed(hdev->id, &ev->bdaddr, conn->type, | 2836 | mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, ev->status); |
2837 | ev->status); | ||
2838 | hci_proto_connect_cfm(conn, ev->status); | 2837 | hci_proto_connect_cfm(conn, ev->status); |
2839 | conn->state = BT_CLOSED; | 2838 | conn->state = BT_CLOSED; |
2840 | hci_conn_del(conn); | 2839 | hci_conn_del(conn); |
2841 | goto unlock; | 2840 | goto unlock; |
2842 | } | 2841 | } |
2843 | 2842 | ||
2844 | mgmt_connected(hdev->id, &ev->bdaddr, conn->type); | 2843 | mgmt_connected(hdev, &ev->bdaddr, conn->type); |
2845 | 2844 | ||
2846 | conn->sec_level = BT_SECURITY_LOW; | 2845 | conn->sec_level = BT_SECURITY_LOW; |
2847 | conn->handle = __le16_to_cpu(ev->handle); | 2846 | conn->handle = __le16_to_cpu(ev->handle); |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 4cb2f958fb10..2ca7b4427e34 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -255,7 +255,7 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, | |||
255 | return cmd; | 255 | return cmd; |
256 | } | 256 | } |
257 | 257 | ||
258 | static void mgmt_pending_foreach(u16 opcode, int index, | 258 | static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, |
259 | void (*cb)(struct pending_cmd *cmd, void *data), | 259 | void (*cb)(struct pending_cmd *cmd, void *data), |
260 | void *data) | 260 | void *data) |
261 | { | 261 | { |
@@ -269,7 +269,7 @@ static void mgmt_pending_foreach(u16 opcode, int index, | |||
269 | if (opcode > 0 && cmd->opcode != opcode) | 269 | if (opcode > 0 && cmd->opcode != opcode) |
270 | continue; | 270 | continue; |
271 | 271 | ||
272 | if (index >= 0 && cmd->index != index) | 272 | if (hdev && cmd->index != hdev->id) |
273 | continue; | 273 | continue; |
274 | 274 | ||
275 | cb(cmd, data); | 275 | cb(cmd, data); |
@@ -475,8 +475,8 @@ failed: | |||
475 | return err; | 475 | return err; |
476 | } | 476 | } |
477 | 477 | ||
478 | static int mgmt_event(u16 event, u16 index, void *data, u16 data_len, | 478 | static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, |
479 | struct sock *skip_sk) | 479 | u16 data_len, struct sock *skip_sk) |
480 | { | 480 | { |
481 | struct sk_buff *skb; | 481 | struct sk_buff *skb; |
482 | struct mgmt_hdr *hdr; | 482 | struct mgmt_hdr *hdr; |
@@ -489,7 +489,10 @@ static int mgmt_event(u16 event, u16 index, void *data, u16 data_len, | |||
489 | 489 | ||
490 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | 490 | hdr = (void *) skb_put(skb, sizeof(*hdr)); |
491 | hdr->opcode = cpu_to_le16(event); | 491 | hdr->opcode = cpu_to_le16(event); |
492 | hdr->index = cpu_to_le16(index); | 492 | if (hdev) |
493 | hdr->index = cpu_to_le16(hdev->id); | ||
494 | else | ||
495 | hdr->index = cpu_to_le16(MGMT_INDEX_NONE); | ||
493 | hdr->len = cpu_to_le16(data_len); | 496 | hdr->len = cpu_to_le16(data_len); |
494 | 497 | ||
495 | if (data) | 498 | if (data) |
@@ -541,7 +544,7 @@ static int set_pairable(struct sock *sk, u16 index, unsigned char *data, | |||
541 | 544 | ||
542 | ev.val = cp->val; | 545 | ev.val = cp->val; |
543 | 546 | ||
544 | err = mgmt_event(MGMT_EV_PAIRABLE, index, &ev, sizeof(ev), sk); | 547 | err = mgmt_event(MGMT_EV_PAIRABLE, hdev, &ev, sizeof(ev), sk); |
545 | 548 | ||
546 | failed: | 549 | failed: |
547 | hci_dev_unlock_bh(hdev); | 550 | hci_dev_unlock_bh(hdev); |
@@ -1966,18 +1969,18 @@ static void cmd_status_rsp(struct pending_cmd *cmd, void *data) | |||
1966 | mgmt_pending_remove(cmd); | 1969 | mgmt_pending_remove(cmd); |
1967 | } | 1970 | } |
1968 | 1971 | ||
1969 | int mgmt_index_added(u16 index) | 1972 | int mgmt_index_added(struct hci_dev *hdev) |
1970 | { | 1973 | { |
1971 | return mgmt_event(MGMT_EV_INDEX_ADDED, index, NULL, 0, NULL); | 1974 | return mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL); |
1972 | } | 1975 | } |
1973 | 1976 | ||
1974 | int mgmt_index_removed(u16 index) | 1977 | int mgmt_index_removed(struct hci_dev *hdev) |
1975 | { | 1978 | { |
1976 | u8 status = ENODEV; | 1979 | u8 status = ENODEV; |
1977 | 1980 | ||
1978 | mgmt_pending_foreach(0, index, cmd_status_rsp, &status); | 1981 | mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); |
1979 | 1982 | ||
1980 | return mgmt_event(MGMT_EV_INDEX_REMOVED, index, NULL, 0, NULL); | 1983 | return mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL); |
1981 | } | 1984 | } |
1982 | 1985 | ||
1983 | struct cmd_lookup { | 1986 | struct cmd_lookup { |
@@ -2005,22 +2008,22 @@ static void mode_rsp(struct pending_cmd *cmd, void *data) | |||
2005 | mgmt_pending_free(cmd); | 2008 | mgmt_pending_free(cmd); |
2006 | } | 2009 | } |
2007 | 2010 | ||
2008 | int mgmt_powered(u16 index, u8 powered) | 2011 | int mgmt_powered(struct hci_dev *hdev, u8 powered) |
2009 | { | 2012 | { |
2010 | struct mgmt_mode ev; | 2013 | struct mgmt_mode ev; |
2011 | struct cmd_lookup match = { powered, NULL }; | 2014 | struct cmd_lookup match = { powered, NULL }; |
2012 | int ret; | 2015 | int ret; |
2013 | 2016 | ||
2014 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, index, mode_rsp, &match); | 2017 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, mode_rsp, &match); |
2015 | 2018 | ||
2016 | if (!powered) { | 2019 | if (!powered) { |
2017 | u8 status = ENETDOWN; | 2020 | u8 status = ENETDOWN; |
2018 | mgmt_pending_foreach(0, index, cmd_status_rsp, &status); | 2021 | mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); |
2019 | } | 2022 | } |
2020 | 2023 | ||
2021 | ev.val = powered; | 2024 | ev.val = powered; |
2022 | 2025 | ||
2023 | ret = mgmt_event(MGMT_EV_POWERED, index, &ev, sizeof(ev), match.sk); | 2026 | ret = mgmt_event(MGMT_EV_POWERED, hdev, &ev, sizeof(ev), match.sk); |
2024 | 2027 | ||
2025 | if (match.sk) | 2028 | if (match.sk) |
2026 | sock_put(match.sk); | 2029 | sock_put(match.sk); |
@@ -2028,17 +2031,17 @@ int mgmt_powered(u16 index, u8 powered) | |||
2028 | return ret; | 2031 | return ret; |
2029 | } | 2032 | } |
2030 | 2033 | ||
2031 | int mgmt_discoverable(u16 index, u8 discoverable) | 2034 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) |
2032 | { | 2035 | { |
2033 | struct mgmt_mode ev; | 2036 | struct mgmt_mode ev; |
2034 | struct cmd_lookup match = { discoverable, NULL }; | 2037 | struct cmd_lookup match = { discoverable, NULL }; |
2035 | int ret; | 2038 | int ret; |
2036 | 2039 | ||
2037 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index, mode_rsp, &match); | 2040 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, mode_rsp, &match); |
2038 | 2041 | ||
2039 | ev.val = discoverable; | 2042 | ev.val = discoverable; |
2040 | 2043 | ||
2041 | ret = mgmt_event(MGMT_EV_DISCOVERABLE, index, &ev, sizeof(ev), | 2044 | ret = mgmt_event(MGMT_EV_DISCOVERABLE, hdev, &ev, sizeof(ev), |
2042 | match.sk); | 2045 | match.sk); |
2043 | 2046 | ||
2044 | if (match.sk) | 2047 | if (match.sk) |
@@ -2047,17 +2050,17 @@ int mgmt_discoverable(u16 index, u8 discoverable) | |||
2047 | return ret; | 2050 | return ret; |
2048 | } | 2051 | } |
2049 | 2052 | ||
2050 | int mgmt_connectable(u16 index, u8 connectable) | 2053 | int mgmt_connectable(struct hci_dev *hdev, u8 connectable) |
2051 | { | 2054 | { |
2052 | struct mgmt_mode ev; | 2055 | struct mgmt_mode ev; |
2053 | struct cmd_lookup match = { connectable, NULL }; | 2056 | struct cmd_lookup match = { connectable, NULL }; |
2054 | int ret; | 2057 | int ret; |
2055 | 2058 | ||
2056 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, mode_rsp, &match); | 2059 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, mode_rsp, &match); |
2057 | 2060 | ||
2058 | ev.val = connectable; | 2061 | ev.val = connectable; |
2059 | 2062 | ||
2060 | ret = mgmt_event(MGMT_EV_CONNECTABLE, index, &ev, sizeof(ev), match.sk); | 2063 | ret = mgmt_event(MGMT_EV_CONNECTABLE, hdev, &ev, sizeof(ev), match.sk); |
2061 | 2064 | ||
2062 | if (match.sk) | 2065 | if (match.sk) |
2063 | sock_put(match.sk); | 2066 | sock_put(match.sk); |
@@ -2065,20 +2068,21 @@ int mgmt_connectable(u16 index, u8 connectable) | |||
2065 | return ret; | 2068 | return ret; |
2066 | } | 2069 | } |
2067 | 2070 | ||
2068 | int mgmt_write_scan_failed(u16 index, u8 scan, u8 status) | 2071 | int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status) |
2069 | { | 2072 | { |
2070 | if (scan & SCAN_PAGE) | 2073 | if (scan & SCAN_PAGE) |
2071 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, | 2074 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, |
2072 | cmd_status_rsp, &status); | 2075 | cmd_status_rsp, &status); |
2073 | 2076 | ||
2074 | if (scan & SCAN_INQUIRY) | 2077 | if (scan & SCAN_INQUIRY) |
2075 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index, | 2078 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, |
2076 | cmd_status_rsp, &status); | 2079 | cmd_status_rsp, &status); |
2077 | 2080 | ||
2078 | return 0; | 2081 | return 0; |
2079 | } | 2082 | } |
2080 | 2083 | ||
2081 | int mgmt_new_link_key(u16 index, struct link_key *key, u8 persistent) | 2084 | int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, |
2085 | u8 persistent) | ||
2082 | { | 2086 | { |
2083 | struct mgmt_ev_new_link_key ev; | 2087 | struct mgmt_ev_new_link_key ev; |
2084 | 2088 | ||
@@ -2090,17 +2094,17 @@ int mgmt_new_link_key(u16 index, struct link_key *key, u8 persistent) | |||
2090 | memcpy(ev.key.val, key->val, 16); | 2094 | memcpy(ev.key.val, key->val, 16); |
2091 | ev.key.pin_len = key->pin_len; | 2095 | ev.key.pin_len = key->pin_len; |
2092 | 2096 | ||
2093 | return mgmt_event(MGMT_EV_NEW_LINK_KEY, index, &ev, sizeof(ev), NULL); | 2097 | return mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL); |
2094 | } | 2098 | } |
2095 | 2099 | ||
2096 | int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type) | 2100 | int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type) |
2097 | { | 2101 | { |
2098 | struct mgmt_addr_info ev; | 2102 | struct mgmt_addr_info ev; |
2099 | 2103 | ||
2100 | bacpy(&ev.bdaddr, bdaddr); | 2104 | bacpy(&ev.bdaddr, bdaddr); |
2101 | ev.type = link_to_mgmt(link_type); | 2105 | ev.type = link_to_mgmt(link_type); |
2102 | 2106 | ||
2103 | return mgmt_event(MGMT_EV_CONNECTED, index, &ev, sizeof(ev), NULL); | 2107 | return mgmt_event(MGMT_EV_CONNECTED, hdev, &ev, sizeof(ev), NULL); |
2104 | } | 2108 | } |
2105 | 2109 | ||
2106 | static void disconnect_rsp(struct pending_cmd *cmd, void *data) | 2110 | static void disconnect_rsp(struct pending_cmd *cmd, void *data) |
@@ -2119,18 +2123,18 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data) | |||
2119 | mgmt_pending_remove(cmd); | 2123 | mgmt_pending_remove(cmd); |
2120 | } | 2124 | } |
2121 | 2125 | ||
2122 | int mgmt_disconnected(u16 index, bdaddr_t *bdaddr, u8 type) | 2126 | int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) |
2123 | { | 2127 | { |
2124 | struct mgmt_addr_info ev; | 2128 | struct mgmt_addr_info ev; |
2125 | struct sock *sk = NULL; | 2129 | struct sock *sk = NULL; |
2126 | int err; | 2130 | int err; |
2127 | 2131 | ||
2128 | mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk); | 2132 | mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk); |
2129 | 2133 | ||
2130 | bacpy(&ev.bdaddr, bdaddr); | 2134 | bacpy(&ev.bdaddr, bdaddr); |
2131 | ev.type = link_to_mgmt(type); | 2135 | ev.type = link_to_mgmt(type); |
2132 | 2136 | ||
2133 | err = mgmt_event(MGMT_EV_DISCONNECTED, index, &ev, sizeof(ev), sk); | 2137 | err = mgmt_event(MGMT_EV_DISCONNECTED, hdev, &ev, sizeof(ev), sk); |
2134 | 2138 | ||
2135 | if (sk) | 2139 | if (sk) |
2136 | sock_put(sk); | 2140 | sock_put(sk); |
@@ -2138,23 +2142,24 @@ int mgmt_disconnected(u16 index, bdaddr_t *bdaddr, u8 type) | |||
2138 | return err; | 2142 | return err; |
2139 | } | 2143 | } |
2140 | 2144 | ||
2141 | int mgmt_disconnect_failed(u16 index) | 2145 | int mgmt_disconnect_failed(struct hci_dev *hdev) |
2142 | { | 2146 | { |
2143 | struct pending_cmd *cmd; | 2147 | struct pending_cmd *cmd; |
2144 | int err; | 2148 | int err; |
2145 | 2149 | ||
2146 | cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, index); | 2150 | cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev->id); |
2147 | if (!cmd) | 2151 | if (!cmd) |
2148 | return -ENOENT; | 2152 | return -ENOENT; |
2149 | 2153 | ||
2150 | err = cmd_status(cmd->sk, index, MGMT_OP_DISCONNECT, EIO); | 2154 | err = cmd_status(cmd->sk, hdev->id, MGMT_OP_DISCONNECT, EIO); |
2151 | 2155 | ||
2152 | mgmt_pending_remove(cmd); | 2156 | mgmt_pending_remove(cmd); |
2153 | 2157 | ||
2154 | return err; | 2158 | return err; |
2155 | } | 2159 | } |
2156 | 2160 | ||
2157 | int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 type, u8 status) | 2161 | int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type, |
2162 | u8 status) | ||
2158 | { | 2163 | { |
2159 | struct mgmt_ev_connect_failed ev; | 2164 | struct mgmt_ev_connect_failed ev; |
2160 | 2165 | ||
@@ -2162,34 +2167,35 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 type, u8 status) | |||
2162 | ev.addr.type = link_to_mgmt(type); | 2167 | ev.addr.type = link_to_mgmt(type); |
2163 | ev.status = status; | 2168 | ev.status = status; |
2164 | 2169 | ||
2165 | return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL); | 2170 | return mgmt_event(MGMT_EV_CONNECT_FAILED, hdev, &ev, sizeof(ev), NULL); |
2166 | } | 2171 | } |
2167 | 2172 | ||
2168 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure) | 2173 | int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure) |
2169 | { | 2174 | { |
2170 | struct mgmt_ev_pin_code_request ev; | 2175 | struct mgmt_ev_pin_code_request ev; |
2171 | 2176 | ||
2172 | bacpy(&ev.bdaddr, bdaddr); | 2177 | bacpy(&ev.bdaddr, bdaddr); |
2173 | ev.secure = secure; | 2178 | ev.secure = secure; |
2174 | 2179 | ||
2175 | return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev), | 2180 | return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, hdev, &ev, sizeof(ev), |
2176 | NULL); | 2181 | NULL); |
2177 | } | 2182 | } |
2178 | 2183 | ||
2179 | int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2184 | int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2185 | u8 status) | ||
2180 | { | 2186 | { |
2181 | struct pending_cmd *cmd; | 2187 | struct pending_cmd *cmd; |
2182 | struct mgmt_rp_pin_code_reply rp; | 2188 | struct mgmt_rp_pin_code_reply rp; |
2183 | int err; | 2189 | int err; |
2184 | 2190 | ||
2185 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, index); | 2191 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev->id); |
2186 | if (!cmd) | 2192 | if (!cmd) |
2187 | return -ENOENT; | 2193 | return -ENOENT; |
2188 | 2194 | ||
2189 | bacpy(&rp.bdaddr, bdaddr); | 2195 | bacpy(&rp.bdaddr, bdaddr); |
2190 | rp.status = status; | 2196 | rp.status = status; |
2191 | 2197 | ||
2192 | err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_REPLY, &rp, | 2198 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, &rp, |
2193 | sizeof(rp)); | 2199 | sizeof(rp)); |
2194 | 2200 | ||
2195 | mgmt_pending_remove(cmd); | 2201 | mgmt_pending_remove(cmd); |
@@ -2197,20 +2203,21 @@ int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | |||
2197 | return err; | 2203 | return err; |
2198 | } | 2204 | } |
2199 | 2205 | ||
2200 | int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2206 | int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2207 | u8 status) | ||
2201 | { | 2208 | { |
2202 | struct pending_cmd *cmd; | 2209 | struct pending_cmd *cmd; |
2203 | struct mgmt_rp_pin_code_reply rp; | 2210 | struct mgmt_rp_pin_code_reply rp; |
2204 | int err; | 2211 | int err; |
2205 | 2212 | ||
2206 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, index); | 2213 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev->id); |
2207 | if (!cmd) | 2214 | if (!cmd) |
2208 | return -ENOENT; | 2215 | return -ENOENT; |
2209 | 2216 | ||
2210 | bacpy(&rp.bdaddr, bdaddr); | 2217 | bacpy(&rp.bdaddr, bdaddr); |
2211 | rp.status = status; | 2218 | rp.status = status; |
2212 | 2219 | ||
2213 | err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, &rp, | 2220 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY, &rp, |
2214 | sizeof(rp)); | 2221 | sizeof(rp)); |
2215 | 2222 | ||
2216 | mgmt_pending_remove(cmd); | 2223 | mgmt_pending_remove(cmd); |
@@ -2218,97 +2225,95 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | |||
2218 | return err; | 2225 | return err; |
2219 | } | 2226 | } |
2220 | 2227 | ||
2221 | int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value, | 2228 | int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2222 | u8 confirm_hint) | 2229 | __le32 value, u8 confirm_hint) |
2223 | { | 2230 | { |
2224 | struct mgmt_ev_user_confirm_request ev; | 2231 | struct mgmt_ev_user_confirm_request ev; |
2225 | 2232 | ||
2226 | BT_DBG("hci%u", index); | 2233 | BT_DBG("%s", hdev->name); |
2227 | 2234 | ||
2228 | bacpy(&ev.bdaddr, bdaddr); | 2235 | bacpy(&ev.bdaddr, bdaddr); |
2229 | ev.confirm_hint = confirm_hint; | 2236 | ev.confirm_hint = confirm_hint; |
2230 | put_unaligned_le32(value, &ev.value); | 2237 | put_unaligned_le32(value, &ev.value); |
2231 | 2238 | ||
2232 | return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev), | 2239 | return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, hdev, &ev, sizeof(ev), |
2233 | NULL); | 2240 | NULL); |
2234 | } | 2241 | } |
2235 | 2242 | ||
2236 | static int confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status, | 2243 | static int confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2237 | u8 opcode) | 2244 | u8 status, u8 opcode) |
2238 | { | 2245 | { |
2239 | struct pending_cmd *cmd; | 2246 | struct pending_cmd *cmd; |
2240 | struct mgmt_rp_user_confirm_reply rp; | 2247 | struct mgmt_rp_user_confirm_reply rp; |
2241 | int err; | 2248 | int err; |
2242 | 2249 | ||
2243 | cmd = mgmt_pending_find(opcode, index); | 2250 | cmd = mgmt_pending_find(opcode, hdev->id); |
2244 | if (!cmd) | 2251 | if (!cmd) |
2245 | return -ENOENT; | 2252 | return -ENOENT; |
2246 | 2253 | ||
2247 | bacpy(&rp.bdaddr, bdaddr); | 2254 | bacpy(&rp.bdaddr, bdaddr); |
2248 | rp.status = status; | 2255 | rp.status = status; |
2249 | err = cmd_complete(cmd->sk, index, opcode, &rp, sizeof(rp)); | 2256 | err = cmd_complete(cmd->sk, hdev->id, opcode, &rp, sizeof(rp)); |
2250 | 2257 | ||
2251 | mgmt_pending_remove(cmd); | 2258 | mgmt_pending_remove(cmd); |
2252 | 2259 | ||
2253 | return err; | 2260 | return err; |
2254 | } | 2261 | } |
2255 | 2262 | ||
2256 | int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2263 | int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2264 | u8 status) | ||
2257 | { | 2265 | { |
2258 | return confirm_reply_complete(index, bdaddr, status, | 2266 | return confirm_reply_complete(hdev, bdaddr, status, |
2259 | MGMT_OP_USER_CONFIRM_REPLY); | 2267 | MGMT_OP_USER_CONFIRM_REPLY); |
2260 | } | 2268 | } |
2261 | 2269 | ||
2262 | int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2270 | int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, |
2271 | bdaddr_t *bdaddr, u8 status) | ||
2263 | { | 2272 | { |
2264 | return confirm_reply_complete(index, bdaddr, status, | 2273 | return confirm_reply_complete(hdev, bdaddr, status, |
2265 | MGMT_OP_USER_CONFIRM_NEG_REPLY); | 2274 | MGMT_OP_USER_CONFIRM_NEG_REPLY); |
2266 | } | 2275 | } |
2267 | 2276 | ||
2268 | int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status) | 2277 | int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status) |
2269 | { | 2278 | { |
2270 | struct mgmt_ev_auth_failed ev; | 2279 | struct mgmt_ev_auth_failed ev; |
2271 | 2280 | ||
2272 | bacpy(&ev.bdaddr, bdaddr); | 2281 | bacpy(&ev.bdaddr, bdaddr); |
2273 | ev.status = status; | 2282 | ev.status = status; |
2274 | 2283 | ||
2275 | return mgmt_event(MGMT_EV_AUTH_FAILED, index, &ev, sizeof(ev), NULL); | 2284 | return mgmt_event(MGMT_EV_AUTH_FAILED, hdev, &ev, sizeof(ev), NULL); |
2276 | } | 2285 | } |
2277 | 2286 | ||
2278 | int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status) | 2287 | int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) |
2279 | { | 2288 | { |
2280 | struct pending_cmd *cmd; | 2289 | struct pending_cmd *cmd; |
2281 | struct hci_dev *hdev; | ||
2282 | struct mgmt_cp_set_local_name ev; | 2290 | struct mgmt_cp_set_local_name ev; |
2283 | int err; | 2291 | int err; |
2284 | 2292 | ||
2285 | memset(&ev, 0, sizeof(ev)); | 2293 | memset(&ev, 0, sizeof(ev)); |
2286 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); | 2294 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); |
2287 | 2295 | ||
2288 | cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, index); | 2296 | cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev->id); |
2289 | if (!cmd) | 2297 | if (!cmd) |
2290 | goto send_event; | 2298 | goto send_event; |
2291 | 2299 | ||
2292 | if (status) { | 2300 | if (status) { |
2293 | err = cmd_status(cmd->sk, index, MGMT_OP_SET_LOCAL_NAME, EIO); | 2301 | err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, |
2302 | EIO); | ||
2294 | goto failed; | 2303 | goto failed; |
2295 | } | 2304 | } |
2296 | 2305 | ||
2297 | hdev = hci_dev_get(index); | 2306 | hci_dev_lock_bh(hdev); |
2298 | if (hdev) { | 2307 | update_eir(hdev); |
2299 | hci_dev_lock_bh(hdev); | 2308 | hci_dev_unlock_bh(hdev); |
2300 | update_eir(hdev); | ||
2301 | hci_dev_unlock_bh(hdev); | ||
2302 | hci_dev_put(hdev); | ||
2303 | } | ||
2304 | 2309 | ||
2305 | err = cmd_complete(cmd->sk, index, MGMT_OP_SET_LOCAL_NAME, &ev, | 2310 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, &ev, |
2306 | sizeof(ev)); | 2311 | sizeof(ev)); |
2307 | if (err < 0) | 2312 | if (err < 0) |
2308 | goto failed; | 2313 | goto failed; |
2309 | 2314 | ||
2310 | send_event: | 2315 | send_event: |
2311 | err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, index, &ev, sizeof(ev), | 2316 | err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev), |
2312 | cmd ? cmd->sk : NULL); | 2317 | cmd ? cmd->sk : NULL); |
2313 | 2318 | ||
2314 | failed: | 2319 | failed: |
@@ -2317,29 +2322,30 @@ failed: | |||
2317 | return err; | 2322 | return err; |
2318 | } | 2323 | } |
2319 | 2324 | ||
2320 | int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, | 2325 | int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, |
2321 | u8 status) | 2326 | u8 *randomizer, u8 status) |
2322 | { | 2327 | { |
2323 | struct pending_cmd *cmd; | 2328 | struct pending_cmd *cmd; |
2324 | int err; | 2329 | int err; |
2325 | 2330 | ||
2326 | BT_DBG("hci%u status %u", index, status); | 2331 | BT_DBG("%s status %u", hdev->name, status); |
2327 | 2332 | ||
2328 | cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index); | 2333 | cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev->id); |
2329 | if (!cmd) | 2334 | if (!cmd) |
2330 | return -ENOENT; | 2335 | return -ENOENT; |
2331 | 2336 | ||
2332 | if (status) { | 2337 | if (status) { |
2333 | err = cmd_status(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | 2338 | err = cmd_status(cmd->sk, hdev->id, |
2334 | EIO); | 2339 | MGMT_OP_READ_LOCAL_OOB_DATA, EIO); |
2335 | } else { | 2340 | } else { |
2336 | struct mgmt_rp_read_local_oob_data rp; | 2341 | struct mgmt_rp_read_local_oob_data rp; |
2337 | 2342 | ||
2338 | memcpy(rp.hash, hash, sizeof(rp.hash)); | 2343 | memcpy(rp.hash, hash, sizeof(rp.hash)); |
2339 | memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer)); | 2344 | memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer)); |
2340 | 2345 | ||
2341 | err = cmd_complete(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | 2346 | err = cmd_complete(cmd->sk, hdev->id, |
2342 | &rp, sizeof(rp)); | 2347 | MGMT_OP_READ_LOCAL_OOB_DATA, |
2348 | &rp, sizeof(rp)); | ||
2343 | } | 2349 | } |
2344 | 2350 | ||
2345 | mgmt_pending_remove(cmd); | 2351 | mgmt_pending_remove(cmd); |
@@ -2347,8 +2353,8 @@ int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, | |||
2347 | return err; | 2353 | return err; |
2348 | } | 2354 | } |
2349 | 2355 | ||
2350 | int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 type, u8 *dev_class, | 2356 | int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type, |
2351 | s8 rssi, u8 *eir) | 2357 | u8 *dev_class, s8 rssi, u8 *eir) |
2352 | { | 2358 | { |
2353 | struct mgmt_ev_device_found ev; | 2359 | struct mgmt_ev_device_found ev; |
2354 | 2360 | ||
@@ -2364,10 +2370,10 @@ int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 type, u8 *dev_class, | |||
2364 | if (dev_class) | 2370 | if (dev_class) |
2365 | memcpy(ev.dev_class, dev_class, sizeof(ev.dev_class)); | 2371 | memcpy(ev.dev_class, dev_class, sizeof(ev.dev_class)); |
2366 | 2372 | ||
2367 | return mgmt_event(MGMT_EV_DEVICE_FOUND, index, &ev, sizeof(ev), NULL); | 2373 | return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, &ev, sizeof(ev), NULL); |
2368 | } | 2374 | } |
2369 | 2375 | ||
2370 | int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name) | 2376 | int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name) |
2371 | { | 2377 | { |
2372 | struct mgmt_ev_remote_name ev; | 2378 | struct mgmt_ev_remote_name ev; |
2373 | 2379 | ||
@@ -2376,64 +2382,64 @@ int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name) | |||
2376 | bacpy(&ev.bdaddr, bdaddr); | 2382 | bacpy(&ev.bdaddr, bdaddr); |
2377 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); | 2383 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); |
2378 | 2384 | ||
2379 | return mgmt_event(MGMT_EV_REMOTE_NAME, index, &ev, sizeof(ev), NULL); | 2385 | return mgmt_event(MGMT_EV_REMOTE_NAME, hdev, &ev, sizeof(ev), NULL); |
2380 | } | 2386 | } |
2381 | 2387 | ||
2382 | int mgmt_inquiry_failed(u16 index, u8 status) | 2388 | int mgmt_inquiry_failed(struct hci_dev *hdev, u8 status) |
2383 | { | 2389 | { |
2384 | struct pending_cmd *cmd; | 2390 | struct pending_cmd *cmd; |
2385 | int err; | 2391 | int err; |
2386 | 2392 | ||
2387 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, index); | 2393 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev->id); |
2388 | if (!cmd) | 2394 | if (!cmd) |
2389 | return -ENOENT; | 2395 | return -ENOENT; |
2390 | 2396 | ||
2391 | err = cmd_status(cmd->sk, index, cmd->opcode, status); | 2397 | err = cmd_status(cmd->sk, hdev->id, cmd->opcode, status); |
2392 | mgmt_pending_remove(cmd); | 2398 | mgmt_pending_remove(cmd); |
2393 | 2399 | ||
2394 | return err; | 2400 | return err; |
2395 | } | 2401 | } |
2396 | 2402 | ||
2397 | int mgmt_discovering(u16 index, u8 discovering) | 2403 | int mgmt_discovering(struct hci_dev *hdev, u8 discovering) |
2398 | { | 2404 | { |
2399 | struct pending_cmd *cmd; | 2405 | struct pending_cmd *cmd; |
2400 | 2406 | ||
2401 | if (discovering) | 2407 | if (discovering) |
2402 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, index); | 2408 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev->id); |
2403 | else | 2409 | else |
2404 | cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, index); | 2410 | cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev->id); |
2405 | 2411 | ||
2406 | if (cmd != NULL) { | 2412 | if (cmd != NULL) { |
2407 | cmd_complete(cmd->sk, index, cmd->opcode, NULL, 0); | 2413 | cmd_complete(cmd->sk, hdev->id, cmd->opcode, NULL, 0); |
2408 | mgmt_pending_remove(cmd); | 2414 | mgmt_pending_remove(cmd); |
2409 | } | 2415 | } |
2410 | 2416 | ||
2411 | return mgmt_event(MGMT_EV_DISCOVERING, index, &discovering, | 2417 | return mgmt_event(MGMT_EV_DISCOVERING, hdev, &discovering, |
2412 | sizeof(discovering), NULL); | 2418 | sizeof(discovering), NULL); |
2413 | } | 2419 | } |
2414 | 2420 | ||
2415 | int mgmt_device_blocked(u16 index, bdaddr_t *bdaddr) | 2421 | int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr) |
2416 | { | 2422 | { |
2417 | struct pending_cmd *cmd; | 2423 | struct pending_cmd *cmd; |
2418 | struct mgmt_ev_device_blocked ev; | 2424 | struct mgmt_ev_device_blocked ev; |
2419 | 2425 | ||
2420 | cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, index); | 2426 | cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, hdev->id); |
2421 | 2427 | ||
2422 | bacpy(&ev.bdaddr, bdaddr); | 2428 | bacpy(&ev.bdaddr, bdaddr); |
2423 | 2429 | ||
2424 | return mgmt_event(MGMT_EV_DEVICE_BLOCKED, index, &ev, sizeof(ev), | 2430 | return mgmt_event(MGMT_EV_DEVICE_BLOCKED, hdev, &ev, sizeof(ev), |
2425 | cmd ? cmd->sk : NULL); | 2431 | cmd ? cmd->sk : NULL); |
2426 | } | 2432 | } |
2427 | 2433 | ||
2428 | int mgmt_device_unblocked(u16 index, bdaddr_t *bdaddr) | 2434 | int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr) |
2429 | { | 2435 | { |
2430 | struct pending_cmd *cmd; | 2436 | struct pending_cmd *cmd; |
2431 | struct mgmt_ev_device_unblocked ev; | 2437 | struct mgmt_ev_device_unblocked ev; |
2432 | 2438 | ||
2433 | cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, index); | 2439 | cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, hdev->id); |
2434 | 2440 | ||
2435 | bacpy(&ev.bdaddr, bdaddr); | 2441 | bacpy(&ev.bdaddr, bdaddr); |
2436 | 2442 | ||
2437 | return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, index, &ev, sizeof(ev), | 2443 | return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &ev, sizeof(ev), |
2438 | cmd ? cmd->sk : NULL); | 2444 | cmd ? cmd->sk : NULL); |
2439 | } | 2445 | } |