aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/nfc/core.c')
-rw-r--r--net/nfc/core.c81
1 files changed, 61 insertions, 20 deletions
diff --git a/net/nfc/core.c b/net/nfc/core.c
index 3192c3f589ee..7df28ad4727f 100644
--- a/net/nfc/core.c
+++ b/net/nfc/core.c
@@ -97,7 +97,7 @@ int nfc_dev_down(struct nfc_dev *dev)
97 goto error; 97 goto error;
98 } 98 }
99 99
100 if (dev->polling || dev->activated_target_idx != NFC_TARGET_IDX_NONE) { 100 if (dev->polling || dev->active_target) {
101 rc = -EBUSY; 101 rc = -EBUSY;
102 goto error; 102 goto error;
103 } 103 }
@@ -183,11 +183,27 @@ error:
183 return rc; 183 return rc;
184} 184}
185 185
186static struct nfc_target *nfc_find_target(struct nfc_dev *dev, u32 target_idx)
187{
188 int i;
189
190 if (dev->n_targets == 0)
191 return NULL;
192
193 for (i = 0; i < dev->n_targets ; i++) {
194 if (dev->targets[i].idx == target_idx)
195 return &dev->targets[i];
196 }
197
198 return NULL;
199}
200
186int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode) 201int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode)
187{ 202{
188 int rc = 0; 203 int rc = 0;
189 u8 *gb; 204 u8 *gb;
190 size_t gb_len; 205 size_t gb_len;
206 struct nfc_target *target;
191 207
192 pr_debug("dev_name=%s comm %d\n", dev_name(&dev->dev), comm_mode); 208 pr_debug("dev_name=%s comm %d\n", dev_name(&dev->dev), comm_mode);
193 209
@@ -212,9 +228,15 @@ int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode)
212 goto error; 228 goto error;
213 } 229 }
214 230
215 rc = dev->ops->dep_link_up(dev, target_index, comm_mode, gb, gb_len); 231 target = nfc_find_target(dev, target_index);
232 if (target == NULL) {
233 rc = -ENOTCONN;
234 goto error;
235 }
236
237 rc = dev->ops->dep_link_up(dev, target, comm_mode, gb, gb_len);
216 if (!rc) 238 if (!rc)
217 dev->activated_target_idx = target_index; 239 dev->active_target = target;
218 240
219error: 241error:
220 device_unlock(&dev->dev); 242 device_unlock(&dev->dev);
@@ -250,7 +272,7 @@ int nfc_dep_link_down(struct nfc_dev *dev)
250 rc = dev->ops->dep_link_down(dev); 272 rc = dev->ops->dep_link_down(dev);
251 if (!rc) { 273 if (!rc) {
252 dev->dep_link_up = false; 274 dev->dep_link_up = false;
253 dev->activated_target_idx = NFC_TARGET_IDX_NONE; 275 dev->active_target = NULL;
254 nfc_llcp_mac_is_down(dev); 276 nfc_llcp_mac_is_down(dev);
255 nfc_genl_dep_link_down_event(dev); 277 nfc_genl_dep_link_down_event(dev);
256 } 278 }
@@ -282,6 +304,7 @@ EXPORT_SYMBOL(nfc_dep_link_is_up);
282int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol) 304int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol)
283{ 305{
284 int rc; 306 int rc;
307 struct nfc_target *target;
285 308
286 pr_debug("dev_name=%s target_idx=%u protocol=%u\n", 309 pr_debug("dev_name=%s target_idx=%u protocol=%u\n",
287 dev_name(&dev->dev), target_idx, protocol); 310 dev_name(&dev->dev), target_idx, protocol);
@@ -293,9 +316,20 @@ int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol)
293 goto error; 316 goto error;
294 } 317 }
295 318
296 rc = dev->ops->activate_target(dev, target_idx, protocol); 319 if (dev->active_target) {
320 rc = -EBUSY;
321 goto error;
322 }
323
324 target = nfc_find_target(dev, target_idx);
325 if (target == NULL) {
326 rc = -ENOTCONN;
327 goto error;
328 }
329
330 rc = dev->ops->activate_target(dev, target, protocol);
297 if (!rc) { 331 if (!rc) {
298 dev->activated_target_idx = target_idx; 332 dev->active_target = target;
299 333
300 if (dev->ops->check_presence) 334 if (dev->ops->check_presence)
301 mod_timer(&dev->check_pres_timer, jiffies + 335 mod_timer(&dev->check_pres_timer, jiffies +
@@ -327,11 +361,21 @@ int nfc_deactivate_target(struct nfc_dev *dev, u32 target_idx)
327 goto error; 361 goto error;
328 } 362 }
329 363
364 if (dev->active_target == NULL) {
365 rc = -ENOTCONN;
366 goto error;
367 }
368
369 if (dev->active_target->idx != target_idx) {
370 rc = -ENOTCONN;
371 goto error;
372 }
373
330 if (dev->ops->check_presence) 374 if (dev->ops->check_presence)
331 del_timer_sync(&dev->check_pres_timer); 375 del_timer_sync(&dev->check_pres_timer);
332 376
333 dev->ops->deactivate_target(dev, target_idx); 377 dev->ops->deactivate_target(dev, dev->active_target);
334 dev->activated_target_idx = NFC_TARGET_IDX_NONE; 378 dev->active_target = NULL;
335 379
336error: 380error:
337 device_unlock(&dev->dev); 381 device_unlock(&dev->dev);
@@ -365,13 +409,13 @@ int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb,
365 goto error; 409 goto error;
366 } 410 }
367 411
368 if (dev->activated_target_idx == NFC_TARGET_IDX_NONE) { 412 if (dev->active_target == NULL) {
369 rc = -ENOTCONN; 413 rc = -ENOTCONN;
370 kfree_skb(skb); 414 kfree_skb(skb);
371 goto error; 415 goto error;
372 } 416 }
373 417
374 if (target_idx != dev->activated_target_idx) { 418 if (dev->active_target->idx != target_idx) {
375 rc = -EADDRNOTAVAIL; 419 rc = -EADDRNOTAVAIL;
376 kfree_skb(skb); 420 kfree_skb(skb);
377 goto error; 421 goto error;
@@ -380,7 +424,8 @@ int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb,
380 if (dev->ops->check_presence) 424 if (dev->ops->check_presence)
381 del_timer_sync(&dev->check_pres_timer); 425 del_timer_sync(&dev->check_pres_timer);
382 426
383 rc = dev->ops->data_exchange(dev, target_idx, skb, cb, cb_context); 427 rc = dev->ops->data_exchange(dev, dev->active_target, skb, cb,
428 cb_context);
384 429
385 if (!rc && dev->ops->check_presence) 430 if (!rc && dev->ops->check_presence)
386 mod_timer(&dev->check_pres_timer, jiffies + 431 mod_timer(&dev->check_pres_timer, jiffies +
@@ -514,7 +559,7 @@ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx)
514 559
515 dev->targets_generation++; 560 dev->targets_generation++;
516 dev->n_targets--; 561 dev->n_targets--;
517 dev->activated_target_idx = NFC_TARGET_IDX_NONE; 562 dev->active_target = NULL;
518 563
519 if (dev->n_targets) { 564 if (dev->n_targets) {
520 memcpy(&dev->targets[i], &dev->targets[i + 1], 565 memcpy(&dev->targets[i], &dev->targets[i + 1],
@@ -556,15 +601,14 @@ static void nfc_check_pres_work(struct work_struct *work)
556 601
557 device_lock(&dev->dev); 602 device_lock(&dev->dev);
558 603
559 if (dev->activated_target_idx != NFC_TARGET_IDX_NONE && 604 if (dev->active_target && timer_pending(&dev->check_pres_timer) == 0) {
560 timer_pending(&dev->check_pres_timer) == 0) { 605 rc = dev->ops->check_presence(dev, dev->active_target);
561 rc = dev->ops->check_presence(dev, dev->activated_target_idx);
562 if (!rc) { 606 if (!rc) {
563 mod_timer(&dev->check_pres_timer, jiffies + 607 mod_timer(&dev->check_pres_timer, jiffies +
564 msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); 608 msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS));
565 } else { 609 } else {
566 nfc_target_lost(dev, dev->activated_target_idx); 610 nfc_target_lost(dev, dev->active_target->idx);
567 dev->activated_target_idx = NFC_TARGET_IDX_NONE; 611 dev->active_target = NULL;
568 } 612 }
569 } 613 }
570 614
@@ -643,8 +687,6 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
643 /* first generation must not be 0 */ 687 /* first generation must not be 0 */
644 dev->targets_generation = 1; 688 dev->targets_generation = 1;
645 689
646 dev->activated_target_idx = NFC_TARGET_IDX_NONE;
647
648 if (ops->check_presence) { 690 if (ops->check_presence) {
649 char name[32]; 691 char name[32];
650 init_timer(&dev->check_pres_timer); 692 init_timer(&dev->check_pres_timer);
@@ -662,7 +704,6 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
662 } 704 }
663 } 705 }
664 706
665
666 return dev; 707 return dev;
667} 708}
668EXPORT_SYMBOL(nfc_allocate_device); 709EXPORT_SYMBOL(nfc_allocate_device);