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: |
