summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/net/nfc/nfc.h1
-rw-r--r--net/nfc/core.c39
2 files changed, 40 insertions, 0 deletions
diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h
index bac070bf3514..57ea09533ae1 100644
--- a/include/net/nfc/nfc.h
+++ b/include/net/nfc/nfc.h
@@ -181,6 +181,7 @@ int nfc_set_remote_general_bytes(struct nfc_dev *dev,
int nfc_targets_found(struct nfc_dev *dev,
struct nfc_target *targets, int ntargets);
+int nfc_target_lost(struct nfc_dev *dev, u32 target_idx);
int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx,
u8 comm_mode, u8 rf_mode);
diff --git a/net/nfc/core.c b/net/nfc/core.c
index 295d129864d2..deb4721ce8a1 100644
--- a/net/nfc/core.c
+++ b/net/nfc/core.c
@@ -455,6 +455,45 @@ int nfc_targets_found(struct nfc_dev *dev,
}
EXPORT_SYMBOL(nfc_targets_found);
+int nfc_target_lost(struct nfc_dev *dev, u32 target_idx)
+{
+ struct nfc_target *tg;
+ int i;
+
+ pr_debug("dev_name %s n_target %d\n", dev_name(&dev->dev), target_idx);
+
+ spin_lock_bh(&dev->targets_lock);
+
+ for (i = 0; i < dev->n_targets; i++) {
+ tg = &dev->targets[i];
+ if (tg->idx == target_idx)
+ break;
+ }
+
+ if (i == dev->n_targets) {
+ spin_unlock_bh(&dev->targets_lock);
+ return -EINVAL;
+ }
+
+ dev->targets_generation++;
+ dev->n_targets--;
+
+ if (dev->n_targets) {
+ memcpy(&dev->targets[i], &dev->targets[i + 1],
+ (dev->n_targets - i) * sizeof(struct nfc_target));
+ } else {
+ kfree(dev->targets);
+ dev->targets = NULL;
+ }
+
+ spin_unlock_bh(&dev->targets_lock);
+
+ nfc_genl_target_lost(dev, target_idx);
+
+ return 0;
+}
+EXPORT_SYMBOL(nfc_target_lost);
+
static void nfc_release(struct device *d)
{
struct nfc_dev *dev = to_nfc_dev(d);