aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc/core.c
diff options
context:
space:
mode:
authorLauro Ramos Venancio <lauro.venancio@openbossa.org>2011-07-01 18:31:34 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-07-05 15:26:57 -0400
commit4d12b8b129f170d0fc3188de1e51a2a1b0f87730 (patch)
treee37bbec5da917fee80706516c56fb41fcd03a1b5 /net/nfc/core.c
parent3e256b8f8dfa309a80b5dece388d85d9a9801a29 (diff)
NFC: add nfc generic netlink interface
The NFC generic netlink interface exports the NFC control operations to the user space. Signed-off-by: Lauro Ramos Venancio <lauro.venancio@openbossa.org> Signed-off-by: Aloisio Almeida Jr <aloisio.almeida@openbossa.org> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com> Reviewed-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/nfc/core.c')
-rw-r--r--net/nfc/core.c93
1 files changed, 91 insertions, 2 deletions
diff --git a/net/nfc/core.c b/net/nfc/core.c
index 19f8035a1ba..c70f607455c 100644
--- a/net/nfc/core.c
+++ b/net/nfc/core.c
@@ -233,12 +233,60 @@ struct sk_buff *nfc_alloc_skb(unsigned int size, gfp_t gfp)
233} 233}
234EXPORT_SYMBOL(nfc_alloc_skb); 234EXPORT_SYMBOL(nfc_alloc_skb);
235 235
236/**
237 * nfc_targets_found - inform that targets were found
238 *
239 * @dev: The nfc device that found the targets
240 * @targets: array of nfc targets found
241 * @ntargets: targets array size
242 *
243 * The device driver must call this function when one or many nfc targets
244 * are found. After calling this function, the device driver must stop
245 * polling for targets.
246 */
247int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets,
248 int n_targets)
249{
250 int i;
251
252 nfc_dbg("dev_name=%s n_targets=%d", dev_name(&dev->dev), n_targets);
253
254 dev->polling = false;
255
256 for (i = 0; i < n_targets; i++)
257 targets[i].idx = dev->target_idx++;
258
259 spin_lock_bh(&dev->targets_lock);
260
261 dev->targets_generation++;
262
263 kfree(dev->targets);
264 dev->targets = kmemdup(targets, n_targets * sizeof(struct nfc_target),
265 GFP_ATOMIC);
266
267 if (!dev->targets) {
268 dev->n_targets = 0;
269 spin_unlock_bh(&dev->targets_lock);
270 return -ENOMEM;
271 }
272
273 dev->n_targets = n_targets;
274 spin_unlock_bh(&dev->targets_lock);
275
276 nfc_genl_targets_found(dev);
277
278 return 0;
279}
280EXPORT_SYMBOL(nfc_targets_found);
281
236static void nfc_release(struct device *d) 282static void nfc_release(struct device *d)
237{ 283{
238 struct nfc_dev *dev = to_nfc_dev(d); 284 struct nfc_dev *dev = to_nfc_dev(d);
239 285
240 nfc_dbg("dev_name=%s", dev_name(&dev->dev)); 286 nfc_dbg("dev_name=%s", dev_name(&dev->dev));
241 287
288 nfc_genl_data_exit(&dev->genl_data);
289 kfree(dev->targets);
242 kfree(dev); 290 kfree(dev);
243} 291}
244 292
@@ -298,6 +346,12 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
298 dev->ops = ops; 346 dev->ops = ops;
299 dev->supported_protocols = supported_protocols; 347 dev->supported_protocols = supported_protocols;
300 348
349 spin_lock_init(&dev->targets_lock);
350 nfc_genl_data_init(&dev->genl_data);
351
352 /* first generation must not be 0 */
353 dev->targets_generation = 1;
354
301 return dev; 355 return dev;
302} 356}
303EXPORT_SYMBOL(nfc_allocate_device); 357EXPORT_SYMBOL(nfc_allocate_device);
@@ -318,7 +372,16 @@ int nfc_register_device(struct nfc_dev *dev)
318 rc = device_add(&dev->dev); 372 rc = device_add(&dev->dev);
319 mutex_unlock(&nfc_devlist_mutex); 373 mutex_unlock(&nfc_devlist_mutex);
320 374
321 return rc; 375 if (rc < 0)
376 return rc;
377
378 rc = nfc_genl_device_added(dev);
379 if (rc)
380 nfc_dbg("The userspace won't be notified that the device %s was"
381 " added", dev_name(&dev->dev));
382
383
384 return 0;
322} 385}
323EXPORT_SYMBOL(nfc_register_device); 386EXPORT_SYMBOL(nfc_register_device);
324 387
@@ -329,6 +392,8 @@ EXPORT_SYMBOL(nfc_register_device);
329 */ 392 */
330void nfc_unregister_device(struct nfc_dev *dev) 393void nfc_unregister_device(struct nfc_dev *dev)
331{ 394{
395 int rc;
396
332 nfc_dbg("dev_name=%s", dev_name(&dev->dev)); 397 nfc_dbg("dev_name=%s", dev_name(&dev->dev));
333 398
334 mutex_lock(&nfc_devlist_mutex); 399 mutex_lock(&nfc_devlist_mutex);
@@ -341,18 +406,42 @@ void nfc_unregister_device(struct nfc_dev *dev)
341 device_unlock(&dev->dev); 406 device_unlock(&dev->dev);
342 407
343 mutex_unlock(&nfc_devlist_mutex); 408 mutex_unlock(&nfc_devlist_mutex);
409
410 rc = nfc_genl_device_removed(dev);
411 if (rc)
412 nfc_dbg("The userspace won't be notified that the device %s"
413 " was removed", dev_name(&dev->dev));
414
344} 415}
345EXPORT_SYMBOL(nfc_unregister_device); 416EXPORT_SYMBOL(nfc_unregister_device);
346 417
347static int __init nfc_init(void) 418static int __init nfc_init(void)
348{ 419{
420 int rc;
421
349 nfc_info("NFC Core ver %s", VERSION); 422 nfc_info("NFC Core ver %s", VERSION);
350 423
351 return class_register(&nfc_class); 424 rc = class_register(&nfc_class);
425 if (rc)
426 return rc;
427
428 rc = nfc_genl_init();
429 if (rc)
430 goto err_genl;
431
432 /* the first generation must not be 0 */
433 nfc_devlist_generation = 1;
434
435 return 0;
436
437err_genl:
438 class_unregister(&nfc_class);
439 return rc;
352} 440}
353 441
354static void __exit nfc_exit(void) 442static void __exit nfc_exit(void)
355{ 443{
444 nfc_genl_exit();
356 class_unregister(&nfc_class); 445 class_unregister(&nfc_class);
357} 446}
358 447