aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
authorEric Lapuyade <eric.lapuyade@intel.com>2012-05-07 06:31:15 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-05-15 17:28:00 -0400
commitd4ccb132801aeeb2cfd18c4b4b7fa0043ab37f80 (patch)
tree7f3372d3925e5cb69cb5db5867accee4d17ff9b8 /net/nfc
parentaddfabf98daad7b469ad788a622dbeab6aaaa330 (diff)
NFC: Specify usage for targets found and target lost events
It is now specified that nfc_target_found() and nfc_target_lost() core functions must not be called from an atomic context. This allow us to serialize calls and protect the targets table using the nfc device lock instead of a spinlock. Signed-off-by: Eric Lapuyade <eric.lapuyade@intel.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/nfc')
-rw-r--r--net/nfc/core.c35
-rw-r--r--net/nfc/netlink.c4
2 files changed, 28 insertions, 11 deletions
diff --git a/net/nfc/core.c b/net/nfc/core.c
index 7df28ad4727f..9f6ce011d35d 100644
--- a/net/nfc/core.c
+++ b/net/nfc/core.c
@@ -501,6 +501,9 @@ EXPORT_SYMBOL(nfc_alloc_recv_skb);
501 * The device driver must call this function when one or many nfc targets 501 * The device driver must call this function when one or many nfc targets
502 * are found. After calling this function, the device driver must stop 502 * are found. After calling this function, the device driver must stop
503 * polling for targets. 503 * polling for targets.
504 * IMPORTANT: this function must not be called from an atomic context.
505 * In addition, it must also not be called from a context that would prevent
506 * the NFC Core to call other nfc ops entry point concurrently.
504 */ 507 */
505int nfc_targets_found(struct nfc_dev *dev, 508int nfc_targets_found(struct nfc_dev *dev,
506 struct nfc_target *targets, int n_targets) 509 struct nfc_target *targets, int n_targets)
@@ -514,7 +517,7 @@ int nfc_targets_found(struct nfc_dev *dev,
514 for (i = 0; i < n_targets; i++) 517 for (i = 0; i < n_targets; i++)
515 targets[i].idx = dev->target_next_idx++; 518 targets[i].idx = dev->target_next_idx++;
516 519
517 spin_lock_bh(&dev->targets_lock); 520 device_lock(&dev->dev);
518 521
519 dev->targets_generation++; 522 dev->targets_generation++;
520 523
@@ -524,12 +527,12 @@ int nfc_targets_found(struct nfc_dev *dev,
524 527
525 if (!dev->targets) { 528 if (!dev->targets) {
526 dev->n_targets = 0; 529 dev->n_targets = 0;
527 spin_unlock_bh(&dev->targets_lock); 530 device_unlock(&dev->dev);
528 return -ENOMEM; 531 return -ENOMEM;
529 } 532 }
530 533
531 dev->n_targets = n_targets; 534 dev->n_targets = n_targets;
532 spin_unlock_bh(&dev->targets_lock); 535 device_unlock(&dev->dev);
533 536
534 nfc_genl_targets_found(dev); 537 nfc_genl_targets_found(dev);
535 538
@@ -537,6 +540,18 @@ int nfc_targets_found(struct nfc_dev *dev,
537} 540}
538EXPORT_SYMBOL(nfc_targets_found); 541EXPORT_SYMBOL(nfc_targets_found);
539 542
543/**
544 * nfc_target_lost - inform that an activated target went out of field
545 *
546 * @dev: The nfc device that had the activated target in field
547 * @target_idx: the nfc index of the target
548 *
549 * The device driver must call this function when the activated target
550 * goes out of the field.
551 * IMPORTANT: this function must not be called from an atomic context.
552 * In addition, it must also not be called from a context that would prevent
553 * the NFC Core to call other nfc ops entry point concurrently.
554 */
540int nfc_target_lost(struct nfc_dev *dev, u32 target_idx) 555int nfc_target_lost(struct nfc_dev *dev, u32 target_idx)
541{ 556{
542 struct nfc_target *tg; 557 struct nfc_target *tg;
@@ -544,7 +559,7 @@ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx)
544 559
545 pr_debug("dev_name %s n_target %d\n", dev_name(&dev->dev), target_idx); 560 pr_debug("dev_name %s n_target %d\n", dev_name(&dev->dev), target_idx);
546 561
547 spin_lock_bh(&dev->targets_lock); 562 device_lock(&dev->dev);
548 563
549 for (i = 0; i < dev->n_targets; i++) { 564 for (i = 0; i < dev->n_targets; i++) {
550 tg = &dev->targets[i]; 565 tg = &dev->targets[i];
@@ -553,7 +568,7 @@ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx)
553 } 568 }
554 569
555 if (i == dev->n_targets) { 570 if (i == dev->n_targets) {
556 spin_unlock_bh(&dev->targets_lock); 571 device_unlock(&dev->dev);
557 return -EINVAL; 572 return -EINVAL;
558 } 573 }
559 574
@@ -569,7 +584,7 @@ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx)
569 dev->targets = NULL; 584 dev->targets = NULL;
570 } 585 }
571 586
572 spin_unlock_bh(&dev->targets_lock); 587 device_unlock(&dev->dev);
573 588
574 nfc_genl_target_lost(dev, target_idx); 589 nfc_genl_target_lost(dev, target_idx);
575 590
@@ -607,8 +622,10 @@ static void nfc_check_pres_work(struct work_struct *work)
607 mod_timer(&dev->check_pres_timer, jiffies + 622 mod_timer(&dev->check_pres_timer, jiffies +
608 msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); 623 msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS));
609 } else { 624 } else {
610 nfc_target_lost(dev, dev->active_target->idx); 625 u32 active_target_idx = dev->active_target->idx;
611 dev->active_target = NULL; 626 device_unlock(&dev->dev);
627 nfc_target_lost(dev, active_target_idx);
628 return;
612 } 629 }
613 } 630 }
614 631
@@ -681,9 +698,9 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
681 dev->tx_headroom = tx_headroom; 698 dev->tx_headroom = tx_headroom;
682 dev->tx_tailroom = tx_tailroom; 699 dev->tx_tailroom = tx_tailroom;
683 700
684 spin_lock_init(&dev->targets_lock);
685 nfc_genl_data_init(&dev->genl_data); 701 nfc_genl_data_init(&dev->genl_data);
686 702
703
687 /* first generation must not be 0 */ 704 /* first generation must not be 0 */
688 dev->targets_generation = 1; 705 dev->targets_generation = 1;
689 706
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index f1829f6ae9c5..77dae74832d3 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -128,7 +128,7 @@ static int nfc_genl_dump_targets(struct sk_buff *skb,
128 cb->args[1] = (long) dev; 128 cb->args[1] = (long) dev;
129 } 129 }
130 130
131 spin_lock_bh(&dev->targets_lock); 131 device_lock(&dev->dev);
132 132
133 cb->seq = dev->targets_generation; 133 cb->seq = dev->targets_generation;
134 134
@@ -141,7 +141,7 @@ static int nfc_genl_dump_targets(struct sk_buff *skb,
141 i++; 141 i++;
142 } 142 }
143 143
144 spin_unlock_bh(&dev->targets_lock); 144 device_unlock(&dev->dev);
145 145
146 cb->args[0] = i; 146 cb->args[0] = i;
147 147