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 | void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); | 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 | * hci_conn_get() and hci_conn_put() are used to control the life-time of an | 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 | /* Disable LE Advertising */ | 670 | /* Disable LE Advertising */ |
| 671 | le_disable_advertising(hdev); | 671 | le_disable_advertising(hdev); |
| 672 | hci_dev_lock(hdev); | 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 | hci_dev_unlock(hdev); | 674 | hci_dev_unlock(hdev); |
| 675 | return; | 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 | EXPORT_SYMBOL(hci_get_route); | 873 | EXPORT_SYMBOL(hci_get_route); |
| 874 | 874 | ||
| 875 | /* This function requires the caller holds hdev->lock */ | 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 | struct hci_dev *hdev = conn->hdev; | 878 | struct hci_dev *hdev = conn->hdev; |
| 879 | struct hci_conn_params *params; | 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 | params->conn = NULL; | 886 | params->conn = NULL; |
| 887 | } | 887 | } |
| 888 | 888 | ||
| 889 | conn->state = BT_CLOSED; | ||
| 890 | |||
| 891 | /* If the status indicates successful cancellation of | 889 | /* If the status indicates successful cancellation of |
| 892 | * the attempt (i.e. Unknown Connection Id) there's no point of | 890 | * the attempt (i.e. Unknown Connection Id) there's no point of |
| 893 | * notifying failure since we'll go back to keep trying to | 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 | mgmt_connect_failed(hdev, &conn->dst, conn->type, | 897 | mgmt_connect_failed(hdev, &conn->dst, conn->type, |
| 900 | conn->dst_type, status); | 898 | conn->dst_type, status); |
| 901 | 899 | ||
| 902 | hci_connect_cfm(conn, status); | ||
| 903 | |||
| 904 | hci_conn_del(conn); | ||
| 905 | |||
| 906 | /* Since we may have temporarily stopped the background scanning in | 900 | /* Since we may have temporarily stopped the background scanning in |
| 907 | * favor of connection establishment, we should restart it. | 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 | hci_enable_advertising(hdev); | 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 | static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err) | 933 | static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err) |
| 918 | { | 934 | { |
| 919 | struct hci_conn *conn = data; | 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 | bt_dev_dbg(hdev, "status 0x%2.2x", status); | 2834 | bt_dev_dbg(hdev, "status 0x%2.2x", status); |
| 2835 | 2835 | ||
| 2836 | /* All connection failure handling is taken care of by the | 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 | * request completion callbacks used for connecting. | 2838 | * request completion callbacks used for connecting. |
| 2839 | */ | 2839 | */ |
| 2840 | if (status) | 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 | bt_dev_dbg(hdev, "status 0x%2.2x", status); | 2859 | bt_dev_dbg(hdev, "status 0x%2.2x", status); |
| 2860 | 2860 | ||
| 2861 | /* All connection failure handling is taken care of by the | 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 | * request completion callbacks used for connecting. | 2863 | * request completion callbacks used for connecting. |
| 2864 | */ | 2864 | */ |
| 2865 | if (status) | 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 | done: | 3180 | done: |
| 3181 | if (status) { | 3181 | if (status) { |
| 3182 | conn->state = BT_CLOSED; | 3182 | hci_conn_failed(conn, status); |
| 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); | ||
| 3188 | } else if (ev->link_type == SCO_LINK) { | 3183 | } else if (ev->link_type == SCO_LINK) { |
| 3189 | switch (conn->setting & SCO_AIRMODE_MASK) { | 3184 | switch (conn->setting & SCO_AIRMODE_MASK) { |
| 3190 | case SCO_AIRMODE_CVSD: | 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 | if (status) { | 5620 | if (status) { |
| 5626 | hci_le_conn_failed(conn, status); | 5621 | hci_conn_failed(conn, status); |
| 5627 | goto unlock; | 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 | static int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, | 4408 | static int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, |
| 4409 | u8 reason) | 4409 | u8 reason) |
| 4410 | { | 4410 | { |
| 4411 | int err; | ||
| 4412 | |||
| 4411 | switch (conn->state) { | 4413 | switch (conn->state) { |
| 4412 | case BT_CONNECTED: | 4414 | case BT_CONNECTED: |
| 4413 | case BT_CONFIG: | 4415 | case BT_CONFIG: |
| 4414 | return hci_disconnect_sync(hdev, conn, reason); | 4416 | return hci_disconnect_sync(hdev, conn, reason); |
| 4415 | case BT_CONNECT: | 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 | case BT_CONNECT2: | 4426 | case BT_CONNECT2: |
| 4418 | return hci_reject_conn_sync(hdev, conn, reason); | 4427 | return hci_reject_conn_sync(hdev, conn, reason); |
| 4419 | default: | 4428 | default: |