This attempts to cleanup the hci_conn if it cannot be aborted as otherwise it would likely result in having the controller and host stack out of sync with respect to connection handle.
Unified · Split
| @@ -1156,7 +1156,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role); · 1155 unmodified lines | ||
| 1156 | 1156 | |
| 1157 | 1157 | void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); |
| 1158 | 1158 | |
| 1159 | −void hci_le_conn_failed(struct hci_conn *conn, u8 status); | |
| 1159 | +void hci_conn_failed(struct hci_conn *conn, u8 status); | |
| 1160 | 1160 | |
| 1161 | 1161 | /* |
| 1162 | 1162 | * hci_conn_get() and hci_conn_put() are used to control the life-time of an |
| @@ -670,7 +670,7 @@ static void le_conn_timeout(struct work_struct *work) · 669 unmodified lines | ||
| 670 | 670 | /* Disable LE Advertising */ |
| 671 | 671 | le_disable_advertising(hdev); |
| 672 | 672 | hci_dev_lock(hdev); |
| 673 | − hci_le_conn_failed(conn, HCI_ERROR_ADVERTISING_TIMEOUT); | |
| 673 | + hci_conn_failed(conn, HCI_ERROR_ADVERTISING_TIMEOUT); | |
| 674 | 674 | hci_dev_unlock(hdev); |
| 675 | 675 | return; |
| 676 | 676 | } |
| @@ -873,7 +873,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src, uint8_t src_type) · 196 unmodified lines | ||
| 873 | 873 | EXPORT_SYMBOL(hci_get_route); |
| 874 | 874 | |
| 875 | 875 | /* This function requires the caller holds hdev->lock */ |
| 876 | −void hci_le_conn_failed(struct hci_conn *conn, u8 status) | |
| 876 | +static void hci_le_conn_failed(struct hci_conn *conn, u8 status) | |
| 877 | 877 | { |
| 878 | 878 | struct hci_dev *hdev = conn->hdev; |
| 879 | 879 | struct hci_conn_params *params; |
| @@ -886,8 +886,6 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status) · 6 unmodified lines | ||
| 886 | 886 | params->conn = NULL; |
| 887 | 887 | } |
| 888 | 888 | |
| 889 | − conn->state = BT_CLOSED; | |
| 890 | − | |
| 891 | 889 | /* If the status indicates successful cancellation of |
| 892 | 890 | * the attempt (i.e. Unknown Connection Id) there's no point of |
| 893 | 891 | * notifying failure since we'll go back to keep trying to |
| @@ -899,10 +897,6 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status) · 5 unmodified lines | ||
| 899 | 897 | mgmt_connect_failed(hdev, &conn->dst, conn->type, |
| 900 | 898 | conn->dst_type, status); |
| 901 | 899 | |
| 902 | − hci_connect_cfm(conn, status); | |
| 903 | − | |
| 904 | − hci_conn_del(conn); | |
| 905 | − | |
| 906 | 900 | /* Since we may have temporarily stopped the background scanning in |
| 907 | 901 | * favor of connection establishment, we should restart it. |
| 908 | 902 | */ |
| @@ -914,6 +908,28 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status) · 5 unmodified lines | ||
| 914 | 908 | hci_enable_advertising(hdev); |
| 915 | 909 | } |
| 916 | 910 | |
| 911 | +/* This function requires the caller holds hdev->lock */ | |
| 912 | +void hci_conn_failed(struct hci_conn *conn, u8 status) | |
| 913 | +{ | |
| 914 | + struct hci_dev *hdev = conn->hdev; | |
| 915 | + | |
| 916 | + bt_dev_dbg(hdev, "status 0x%2.2x", status); | |
| 917 | + | |
| 918 | + switch (conn->type) { | |
| 919 | + case LE_LINK: | |
| 920 | + hci_le_conn_failed(conn, status); | |
| 921 | + break; | |
| 922 | + case ACL_LINK: | |
| 923 | + mgmt_connect_failed(hdev, &conn->dst, conn->type, | |
| 924 | + conn->dst_type, status); | |
| 925 | + break; | |
| 926 | + } | |
| 927 | + | |
| 928 | + conn->state = BT_CLOSED; | |
| 929 | + hci_connect_cfm(conn, status); | |
| 930 | + hci_conn_del(conn); | |
| 931 | +} | |
| 932 | + | |
| 917 | 933 | static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err) |
| 918 | 934 | { |
| 919 | 935 | struct hci_conn *conn = data; |
| @@ -2834,7 +2834,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status) · 2833 unmodified lines | ||
| 2834 | 2834 | bt_dev_dbg(hdev, "status 0x%2.2x", status); |
| 2835 | 2835 | |
| 2836 | 2836 | /* All connection failure handling is taken care of by the |
| 2837 | − * hci_le_conn_failed function which is triggered by the HCI | |
| 2837 | + * hci_conn_failed function which is triggered by the HCI | |
| 2838 | 2838 | * request completion callbacks used for connecting. |
| 2839 | 2839 | */ |
| 2840 | 2840 | if (status) |
| @@ -2859,7 +2859,7 @@ static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status) · 18 unmodified lines | ||
| 2859 | 2859 | bt_dev_dbg(hdev, "status 0x%2.2x", status); |
| 2860 | 2860 | |
| 2861 | 2861 | /* All connection failure handling is taken care of by the |
| 2862 | − * hci_le_conn_failed function which is triggered by the HCI | |
| 2862 | + * hci_conn_failed function which is triggered by the HCI | |
| 2863 | 2863 | * request completion callbacks used for connecting. |
| 2864 | 2864 | */ |
| 2865 | 2865 | if (status) |
| @@ -3179,12 +3179,7 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, · 313 unmodified lines | ||
| 3179 | 3179 | |
| 3180 | 3180 | done: |
| 3181 | 3181 | if (status) { |
| 3182 | − conn->state = BT_CLOSED; | |
| 3183 | − if (conn->type == ACL_LINK) | |
| 3184 | − mgmt_connect_failed(hdev, &conn->dst, conn->type, | |
| 3185 | − conn->dst_type, status); | |
| 3186 | − hci_connect_cfm(conn, status); | |
| 3187 | − hci_conn_del(conn); | |
| 3182 | + hci_conn_failed(conn, status); | |
| 3188 | 3183 | } else if (ev->link_type == SCO_LINK) { |
| 3189 | 3184 | switch (conn->setting & SCO_AIRMODE_MASK) { |
| 3190 | 3185 | case SCO_AIRMODE_CVSD: |
| @@ -5623,7 +5618,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, · 2432 unmodified lines | ||
| 5623 | 5618 | } |
| 5624 | 5619 | |
| 5625 | 5620 | if (status) { |
| 5626 | − hci_le_conn_failed(conn, status); | |
| 5621 | + hci_conn_failed(conn, status); | |
| 5627 | 5622 | goto unlock; |
| 5628 | 5623 | } |
| 5629 | 5624 | |
| @@ -4408,12 +4408,21 @@ static int hci_reject_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, · 4407 unmodified lines | ||
| 4408 | 4408 | static int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, |
| 4409 | 4409 | u8 reason) |
| 4410 | 4410 | { |
| 4411 | + int err; | |
| 4412 | + | |
| 4411 | 4413 | switch (conn->state) { |
| 4412 | 4414 | case BT_CONNECTED: |
| 4413 | 4415 | case BT_CONFIG: |
| 4414 | 4416 | return hci_disconnect_sync(hdev, conn, reason); |
| 4415 | 4417 | case BT_CONNECT: |
| 4416 | − return hci_connect_cancel_sync(hdev, conn); | |
| 4418 | + err = hci_connect_cancel_sync(hdev, conn); | |
| 4419 | + /* Cleanup hci_conn object if it cannot be cancelled as it | |
| 4420 | + * likelly means the controller and host stack are out of sync. | |
| 4421 | + */ | |
| 4422 | + if (err) | |
| 4423 | + hci_conn_failed(conn, err); | |
| 4424 | + | |
| 4425 | + return err; | |
| 4417 | 4426 | case BT_CONNECT2: |
| 4418 | 4427 | return hci_reject_conn_sync(hdev, conn, reason); |
| 4419 | 4428 | default: |