diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/nfc/nci/core.c | 47 | ||||
-rw-r--r-- | net/nfc/nci/data.c | 56 | ||||
-rw-r--r-- | net/nfc/nci/ntf.c | 37 | ||||
-rw-r--r-- | net/nfc/nci/rsp.c | 20 |
4 files changed, 127 insertions, 33 deletions
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 51feb5e63008..eb607970bd56 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c | |||
@@ -45,6 +45,19 @@ static void nci_cmd_work(struct work_struct *work); | |||
45 | static void nci_rx_work(struct work_struct *work); | 45 | static void nci_rx_work(struct work_struct *work); |
46 | static void nci_tx_work(struct work_struct *work); | 46 | static void nci_tx_work(struct work_struct *work); |
47 | 47 | ||
48 | struct nci_conn_info *nci_get_conn_info_by_conn_id(struct nci_dev *ndev, | ||
49 | int conn_id) | ||
50 | { | ||
51 | struct nci_conn_info *conn_info; | ||
52 | |||
53 | list_for_each_entry(conn_info, &ndev->conn_info_list, list) { | ||
54 | if (conn_info->conn_id == conn_id) | ||
55 | return conn_info; | ||
56 | } | ||
57 | |||
58 | return NULL; | ||
59 | } | ||
60 | |||
48 | /* ---- NCI requests ---- */ | 61 | /* ---- NCI requests ---- */ |
49 | 62 | ||
50 | void nci_req_complete(struct nci_dev *ndev, int result) | 63 | void nci_req_complete(struct nci_dev *ndev, int result) |
@@ -712,6 +725,11 @@ static int nci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, | |||
712 | { | 725 | { |
713 | struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); | 726 | struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); |
714 | int rc; | 727 | int rc; |
728 | struct nci_conn_info *conn_info; | ||
729 | |||
730 | conn_info = nci_get_conn_info_by_conn_id(ndev, NCI_STATIC_RF_CONN_ID); | ||
731 | if (!conn_info) | ||
732 | return -EPROTO; | ||
715 | 733 | ||
716 | pr_debug("target_idx %d, len %d\n", target->idx, skb->len); | 734 | pr_debug("target_idx %d, len %d\n", target->idx, skb->len); |
717 | 735 | ||
@@ -724,8 +742,8 @@ static int nci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, | |||
724 | return -EBUSY; | 742 | return -EBUSY; |
725 | 743 | ||
726 | /* store cb and context to be used on receiving data */ | 744 | /* store cb and context to be used on receiving data */ |
727 | ndev->data_exchange_cb = cb; | 745 | conn_info->data_exchange_cb = cb; |
728 | ndev->data_exchange_cb_context = cb_context; | 746 | conn_info->data_exchange_cb_context = cb_context; |
729 | 747 | ||
730 | rc = nci_send_data(ndev, NCI_STATIC_RF_CONN_ID, skb); | 748 | rc = nci_send_data(ndev, NCI_STATIC_RF_CONN_ID, skb); |
731 | if (rc) | 749 | if (rc) |
@@ -913,6 +931,7 @@ int nci_register_device(struct nci_dev *ndev) | |||
913 | (unsigned long) ndev); | 931 | (unsigned long) ndev); |
914 | 932 | ||
915 | mutex_init(&ndev->req_lock); | 933 | mutex_init(&ndev->req_lock); |
934 | INIT_LIST_HEAD(&ndev->conn_info_list); | ||
916 | 935 | ||
917 | rc = nfc_register_device(ndev->nfc_dev); | 936 | rc = nfc_register_device(ndev->nfc_dev); |
918 | if (rc) | 937 | if (rc) |
@@ -938,12 +957,19 @@ EXPORT_SYMBOL(nci_register_device); | |||
938 | */ | 957 | */ |
939 | void nci_unregister_device(struct nci_dev *ndev) | 958 | void nci_unregister_device(struct nci_dev *ndev) |
940 | { | 959 | { |
960 | struct nci_conn_info *conn_info, *n; | ||
961 | |||
941 | nci_close_device(ndev); | 962 | nci_close_device(ndev); |
942 | 963 | ||
943 | destroy_workqueue(ndev->cmd_wq); | 964 | destroy_workqueue(ndev->cmd_wq); |
944 | destroy_workqueue(ndev->rx_wq); | 965 | destroy_workqueue(ndev->rx_wq); |
945 | destroy_workqueue(ndev->tx_wq); | 966 | destroy_workqueue(ndev->tx_wq); |
946 | 967 | ||
968 | list_for_each_entry_safe(conn_info, n, &ndev->conn_info_list, list) { | ||
969 | list_del(&conn_info->list); | ||
970 | /* conn_info is allocated with devm_kzalloc */ | ||
971 | } | ||
972 | |||
947 | nfc_unregister_device(ndev->nfc_dev); | 973 | nfc_unregister_device(ndev->nfc_dev); |
948 | } | 974 | } |
949 | EXPORT_SYMBOL(nci_unregister_device); | 975 | EXPORT_SYMBOL(nci_unregister_device); |
@@ -1027,20 +1053,25 @@ int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload) | |||
1027 | static void nci_tx_work(struct work_struct *work) | 1053 | static void nci_tx_work(struct work_struct *work) |
1028 | { | 1054 | { |
1029 | struct nci_dev *ndev = container_of(work, struct nci_dev, tx_work); | 1055 | struct nci_dev *ndev = container_of(work, struct nci_dev, tx_work); |
1056 | struct nci_conn_info *conn_info; | ||
1030 | struct sk_buff *skb; | 1057 | struct sk_buff *skb; |
1031 | 1058 | ||
1032 | pr_debug("credits_cnt %d\n", atomic_read(&ndev->credits_cnt)); | 1059 | conn_info = nci_get_conn_info_by_conn_id(ndev, ndev->cur_conn_id); |
1060 | if (!conn_info) | ||
1061 | return; | ||
1062 | |||
1063 | pr_debug("credits_cnt %d\n", atomic_read(&conn_info->credits_cnt)); | ||
1033 | 1064 | ||
1034 | /* Send queued tx data */ | 1065 | /* Send queued tx data */ |
1035 | while (atomic_read(&ndev->credits_cnt)) { | 1066 | while (atomic_read(&conn_info->credits_cnt)) { |
1036 | skb = skb_dequeue(&ndev->tx_q); | 1067 | skb = skb_dequeue(&ndev->tx_q); |
1037 | if (!skb) | 1068 | if (!skb) |
1038 | return; | 1069 | return; |
1039 | 1070 | ||
1040 | /* Check if data flow control is used */ | 1071 | /* Check if data flow control is used */ |
1041 | if (atomic_read(&ndev->credits_cnt) != | 1072 | if (atomic_read(&conn_info->credits_cnt) != |
1042 | NCI_DATA_FLOW_CONTROL_NOT_USED) | 1073 | NCI_DATA_FLOW_CONTROL_NOT_USED) |
1043 | atomic_dec(&ndev->credits_cnt); | 1074 | atomic_dec(&conn_info->credits_cnt); |
1044 | 1075 | ||
1045 | pr_debug("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d\n", | 1076 | pr_debug("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d\n", |
1046 | nci_pbf(skb->data), | 1077 | nci_pbf(skb->data), |
@@ -1092,7 +1123,9 @@ static void nci_rx_work(struct work_struct *work) | |||
1092 | if (test_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags)) { | 1123 | if (test_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags)) { |
1093 | /* complete the data exchange transaction, if exists */ | 1124 | /* complete the data exchange transaction, if exists */ |
1094 | if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) | 1125 | if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) |
1095 | nci_data_exchange_complete(ndev, NULL, -ETIMEDOUT); | 1126 | nci_data_exchange_complete(ndev, NULL, |
1127 | ndev->cur_conn_id, | ||
1128 | -ETIMEDOUT); | ||
1096 | 1129 | ||
1097 | clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags); | 1130 | clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags); |
1098 | } | 1131 | } |
diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c index a2de2a8cb00e..566466d90048 100644 --- a/net/nfc/nci/data.c +++ b/net/nfc/nci/data.c | |||
@@ -36,10 +36,20 @@ | |||
36 | 36 | ||
37 | /* Complete data exchange transaction and forward skb to nfc core */ | 37 | /* Complete data exchange transaction and forward skb to nfc core */ |
38 | void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, | 38 | void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, |
39 | int err) | 39 | __u8 conn_id, int err) |
40 | { | 40 | { |
41 | data_exchange_cb_t cb = ndev->data_exchange_cb; | 41 | struct nci_conn_info *conn_info; |
42 | void *cb_context = ndev->data_exchange_cb_context; | 42 | data_exchange_cb_t cb; |
43 | void *cb_context; | ||
44 | |||
45 | conn_info = nci_get_conn_info_by_conn_id(ndev, conn_id); | ||
46 | if (!conn_info) { | ||
47 | kfree_skb(skb); | ||
48 | goto exit; | ||
49 | } | ||
50 | |||
51 | cb = conn_info->data_exchange_cb; | ||
52 | cb_context = conn_info->data_exchange_cb_context; | ||
43 | 53 | ||
44 | pr_debug("len %d, err %d\n", skb ? skb->len : 0, err); | 54 | pr_debug("len %d, err %d\n", skb ? skb->len : 0, err); |
45 | 55 | ||
@@ -48,9 +58,6 @@ void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, | |||
48 | clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags); | 58 | clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags); |
49 | 59 | ||
50 | if (cb) { | 60 | if (cb) { |
51 | ndev->data_exchange_cb = NULL; | ||
52 | ndev->data_exchange_cb_context = NULL; | ||
53 | |||
54 | /* forward skb to nfc core */ | 61 | /* forward skb to nfc core */ |
55 | cb(cb_context, skb, err); | 62 | cb(cb_context, skb, err); |
56 | } else if (skb) { | 63 | } else if (skb) { |
@@ -60,6 +67,7 @@ void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, | |||
60 | kfree_skb(skb); | 67 | kfree_skb(skb); |
61 | } | 68 | } |
62 | 69 | ||
70 | exit: | ||
63 | clear_bit(NCI_DATA_EXCHANGE, &ndev->flags); | 71 | clear_bit(NCI_DATA_EXCHANGE, &ndev->flags); |
64 | } | 72 | } |
65 | 73 | ||
@@ -85,6 +93,7 @@ static inline void nci_push_data_hdr(struct nci_dev *ndev, | |||
85 | static int nci_queue_tx_data_frags(struct nci_dev *ndev, | 93 | static int nci_queue_tx_data_frags(struct nci_dev *ndev, |
86 | __u8 conn_id, | 94 | __u8 conn_id, |
87 | struct sk_buff *skb) { | 95 | struct sk_buff *skb) { |
96 | struct nci_conn_info *conn_info; | ||
88 | int total_len = skb->len; | 97 | int total_len = skb->len; |
89 | unsigned char *data = skb->data; | 98 | unsigned char *data = skb->data; |
90 | unsigned long flags; | 99 | unsigned long flags; |
@@ -95,11 +104,17 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev, | |||
95 | 104 | ||
96 | pr_debug("conn_id 0x%x, total_len %d\n", conn_id, total_len); | 105 | pr_debug("conn_id 0x%x, total_len %d\n", conn_id, total_len); |
97 | 106 | ||
107 | conn_info = nci_get_conn_info_by_conn_id(ndev, conn_id); | ||
108 | if (!conn_info) { | ||
109 | rc = -EPROTO; | ||
110 | goto free_exit; | ||
111 | } | ||
112 | |||
98 | __skb_queue_head_init(&frags_q); | 113 | __skb_queue_head_init(&frags_q); |
99 | 114 | ||
100 | while (total_len) { | 115 | while (total_len) { |
101 | frag_len = | 116 | frag_len = |
102 | min_t(int, total_len, ndev->max_data_pkt_payload_size); | 117 | min_t(int, total_len, conn_info->max_pkt_payload_len); |
103 | 118 | ||
104 | skb_frag = nci_skb_alloc(ndev, | 119 | skb_frag = nci_skb_alloc(ndev, |
105 | (NCI_DATA_HDR_SIZE + frag_len), | 120 | (NCI_DATA_HDR_SIZE + frag_len), |
@@ -151,12 +166,19 @@ exit: | |||
151 | /* Send NCI data */ | 166 | /* Send NCI data */ |
152 | int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb) | 167 | int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb) |
153 | { | 168 | { |
169 | struct nci_conn_info *conn_info; | ||
154 | int rc = 0; | 170 | int rc = 0; |
155 | 171 | ||
156 | pr_debug("conn_id 0x%x, plen %d\n", conn_id, skb->len); | 172 | pr_debug("conn_id 0x%x, plen %d\n", conn_id, skb->len); |
157 | 173 | ||
174 | conn_info = nci_get_conn_info_by_conn_id(ndev, conn_id); | ||
175 | if (!conn_info) { | ||
176 | rc = -EPROTO; | ||
177 | goto free_exit; | ||
178 | } | ||
179 | |||
158 | /* check if the packet need to be fragmented */ | 180 | /* check if the packet need to be fragmented */ |
159 | if (skb->len <= ndev->max_data_pkt_payload_size) { | 181 | if (skb->len <= conn_info->max_pkt_payload_len) { |
160 | /* no need to fragment packet */ | 182 | /* no need to fragment packet */ |
161 | nci_push_data_hdr(ndev, conn_id, skb, NCI_PBF_LAST); | 183 | nci_push_data_hdr(ndev, conn_id, skb, NCI_PBF_LAST); |
162 | 184 | ||
@@ -170,6 +192,7 @@ int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb) | |||
170 | } | 192 | } |
171 | } | 193 | } |
172 | 194 | ||
195 | ndev->cur_conn_id = conn_id; | ||
173 | queue_work(ndev->tx_wq, &ndev->tx_work); | 196 | queue_work(ndev->tx_wq, &ndev->tx_work); |
174 | 197 | ||
175 | goto exit; | 198 | goto exit; |
@@ -185,7 +208,7 @@ exit: | |||
185 | 208 | ||
186 | static void nci_add_rx_data_frag(struct nci_dev *ndev, | 209 | static void nci_add_rx_data_frag(struct nci_dev *ndev, |
187 | struct sk_buff *skb, | 210 | struct sk_buff *skb, |
188 | __u8 pbf, __u8 status) | 211 | __u8 pbf, __u8 conn_id, __u8 status) |
189 | { | 212 | { |
190 | int reassembly_len; | 213 | int reassembly_len; |
191 | int err = 0; | 214 | int err = 0; |
@@ -229,16 +252,13 @@ static void nci_add_rx_data_frag(struct nci_dev *ndev, | |||
229 | } | 252 | } |
230 | 253 | ||
231 | exit: | 254 | exit: |
232 | if (ndev->nfc_dev->rf_mode == NFC_RF_INITIATOR) { | 255 | if (ndev->nfc_dev->rf_mode == NFC_RF_TARGET) { |
233 | nci_data_exchange_complete(ndev, skb, err); | ||
234 | } else if (ndev->nfc_dev->rf_mode == NFC_RF_TARGET) { | ||
235 | /* Data received in Target mode, forward to nfc core */ | 256 | /* Data received in Target mode, forward to nfc core */ |
236 | err = nfc_tm_data_received(ndev->nfc_dev, skb); | 257 | err = nfc_tm_data_received(ndev->nfc_dev, skb); |
237 | if (err) | 258 | if (err) |
238 | pr_err("unable to handle received data\n"); | 259 | pr_err("unable to handle received data\n"); |
239 | } else { | 260 | } else { |
240 | pr_err("rf mode unknown\n"); | 261 | nci_data_exchange_complete(ndev, skb, conn_id, err); |
241 | kfree_skb(skb); | ||
242 | } | 262 | } |
243 | } | 263 | } |
244 | 264 | ||
@@ -247,6 +267,8 @@ void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
247 | { | 267 | { |
248 | __u8 pbf = nci_pbf(skb->data); | 268 | __u8 pbf = nci_pbf(skb->data); |
249 | __u8 status = 0; | 269 | __u8 status = 0; |
270 | __u8 conn_id = nci_conn_id(skb->data); | ||
271 | struct nci_conn_info *conn_info; | ||
250 | 272 | ||
251 | pr_debug("len %d\n", skb->len); | 273 | pr_debug("len %d\n", skb->len); |
252 | 274 | ||
@@ -255,6 +277,10 @@ void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
255 | nci_conn_id(skb->data), | 277 | nci_conn_id(skb->data), |
256 | nci_plen(skb->data)); | 278 | nci_plen(skb->data)); |
257 | 279 | ||
280 | conn_info = nci_get_conn_info_by_conn_id(ndev, nci_conn_id(skb->data)); | ||
281 | if (!conn_info) | ||
282 | return; | ||
283 | |||
258 | /* strip the nci data header */ | 284 | /* strip the nci data header */ |
259 | skb_pull(skb, NCI_DATA_HDR_SIZE); | 285 | skb_pull(skb, NCI_DATA_HDR_SIZE); |
260 | 286 | ||
@@ -268,5 +294,5 @@ void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
268 | skb_trim(skb, (skb->len - 1)); | 294 | skb_trim(skb, (skb->len - 1)); |
269 | } | 295 | } |
270 | 296 | ||
271 | nci_add_rx_data_frag(ndev, skb, pbf, nci_to_errno(status)); | 297 | nci_add_rx_data_frag(ndev, skb, pbf, conn_id, nci_to_errno(status)); |
272 | } | 298 | } |
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c index 22e453cb787d..28fdbe234bd4 100644 --- a/net/nfc/nci/ntf.c +++ b/net/nfc/nci/ntf.c | |||
@@ -43,6 +43,7 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, | |||
43 | struct sk_buff *skb) | 43 | struct sk_buff *skb) |
44 | { | 44 | { |
45 | struct nci_core_conn_credit_ntf *ntf = (void *) skb->data; | 45 | struct nci_core_conn_credit_ntf *ntf = (void *) skb->data; |
46 | struct nci_conn_info *conn_info; | ||
46 | int i; | 47 | int i; |
47 | 48 | ||
48 | pr_debug("num_entries %d\n", ntf->num_entries); | 49 | pr_debug("num_entries %d\n", ntf->num_entries); |
@@ -59,11 +60,13 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, | |||
59 | i, ntf->conn_entries[i].conn_id, | 60 | i, ntf->conn_entries[i].conn_id, |
60 | ntf->conn_entries[i].credits); | 61 | ntf->conn_entries[i].credits); |
61 | 62 | ||
62 | if (ntf->conn_entries[i].conn_id == NCI_STATIC_RF_CONN_ID) { | 63 | conn_info = nci_get_conn_info_by_conn_id(ndev, |
63 | /* found static rf connection */ | 64 | ntf->conn_entries[i].conn_id); |
64 | atomic_add(ntf->conn_entries[i].credits, | 65 | if (!conn_info) |
65 | &ndev->credits_cnt); | 66 | return; |
66 | } | 67 | |
68 | atomic_add(ntf->conn_entries[i].credits, | ||
69 | &conn_info->credits_cnt); | ||
67 | } | 70 | } |
68 | 71 | ||
69 | /* trigger the next tx */ | 72 | /* trigger the next tx */ |
@@ -96,7 +99,7 @@ static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev, | |||
96 | 99 | ||
97 | /* complete the data exchange transaction, if exists */ | 100 | /* complete the data exchange transaction, if exists */ |
98 | if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) | 101 | if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) |
99 | nci_data_exchange_complete(ndev, NULL, -EIO); | 102 | nci_data_exchange_complete(ndev, NULL, ntf->conn_id, -EIO); |
100 | } | 103 | } |
101 | 104 | ||
102 | static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, | 105 | static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, |
@@ -513,6 +516,7 @@ static int nci_store_general_bytes_nfc_dep(struct nci_dev *ndev, | |||
513 | static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, | 516 | static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, |
514 | struct sk_buff *skb) | 517 | struct sk_buff *skb) |
515 | { | 518 | { |
519 | struct nci_conn_info *conn_info; | ||
516 | struct nci_rf_intf_activated_ntf ntf; | 520 | struct nci_rf_intf_activated_ntf ntf; |
517 | __u8 *data = skb->data; | 521 | __u8 *data = skb->data; |
518 | int err = NCI_STATUS_OK; | 522 | int err = NCI_STATUS_OK; |
@@ -614,11 +618,17 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, | |||
614 | 618 | ||
615 | exit: | 619 | exit: |
616 | if (err == NCI_STATUS_OK) { | 620 | if (err == NCI_STATUS_OK) { |
617 | ndev->max_data_pkt_payload_size = ntf.max_data_pkt_payload_size; | 621 | conn_info = nci_get_conn_info_by_conn_id(ndev, |
618 | ndev->initial_num_credits = ntf.initial_num_credits; | 622 | NCI_STATIC_RF_CONN_ID); |
623 | if (!conn_info) | ||
624 | return; | ||
625 | |||
626 | conn_info->max_pkt_payload_len = ntf.max_data_pkt_payload_size; | ||
627 | conn_info->initial_num_credits = ntf.initial_num_credits; | ||
619 | 628 | ||
620 | /* set the available credits to initial value */ | 629 | /* set the available credits to initial value */ |
621 | atomic_set(&ndev->credits_cnt, ndev->initial_num_credits); | 630 | atomic_set(&conn_info->credits_cnt, |
631 | conn_info->initial_num_credits); | ||
622 | 632 | ||
623 | /* store general bytes to be reported later in dep_link_up */ | 633 | /* store general bytes to be reported later in dep_link_up */ |
624 | if (ntf.rf_interface == NCI_RF_INTERFACE_NFC_DEP) { | 634 | if (ntf.rf_interface == NCI_RF_INTERFACE_NFC_DEP) { |
@@ -661,10 +671,16 @@ exit: | |||
661 | static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, | 671 | static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, |
662 | struct sk_buff *skb) | 672 | struct sk_buff *skb) |
663 | { | 673 | { |
674 | struct nci_conn_info *conn_info; | ||
664 | struct nci_rf_deactivate_ntf *ntf = (void *) skb->data; | 675 | struct nci_rf_deactivate_ntf *ntf = (void *) skb->data; |
665 | 676 | ||
666 | pr_debug("entry, type 0x%x, reason 0x%x\n", ntf->type, ntf->reason); | 677 | pr_debug("entry, type 0x%x, reason 0x%x\n", ntf->type, ntf->reason); |
667 | 678 | ||
679 | conn_info = | ||
680 | nci_get_conn_info_by_conn_id(ndev, NCI_STATIC_RF_CONN_ID); | ||
681 | if (!conn_info) | ||
682 | return; | ||
683 | |||
668 | /* drop tx data queue */ | 684 | /* drop tx data queue */ |
669 | skb_queue_purge(&ndev->tx_q); | 685 | skb_queue_purge(&ndev->tx_q); |
670 | 686 | ||
@@ -676,7 +692,8 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, | |||
676 | 692 | ||
677 | /* complete the data exchange transaction, if exists */ | 693 | /* complete the data exchange transaction, if exists */ |
678 | if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) | 694 | if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) |
679 | nci_data_exchange_complete(ndev, NULL, -EIO); | 695 | nci_data_exchange_complete(ndev, NULL, NCI_STATIC_RF_CONN_ID, |
696 | -EIO); | ||
680 | 697 | ||
681 | switch (ntf->type) { | 698 | switch (ntf->type) { |
682 | case NCI_DEACTIVATE_TYPE_IDLE_MODE: | 699 | case NCI_DEACTIVATE_TYPE_IDLE_MODE: |
diff --git a/net/nfc/nci/rsp.c b/net/nfc/nci/rsp.c index 041de51ccdbe..93b914937263 100644 --- a/net/nfc/nci/rsp.c +++ b/net/nfc/nci/rsp.c | |||
@@ -140,13 +140,31 @@ static void nci_rf_disc_map_rsp_packet(struct nci_dev *ndev, | |||
140 | 140 | ||
141 | static void nci_rf_disc_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) | 141 | static void nci_rf_disc_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) |
142 | { | 142 | { |
143 | struct nci_conn_info *conn_info; | ||
143 | __u8 status = skb->data[0]; | 144 | __u8 status = skb->data[0]; |
144 | 145 | ||
145 | pr_debug("status 0x%x\n", status); | 146 | pr_debug("status 0x%x\n", status); |
146 | 147 | ||
147 | if (status == NCI_STATUS_OK) | 148 | if (status == NCI_STATUS_OK) { |
148 | atomic_set(&ndev->state, NCI_DISCOVERY); | 149 | atomic_set(&ndev->state, NCI_DISCOVERY); |
149 | 150 | ||
151 | conn_info = nci_get_conn_info_by_conn_id(ndev, | ||
152 | NCI_STATIC_RF_CONN_ID); | ||
153 | if (!conn_info) { | ||
154 | conn_info = devm_kzalloc(&ndev->nfc_dev->dev, | ||
155 | sizeof(struct nci_conn_info), | ||
156 | GFP_KERNEL); | ||
157 | if (!conn_info) { | ||
158 | status = NCI_STATUS_REJECTED; | ||
159 | goto exit; | ||
160 | } | ||
161 | conn_info->conn_id = NCI_STATIC_RF_CONN_ID; | ||
162 | INIT_LIST_HEAD(&conn_info->list); | ||
163 | list_add(&conn_info->list, &ndev->conn_info_list); | ||
164 | } | ||
165 | } | ||
166 | |||
167 | exit: | ||
150 | nci_req_complete(ndev, status); | 168 | nci_req_complete(ndev, status); |
151 | } | 169 | } |
152 | 170 | ||