aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc/core.c
diff options
context:
space:
mode:
authorEric Lapuyade <eric.lapuyade@intel.com>2012-05-07 06:31:13 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-05-15 17:27:59 -0400
commit900994332675f84a9fbbb33ff089474614c7f2fe (patch)
tree6b9b6f7b50217a30e72848466865e521ee64d048 /net/nfc/core.c
parent536acc085c641ff8ba46c2c0e97b5e137cbc22d6 (diff)
NFC: Cache the core NFC active target pointer instead of its index
The NFC Core now caches the active nfc target pointer, thereby avoiding the need to lookup the target table for each invocation of a driver ops. Consequently, pn533, HCI and NCI now directly receive an nfc_target pointer instead of a target index. Cc: Ilan Elias <ilane@ti.com> 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/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 3192c3f589e..7df28ad4727 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);