X-Git-Url: http://git.cascardo.info/?a=blobdiff_plain;f=net%2Fbluetooth%2Fhci_event.c;h=3f2e8b830cbd1cf37b65431bfd76981bc2447dff;hb=6a8fc95c87110a466ee81675b41170b963f82bdb;hp=322abbbbcef991a36adaaf0750c723ceebba3147;hpb=7a02d089695a1217992434f03a78aa32bad85b5c;p=cascardo%2Flinux.git diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 322abbbbcef9..3f2e8b830cbd 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -242,7 +242,8 @@ static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) if (rp->status) return; - if (test_bit(HCI_SETUP, &hdev->dev_flags)) + if (test_bit(HCI_SETUP, &hdev->dev_flags) || + test_bit(HCI_CONFIG, &hdev->dev_flags)) memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH); } @@ -257,6 +258,8 @@ static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) if (!sent) return; + hci_dev_lock(hdev); + if (!status) { __u8 param = *((__u8 *) sent); @@ -268,6 +271,8 @@ static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_auth_enable_complete(hdev, status); + + hci_dev_unlock(hdev); } static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) @@ -443,6 +448,8 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) if (!sent) return; + hci_dev_lock(hdev); + if (!status) { if (sent->mode) hdev->features[1][0] |= LMP_HOST_SSP; @@ -458,6 +465,8 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) else clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); } + + hci_dev_unlock(hdev); } static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb) @@ -471,6 +480,8 @@ static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb) if (!sent) return; + hci_dev_lock(hdev); + if (!status) { if (sent->support) hdev->features[1][0] |= LMP_HOST_SC; @@ -486,6 +497,8 @@ static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb) else clear_bit(HCI_SC_ENABLED, &hdev->dev_flags); } + + hci_dev_unlock(hdev); } static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) @@ -497,7 +510,8 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) if (rp->status) return; - if (test_bit(HCI_SETUP, &hdev->dev_flags)) { + if (test_bit(HCI_SETUP, &hdev->dev_flags) || + test_bit(HCI_CONFIG, &hdev->dev_flags)) { hdev->hci_ver = rp->hci_ver; hdev->hci_rev = __le16_to_cpu(rp->hci_rev); hdev->lmp_ver = rp->lmp_ver; @@ -516,7 +530,8 @@ static void hci_cc_read_local_commands(struct hci_dev *hdev, if (rp->status) return; - if (test_bit(HCI_SETUP, &hdev->dev_flags)) + if (test_bit(HCI_SETUP, &hdev->dev_flags) || + test_bit(HCI_CONFIG, &hdev->dev_flags)) memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); } @@ -1135,6 +1150,8 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, if (!cp) return; + hci_dev_lock(hdev); + switch (cp->enable) { case LE_SCAN_ENABLE: set_bit(HCI_LE_SCAN, &hdev->dev_flags); @@ -1184,6 +1201,8 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable); break; } + + hci_dev_unlock(hdev); } static void hci_cc_le_read_white_list_size(struct hci_dev *hdev, @@ -1278,6 +1297,8 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev, if (!sent) return; + hci_dev_lock(hdev); + if (sent->le) { hdev->features[1][0] |= LMP_HOST_LE; set_bit(HCI_LE_ENABLED, &hdev->dev_flags); @@ -1291,6 +1312,8 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev, hdev->features[1][0] |= LMP_HOST_LE_BREDR; else hdev->features[1][0] &= ~LMP_HOST_LE_BREDR; + + hci_dev_unlock(hdev); } static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb) @@ -2174,7 +2197,12 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) return; } - if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags) && + /* Require HCI_CONNECTABLE or a whitelist entry to accept the + * connection. These features are only touched through mgmt so + * only do the checks if HCI_MGMT is set. + */ + if (test_bit(HCI_MGMT, &hdev->dev_flags) && + !test_bit(HCI_CONNECTABLE, &hdev->dev_flags) && !hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr, BDADDR_BREDR)) { hci_reject_conn(hdev, &ev->bdaddr);