diff options
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_conn.c | 8 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 14 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 17 |
3 files changed, 35 insertions, 4 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index b50dabb3f86a..faff6247ac8f 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -589,6 +589,14 @@ EXPORT_SYMBOL(hci_get_route); | |||
589 | void hci_le_conn_failed(struct hci_conn *conn, u8 status) | 589 | void hci_le_conn_failed(struct hci_conn *conn, u8 status) |
590 | { | 590 | { |
591 | struct hci_dev *hdev = conn->hdev; | 591 | struct hci_dev *hdev = conn->hdev; |
592 | struct hci_conn_params *params; | ||
593 | |||
594 | params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst, | ||
595 | conn->dst_type); | ||
596 | if (params && params->conn) { | ||
597 | hci_conn_drop(params->conn); | ||
598 | params->conn = NULL; | ||
599 | } | ||
592 | 600 | ||
593 | conn->state = BT_CLOSED; | 601 | conn->state = BT_CLOSED; |
594 | 602 | ||
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index abeb5e47311e..9b7145959a49 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -2538,8 +2538,13 @@ static void hci_pend_le_actions_clear(struct hci_dev *hdev) | |||
2538 | { | 2538 | { |
2539 | struct hci_conn_params *p; | 2539 | struct hci_conn_params *p; |
2540 | 2540 | ||
2541 | list_for_each_entry(p, &hdev->le_conn_params, list) | 2541 | list_for_each_entry(p, &hdev->le_conn_params, list) { |
2542 | if (p->conn) { | ||
2543 | hci_conn_drop(p->conn); | ||
2544 | p->conn = NULL; | ||
2545 | } | ||
2542 | list_del_init(&p->action); | 2546 | list_del_init(&p->action); |
2547 | } | ||
2543 | 2548 | ||
2544 | BT_DBG("All LE pending actions cleared"); | 2549 | BT_DBG("All LE pending actions cleared"); |
2545 | } | 2550 | } |
@@ -2580,8 +2585,8 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
2580 | 2585 | ||
2581 | hci_dev_lock(hdev); | 2586 | hci_dev_lock(hdev); |
2582 | hci_inquiry_cache_flush(hdev); | 2587 | hci_inquiry_cache_flush(hdev); |
2583 | hci_conn_hash_flush(hdev); | ||
2584 | hci_pend_le_actions_clear(hdev); | 2588 | hci_pend_le_actions_clear(hdev); |
2589 | hci_conn_hash_flush(hdev); | ||
2585 | hci_dev_unlock(hdev); | 2590 | hci_dev_unlock(hdev); |
2586 | 2591 | ||
2587 | hci_notify(hdev, HCI_DEV_DOWN); | 2592 | hci_notify(hdev, HCI_DEV_DOWN); |
@@ -3729,6 +3734,9 @@ void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) | |||
3729 | if (!params) | 3734 | if (!params) |
3730 | return; | 3735 | return; |
3731 | 3736 | ||
3737 | if (params->conn) | ||
3738 | hci_conn_drop(params->conn); | ||
3739 | |||
3732 | list_del(¶ms->action); | 3740 | list_del(¶ms->action); |
3733 | list_del(¶ms->list); | 3741 | list_del(¶ms->list); |
3734 | kfree(params); | 3742 | kfree(params); |
@@ -3759,6 +3767,8 @@ void hci_conn_params_clear_all(struct hci_dev *hdev) | |||
3759 | struct hci_conn_params *params, *tmp; | 3767 | struct hci_conn_params *params, *tmp; |
3760 | 3768 | ||
3761 | list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { | 3769 | list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { |
3770 | if (params->conn) | ||
3771 | hci_conn_drop(params->conn); | ||
3762 | list_del(¶ms->action); | 3772 | list_del(¶ms->action); |
3763 | list_del(¶ms->list); | 3773 | list_del(¶ms->list); |
3764 | kfree(params); | 3774 | kfree(params); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index da7ab6b9bb69..3a99f30a3317 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -4226,8 +4226,13 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
4226 | hci_proto_connect_cfm(conn, ev->status); | 4226 | hci_proto_connect_cfm(conn, ev->status); |
4227 | 4227 | ||
4228 | params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); | 4228 | params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); |
4229 | if (params) | 4229 | if (params) { |
4230 | list_del_init(¶ms->action); | 4230 | list_del_init(¶ms->action); |
4231 | if (params->conn) { | ||
4232 | hci_conn_drop(params->conn); | ||
4233 | params->conn = NULL; | ||
4234 | } | ||
4235 | } | ||
4231 | 4236 | ||
4232 | unlock: | 4237 | unlock: |
4233 | hci_update_background_scan(hdev); | 4238 | hci_update_background_scan(hdev); |
@@ -4309,8 +4314,16 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, | |||
4309 | 4314 | ||
4310 | conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, | 4315 | conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, |
4311 | HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER); | 4316 | HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER); |
4312 | if (!IS_ERR(conn)) | 4317 | if (!IS_ERR(conn)) { |
4318 | /* Store the pointer since we don't really have any | ||
4319 | * other owner of the object besides the params that | ||
4320 | * triggered it. This way we can abort the connection if | ||
4321 | * the parameters get removed and keep the reference | ||
4322 | * count consistent once the connection is established. | ||
4323 | */ | ||
4324 | params->conn = conn; | ||
4313 | return; | 4325 | return; |
4326 | } | ||
4314 | 4327 | ||
4315 | switch (PTR_ERR(conn)) { | 4328 | switch (PTR_ERR(conn)) { |
4316 | case -EBUSY: | 4329 | case -EBUSY: |