aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2011-11-08 13:40:16 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-11-09 09:33:46 -0500
commit56e5cb86eb377970825486a5861f5926d65e64c1 (patch)
tree87e57ea9c98f2663a359717b658c05d0ee2fecac /net/bluetooth
parent2e58ef3e11d0775795345a20185b5a7c4bdae194 (diff)
Bluetooth: Add missing hci_dev locking when calling mgmt functions
Now that the pending commands are within struct hci_dev we can properly control access to them throught the hci_dev locking mechanism. 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.c12
-rw-r--r--net/bluetooth/hci_event.c45
-rw-r--r--net/bluetooth/mgmt.c13
3 files changed, 57 insertions, 13 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e5cf01396773..f87bf242539e 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -549,8 +549,11 @@ int hci_dev_open(__u16 dev)
549 hci_dev_hold(hdev); 549 hci_dev_hold(hdev);
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 hci_dev_lock_bh(hdev);
553 mgmt_powered(hdev, 1); 554 mgmt_powered(hdev, 1);
555 hci_dev_unlock_bh(hdev);
556 }
554 } else { 557 } else {
555 /* Init failed, cleanup */ 558 /* Init failed, cleanup */
556 tasklet_kill(&hdev->rx_task); 559 tasklet_kill(&hdev->rx_task);
@@ -642,7 +645,9 @@ static int hci_dev_do_close(struct hci_dev *hdev)
642 * and no tasks are scheduled. */ 645 * and no tasks are scheduled. */
643 hdev->close(hdev); 646 hdev->close(hdev);
644 647
648 hci_dev_lock_bh(hdev);
645 mgmt_powered(hdev, 0); 649 mgmt_powered(hdev, 0);
650 hci_dev_unlock_bh(hdev);
646 651
647 /* Clear flags */ 652 /* Clear flags */
648 hdev->flags = 0; 653 hdev->flags = 0;
@@ -1561,8 +1566,11 @@ void hci_unregister_dev(struct hci_dev *hdev)
1561 kfree_skb(hdev->reassembly[i]); 1566 kfree_skb(hdev->reassembly[i]);
1562 1567
1563 if (!test_bit(HCI_INIT, &hdev->flags) && 1568 if (!test_bit(HCI_INIT, &hdev->flags) &&
1564 !test_bit(HCI_SETUP, &hdev->flags)) 1569 !test_bit(HCI_SETUP, &hdev->flags)) {
1570 hci_dev_lock_bh(hdev);
1565 mgmt_index_removed(hdev); 1571 mgmt_index_removed(hdev);
1572 hci_dev_unlock_bh(hdev);
1573 }
1566 1574
1567 /* mgmt_index_removed should take care of emptying the 1575 /* mgmt_index_removed should take care of emptying the
1568 * pending list */ 1576 * pending list */
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8303f8fa1821..a89cf1f24e47 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -60,7 +60,9 @@ 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 hci_dev_lock(hdev);
63 mgmt_discovering(hdev, 0); 64 mgmt_discovering(hdev, 0);
65 hci_dev_unlock(hdev);
64 66
65 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); 67 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
66 68
@@ -201,13 +203,15 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
201 if (!sent) 203 if (!sent)
202 return; 204 return;
203 205
206 hci_dev_lock(hdev);
207
204 if (test_bit(HCI_MGMT, &hdev->flags)) 208 if (test_bit(HCI_MGMT, &hdev->flags))
205 mgmt_set_local_name_complete(hdev, sent, status); 209 mgmt_set_local_name_complete(hdev, sent, status);
206 210
207 if (status) 211 if (status == 0)
208 return; 212 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
209 213
210 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH); 214 hci_dev_unlock(hdev);
211} 215}
212 216
213static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) 217static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
@@ -282,6 +286,8 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
282 286
283 param = *((__u8 *) sent); 287 param = *((__u8 *) sent);
284 288
289 hci_dev_lock(hdev);
290
285 if (status != 0) { 291 if (status != 0) {
286 mgmt_write_scan_failed(hdev, param, status); 292 mgmt_write_scan_failed(hdev, param, status);
287 hdev->discov_timeout = 0; 293 hdev->discov_timeout = 0;
@@ -311,6 +317,7 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
311 mgmt_connectable(hdev, 0); 317 mgmt_connectable(hdev, 0);
312 318
313done: 319done:
320 hci_dev_unlock(hdev);
314 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status); 321 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
315} 322}
316 323
@@ -834,19 +841,24 @@ static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
834 841
835 BT_DBG("%s status 0x%x", hdev->name, rp->status); 842 BT_DBG("%s status 0x%x", hdev->name, rp->status);
836 843
844 hci_dev_lock(hdev);
845
837 if (test_bit(HCI_MGMT, &hdev->flags)) 846 if (test_bit(HCI_MGMT, &hdev->flags))
838 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); 847 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
839 848
840 if (rp->status != 0) 849 if (rp->status != 0)
841 return; 850 goto unlock;
842 851
843 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); 852 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
844 if (!cp) 853 if (!cp)
845 return; 854 goto unlock;
846 855
847 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 856 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
848 if (conn) 857 if (conn)
849 conn->pin_length = cp->pin_len; 858 conn->pin_length = cp->pin_len;
859
860unlock:
861 hci_dev_unlock(hdev);
850} 862}
851 863
852static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) 864static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
@@ -855,10 +867,15 @@ static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
855 867
856 BT_DBG("%s status 0x%x", hdev->name, rp->status); 868 BT_DBG("%s status 0x%x", hdev->name, rp->status);
857 869
870 hci_dev_lock(hdev);
871
858 if (test_bit(HCI_MGMT, &hdev->flags)) 872 if (test_bit(HCI_MGMT, &hdev->flags))
859 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, 873 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
860 rp->status); 874 rp->status);
875
876 hci_dev_unlock(hdev);
861} 877}
878
862static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, 879static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
863 struct sk_buff *skb) 880 struct sk_buff *skb)
864{ 881{
@@ -885,9 +902,13 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
885 902
886 BT_DBG("%s status 0x%x", hdev->name, rp->status); 903 BT_DBG("%s status 0x%x", hdev->name, rp->status);
887 904
905 hci_dev_lock(hdev);
906
888 if (test_bit(HCI_MGMT, &hdev->flags)) 907 if (test_bit(HCI_MGMT, &hdev->flags))
889 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, 908 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr,
890 rp->status); 909 rp->status);
910
911 hci_dev_unlock(hdev);
891} 912}
892 913
893static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, 914static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
@@ -897,9 +918,13 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
897 918
898 BT_DBG("%s status 0x%x", hdev->name, rp->status); 919 BT_DBG("%s status 0x%x", hdev->name, rp->status);
899 920
921 hci_dev_lock(hdev);
922
900 if (test_bit(HCI_MGMT, &hdev->flags)) 923 if (test_bit(HCI_MGMT, &hdev->flags))
901 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr, 924 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
902 rp->status); 925 rp->status);
926
927 hci_dev_unlock(hdev);
903} 928}
904 929
905static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, 930static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
@@ -909,8 +934,10 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
909 934
910 BT_DBG("%s status 0x%x", hdev->name, rp->status); 935 BT_DBG("%s status 0x%x", hdev->name, rp->status);
911 936
937 hci_dev_lock(hdev);
912 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash, 938 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
913 rp->randomizer, rp->status); 939 rp->randomizer, rp->status);
940 hci_dev_unlock(hdev);
914} 941}
915 942
916static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, 943static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
@@ -985,14 +1012,18 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
985 if (status) { 1012 if (status) {
986 hci_req_complete(hdev, HCI_OP_INQUIRY, status); 1013 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
987 hci_conn_check_pending(hdev); 1014 hci_conn_check_pending(hdev);
1015 hci_dev_lock(hdev);
988 if (test_bit(HCI_MGMT, &hdev->flags)) 1016 if (test_bit(HCI_MGMT, &hdev->flags))
989 mgmt_inquiry_failed(hdev, status); 1017 mgmt_inquiry_failed(hdev, status);
1018 hci_dev_unlock(hdev);
990 return; 1019 return;
991 } 1020 }
992 1021
993 set_bit(HCI_INQUIRY, &hdev->flags); 1022 set_bit(HCI_INQUIRY, &hdev->flags);
994 1023
1024 hci_dev_lock(hdev);
995 mgmt_discovering(hdev, 1); 1025 mgmt_discovering(hdev, 1);
1026 hci_dev_unlock(hdev);
996} 1027}
997 1028
998static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) 1029static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
@@ -1378,7 +1409,9 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff
1378 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) 1409 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1379 return; 1410 return;
1380 1411
1412 hci_dev_lock(hdev);
1381 mgmt_discovering(hdev, 0); 1413 mgmt_discovering(hdev, 0);
1414 hci_dev_unlock(hdev);
1382} 1415}
1383 1416
1384static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) 1417static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
@@ -1572,7 +1605,9 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
1572 BT_DBG("%s status %d", hdev->name, ev->status); 1605 BT_DBG("%s status %d", hdev->name, ev->status);
1573 1606
1574 if (ev->status) { 1607 if (ev->status) {
1608 hci_dev_lock(hdev);
1575 mgmt_disconnect_failed(hdev); 1609 mgmt_disconnect_failed(hdev);
1610 hci_dev_unlock(hdev);
1576 return; 1611 return;
1577 } 1612 }
1578 1613
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index be198f382ed8..be4c3d03d808 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1335,16 +1335,19 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status)
1335static void pairing_complete_cb(struct hci_conn *conn, u8 status) 1335static void pairing_complete_cb(struct hci_conn *conn, u8 status)
1336{ 1336{
1337 struct pending_cmd *cmd; 1337 struct pending_cmd *cmd;
1338 struct hci_dev *hdev = conn->hdev;
1338 1339
1339 BT_DBG("status %u", status); 1340 BT_DBG("status %u", status);
1340 1341
1342 hci_dev_lock_bh(hdev);
1343
1341 cmd = find_pairing(conn); 1344 cmd = find_pairing(conn);
1342 if (!cmd) { 1345 if (!cmd)
1343 BT_DBG("Unable to find a pending command"); 1346 BT_DBG("Unable to find a pending command");
1344 return; 1347 else
1345 } 1348 pairing_complete(cmd, status);
1346 1349
1347 pairing_complete(cmd, status); 1350 hci_dev_unlock_bh(hdev);
1348} 1351}
1349 1352
1350static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len) 1353static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len)
@@ -2302,9 +2305,7 @@ int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status)
2302 goto failed; 2305 goto failed;
2303 } 2306 }
2304 2307
2305 hci_dev_lock_bh(hdev);
2306 update_eir(hdev); 2308 update_eir(hdev);
2307 hci_dev_unlock_bh(hdev);
2308 2309
2309 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, &ev, 2310 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, &ev,
2310 sizeof(ev)); 2311 sizeof(ev));