aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_conn.c8
-rw-r--r--net/bluetooth/hci_core.c14
-rw-r--r--net/bluetooth/hci_event.c17
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);
589void hci_le_conn_failed(struct hci_conn *conn, u8 status) 589void 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(&params->action); 3740 list_del(&params->action);
3733 list_del(&params->list); 3741 list_del(&params->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(&params->action); 3772 list_del(&params->action);
3763 list_del(&params->list); 3773 list_del(&params->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(&params->action); 4230 list_del_init(&params->action);
4231 if (params->conn) {
4232 hci_conn_drop(params->conn);
4233 params->conn = NULL;
4234 }
4235 }
4231 4236
4232unlock: 4237unlock:
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: