]> git.karo-electronics.de Git - mv-sheeva.git/blob - net/nfc/netlink.c
NFC: Remove the rf mode parameter from the DEP link up routine
[mv-sheeva.git] / net / nfc / netlink.c
1 /*
2  * Copyright (C) 2011 Instituto Nokia de Tecnologia
3  *
4  * Authors:
5  *    Lauro Ramos Venancio <lauro.venancio@openbossa.org>
6  *    Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the
20  * Free Software Foundation, Inc.,
21  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22  */
23
24 #define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
25
26 #include <net/genetlink.h>
27 #include <linux/nfc.h>
28 #include <linux/slab.h>
29
30 #include "nfc.h"
31
32 static struct genl_multicast_group nfc_genl_event_mcgrp = {
33         .name = NFC_GENL_MCAST_EVENT_NAME,
34 };
35
36 struct genl_family nfc_genl_family = {
37         .id = GENL_ID_GENERATE,
38         .hdrsize = 0,
39         .name = NFC_GENL_NAME,
40         .version = NFC_GENL_VERSION,
41         .maxattr = NFC_ATTR_MAX,
42 };
43
44 static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = {
45         [NFC_ATTR_DEVICE_INDEX] = { .type = NLA_U32 },
46         [NFC_ATTR_DEVICE_NAME] = { .type = NLA_STRING,
47                                 .len = NFC_DEVICE_NAME_MAXSIZE },
48         [NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 },
49         [NFC_ATTR_COMM_MODE] = { .type = NLA_U8 },
50         [NFC_ATTR_RF_MODE] = { .type = NLA_U8 },
51         [NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 },
52 };
53
54 static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,
55                                         struct netlink_callback *cb, int flags)
56 {
57         void *hdr;
58
59         hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
60                                 &nfc_genl_family, flags, NFC_CMD_GET_TARGET);
61         if (!hdr)
62                 return -EMSGSIZE;
63
64         genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
65
66         NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target->idx);
67         NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS,
68                                 target->supported_protocols);
69         NLA_PUT_U16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res);
70         NLA_PUT_U8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res);
71         if (target->nfcid1_len > 0)
72                 NLA_PUT(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len,
73                                 target->nfcid1);
74         if (target->sensb_res_len > 0)
75                 NLA_PUT(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len,
76                                 target->sensb_res);
77         if (target->sensf_res_len > 0)
78                 NLA_PUT(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len,
79                                 target->sensf_res);
80
81         return genlmsg_end(msg, hdr);
82
83 nla_put_failure:
84         genlmsg_cancel(msg, hdr);
85         return -EMSGSIZE;
86 }
87
88 static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb)
89 {
90         struct nfc_dev *dev;
91         int rc;
92         u32 idx;
93
94         rc = nlmsg_parse(cb->nlh, GENL_HDRLEN + nfc_genl_family.hdrsize,
95                                                 nfc_genl_family.attrbuf,
96                                                 nfc_genl_family.maxattr,
97                                                 nfc_genl_policy);
98         if (rc < 0)
99                 return ERR_PTR(rc);
100
101         if (!nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX])
102                 return ERR_PTR(-EINVAL);
103
104         idx = nla_get_u32(nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX]);
105
106         dev = nfc_get_device(idx);
107         if (!dev)
108                 return ERR_PTR(-ENODEV);
109
110         return dev;
111 }
112
113 static int nfc_genl_dump_targets(struct sk_buff *skb,
114                                 struct netlink_callback *cb)
115 {
116         int i = cb->args[0];
117         struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
118         int rc;
119
120         if (!dev) {
121                 dev = __get_device_from_cb(cb);
122                 if (IS_ERR(dev))
123                         return PTR_ERR(dev);
124
125                 cb->args[1] = (long) dev;
126         }
127
128         spin_lock_bh(&dev->targets_lock);
129
130         cb->seq = dev->targets_generation;
131
132         while (i < dev->n_targets) {
133                 rc = nfc_genl_send_target(skb, &dev->targets[i], cb,
134                                                                 NLM_F_MULTI);
135                 if (rc < 0)
136                         break;
137
138                 i++;
139         }
140
141         spin_unlock_bh(&dev->targets_lock);
142
143         cb->args[0] = i;
144
145         return skb->len;
146 }
147
148 static int nfc_genl_dump_targets_done(struct netlink_callback *cb)
149 {
150         struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
151
152         if (dev)
153                 nfc_put_device(dev);
154
155         return 0;
156 }
157
158 int nfc_genl_targets_found(struct nfc_dev *dev)
159 {
160         struct sk_buff *msg;
161         void *hdr;
162
163         dev->genl_data.poll_req_pid = 0;
164
165         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
166         if (!msg)
167                 return -ENOMEM;
168
169         hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
170                                 NFC_EVENT_TARGETS_FOUND);
171         if (!hdr)
172                 goto free_msg;
173
174         NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
175
176         genlmsg_end(msg, hdr);
177
178         return genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
179
180 nla_put_failure:
181         genlmsg_cancel(msg, hdr);
182 free_msg:
183         nlmsg_free(msg);
184         return -EMSGSIZE;
185 }
186
187 int nfc_genl_device_added(struct nfc_dev *dev)
188 {
189         struct sk_buff *msg;
190         void *hdr;
191
192         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
193         if (!msg)
194                 return -ENOMEM;
195
196         hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
197                                 NFC_EVENT_DEVICE_ADDED);
198         if (!hdr)
199                 goto free_msg;
200
201         NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev));
202         NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
203         NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols);
204         NLA_PUT_U8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up);
205
206         genlmsg_end(msg, hdr);
207
208         genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
209
210         return 0;
211
212 nla_put_failure:
213         genlmsg_cancel(msg, hdr);
214 free_msg:
215         nlmsg_free(msg);
216         return -EMSGSIZE;
217 }
218
219 int nfc_genl_device_removed(struct nfc_dev *dev)
220 {
221         struct sk_buff *msg;
222         void *hdr;
223
224         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
225         if (!msg)
226                 return -ENOMEM;
227
228         hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
229                                 NFC_EVENT_DEVICE_REMOVED);
230         if (!hdr)
231                 goto free_msg;
232
233         NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
234
235         genlmsg_end(msg, hdr);
236
237         genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
238
239         return 0;
240
241 nla_put_failure:
242         genlmsg_cancel(msg, hdr);
243 free_msg:
244         nlmsg_free(msg);
245         return -EMSGSIZE;
246 }
247
248 static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
249                                                 u32 pid, u32 seq,
250                                                 struct netlink_callback *cb,
251                                                 int flags)
252 {
253         void *hdr;
254
255         hdr = genlmsg_put(msg, pid, seq, &nfc_genl_family, flags,
256                                                         NFC_CMD_GET_DEVICE);
257         if (!hdr)
258                 return -EMSGSIZE;
259
260         if (cb)
261                 genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
262
263         NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev));
264         NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
265         NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols);
266         NLA_PUT_U8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up);
267
268         return genlmsg_end(msg, hdr);
269
270 nla_put_failure:
271         genlmsg_cancel(msg, hdr);
272         return -EMSGSIZE;
273 }
274
275 static int nfc_genl_dump_devices(struct sk_buff *skb,
276                                 struct netlink_callback *cb)
277 {
278         struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
279         struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
280         bool first_call = false;
281
282         if (!iter) {
283                 first_call = true;
284                 iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL);
285                 if (!iter)
286                         return -ENOMEM;
287                 cb->args[0] = (long) iter;
288         }
289
290         mutex_lock(&nfc_devlist_mutex);
291
292         cb->seq = nfc_devlist_generation;
293
294         if (first_call) {
295                 nfc_device_iter_init(iter);
296                 dev = nfc_device_iter_next(iter);
297         }
298
299         while (dev) {
300                 int rc;
301
302                 rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).pid,
303                                                         cb->nlh->nlmsg_seq,
304                                                         cb, NLM_F_MULTI);
305                 if (rc < 0)
306                         break;
307
308                 dev = nfc_device_iter_next(iter);
309         }
310
311         mutex_unlock(&nfc_devlist_mutex);
312
313         cb->args[1] = (long) dev;
314
315         return skb->len;
316 }
317
318 static int nfc_genl_dump_devices_done(struct netlink_callback *cb)
319 {
320         struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
321
322         nfc_device_iter_exit(iter);
323         kfree(iter);
324
325         return 0;
326 }
327
328 int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx,
329                                                 u8 comm_mode, u8 rf_mode)
330 {
331         struct sk_buff *msg;
332         void *hdr;
333
334         pr_debug("DEP link is up\n");
335
336         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
337         if (!msg)
338                 return -ENOMEM;
339
340         hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
341                                 NFC_CMD_DEP_LINK_UP);
342         if (!hdr)
343                 goto free_msg;
344
345         NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
346         if (rf_mode == NFC_RF_INITIATOR)
347                 NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target_idx);
348         NLA_PUT_U8(msg, NFC_ATTR_COMM_MODE, comm_mode);
349         NLA_PUT_U8(msg, NFC_ATTR_RF_MODE, rf_mode);
350
351         genlmsg_end(msg, hdr);
352
353         dev->dep_link_up = true;
354
355         genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
356
357         return 0;
358
359 nla_put_failure:
360         genlmsg_cancel(msg, hdr);
361 free_msg:
362         nlmsg_free(msg);
363         return -EMSGSIZE;
364 }
365
366 int nfc_genl_dep_link_down_event(struct nfc_dev *dev)
367 {
368         struct sk_buff *msg;
369         void *hdr;
370
371         pr_debug("DEP link is down\n");
372
373         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
374         if (!msg)
375                 return -ENOMEM;
376
377         hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
378                                 NFC_CMD_DEP_LINK_DOWN);
379         if (!hdr)
380                 goto free_msg;
381
382         NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
383
384         genlmsg_end(msg, hdr);
385
386         genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
387
388         return 0;
389
390 nla_put_failure:
391         genlmsg_cancel(msg, hdr);
392 free_msg:
393         nlmsg_free(msg);
394         return -EMSGSIZE;
395 }
396
397 static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info)
398 {
399         struct sk_buff *msg;
400         struct nfc_dev *dev;
401         u32 idx;
402         int rc = -ENOBUFS;
403
404         if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
405                 return -EINVAL;
406
407         idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
408
409         dev = nfc_get_device(idx);
410         if (!dev)
411                 return -ENODEV;
412
413         msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
414         if (!msg) {
415                 rc = -ENOMEM;
416                 goto out_putdev;
417         }
418
419         rc = nfc_genl_send_device(msg, dev, info->snd_pid, info->snd_seq,
420                                                                 NULL, 0);
421         if (rc < 0)
422                 goto out_free;
423
424         nfc_put_device(dev);
425
426         return genlmsg_reply(msg, info);
427
428 out_free:
429         nlmsg_free(msg);
430 out_putdev:
431         nfc_put_device(dev);
432         return rc;
433 }
434
435 static int nfc_genl_dev_up(struct sk_buff *skb, struct genl_info *info)
436 {
437         struct nfc_dev *dev;
438         int rc;
439         u32 idx;
440
441         if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
442                 return -EINVAL;
443
444         idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
445
446         dev = nfc_get_device(idx);
447         if (!dev)
448                 return -ENODEV;
449
450         rc = nfc_dev_up(dev);
451
452         nfc_put_device(dev);
453         return rc;
454 }
455
456 static int nfc_genl_dev_down(struct sk_buff *skb, struct genl_info *info)
457 {
458         struct nfc_dev *dev;
459         int rc;
460         u32 idx;
461
462         if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
463                 return -EINVAL;
464
465         idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
466
467         dev = nfc_get_device(idx);
468         if (!dev)
469                 return -ENODEV;
470
471         rc = nfc_dev_down(dev);
472
473         nfc_put_device(dev);
474         return rc;
475 }
476
477 static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info)
478 {
479         struct nfc_dev *dev;
480         int rc;
481         u32 idx;
482         u32 protocols;
483
484         pr_debug("Poll start\n");
485
486         if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
487                 !info->attrs[NFC_ATTR_PROTOCOLS])
488                 return -EINVAL;
489
490         idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
491         protocols = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]);
492
493         dev = nfc_get_device(idx);
494         if (!dev)
495                 return -ENODEV;
496
497         mutex_lock(&dev->genl_data.genl_data_mutex);
498
499         rc = nfc_start_poll(dev, protocols);
500         if (!rc)
501                 dev->genl_data.poll_req_pid = info->snd_pid;
502
503         mutex_unlock(&dev->genl_data.genl_data_mutex);
504
505         nfc_put_device(dev);
506         return rc;
507 }
508
509 static int nfc_genl_stop_poll(struct sk_buff *skb, struct genl_info *info)
510 {
511         struct nfc_dev *dev;
512         int rc;
513         u32 idx;
514
515         if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
516                 return -EINVAL;
517
518         idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
519
520         dev = nfc_get_device(idx);
521         if (!dev)
522                 return -ENODEV;
523
524         mutex_lock(&dev->genl_data.genl_data_mutex);
525
526         if (dev->genl_data.poll_req_pid != info->snd_pid) {
527                 rc = -EBUSY;
528                 goto out;
529         }
530
531         rc = nfc_stop_poll(dev);
532         dev->genl_data.poll_req_pid = 0;
533
534 out:
535         mutex_unlock(&dev->genl_data.genl_data_mutex);
536         nfc_put_device(dev);
537         return rc;
538 }
539
540 static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info)
541 {
542         struct nfc_dev *dev;
543         int rc, tgt_idx;
544         u32 idx;
545         u8 comm;
546
547         pr_debug("DEP link up\n");
548
549         if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
550             !info->attrs[NFC_ATTR_COMM_MODE])
551                 return -EINVAL;
552
553         idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
554         if (!info->attrs[NFC_ATTR_TARGET_INDEX])
555                 tgt_idx = NFC_TARGET_IDX_ANY;
556         else
557                 tgt_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);
558
559         comm = nla_get_u8(info->attrs[NFC_ATTR_COMM_MODE]);
560
561         if (comm != NFC_COMM_ACTIVE && comm != NFC_COMM_PASSIVE)
562                 return -EINVAL;
563
564         dev = nfc_get_device(idx);
565         if (!dev)
566                 return -ENODEV;
567
568         rc = nfc_dep_link_up(dev, tgt_idx, comm);
569
570         nfc_put_device(dev);
571
572         return rc;
573 }
574
575 static int nfc_genl_dep_link_down(struct sk_buff *skb, struct genl_info *info)
576 {
577         struct nfc_dev *dev;
578         int rc;
579         u32 idx;
580
581         if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
582                 return -EINVAL;
583
584         idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
585
586         dev = nfc_get_device(idx);
587         if (!dev)
588                 return -ENODEV;
589
590         rc = nfc_dep_link_down(dev);
591
592         nfc_put_device(dev);
593         return rc;
594 }
595
596 static struct genl_ops nfc_genl_ops[] = {
597         {
598                 .cmd = NFC_CMD_GET_DEVICE,
599                 .doit = nfc_genl_get_device,
600                 .dumpit = nfc_genl_dump_devices,
601                 .done = nfc_genl_dump_devices_done,
602                 .policy = nfc_genl_policy,
603         },
604         {
605                 .cmd = NFC_CMD_DEV_UP,
606                 .doit = nfc_genl_dev_up,
607                 .policy = nfc_genl_policy,
608         },
609         {
610                 .cmd = NFC_CMD_DEV_DOWN,
611                 .doit = nfc_genl_dev_down,
612                 .policy = nfc_genl_policy,
613         },
614         {
615                 .cmd = NFC_CMD_START_POLL,
616                 .doit = nfc_genl_start_poll,
617                 .policy = nfc_genl_policy,
618         },
619         {
620                 .cmd = NFC_CMD_STOP_POLL,
621                 .doit = nfc_genl_stop_poll,
622                 .policy = nfc_genl_policy,
623         },
624         {
625                 .cmd = NFC_CMD_DEP_LINK_UP,
626                 .doit = nfc_genl_dep_link_up,
627                 .policy = nfc_genl_policy,
628         },
629         {
630                 .cmd = NFC_CMD_DEP_LINK_DOWN,
631                 .doit = nfc_genl_dep_link_down,
632                 .policy = nfc_genl_policy,
633         },
634         {
635                 .cmd = NFC_CMD_GET_TARGET,
636                 .dumpit = nfc_genl_dump_targets,
637                 .done = nfc_genl_dump_targets_done,
638                 .policy = nfc_genl_policy,
639         },
640 };
641
642 static int nfc_genl_rcv_nl_event(struct notifier_block *this,
643                                                 unsigned long event, void *ptr)
644 {
645         struct netlink_notify *n = ptr;
646         struct class_dev_iter iter;
647         struct nfc_dev *dev;
648
649         if (event != NETLINK_URELEASE || n->protocol != NETLINK_GENERIC)
650                 goto out;
651
652         pr_debug("NETLINK_URELEASE event from id %d\n", n->pid);
653
654         nfc_device_iter_init(&iter);
655         dev = nfc_device_iter_next(&iter);
656
657         while (dev) {
658                 if (dev->genl_data.poll_req_pid == n->pid) {
659                         nfc_stop_poll(dev);
660                         dev->genl_data.poll_req_pid = 0;
661                 }
662                 dev = nfc_device_iter_next(&iter);
663         }
664
665         nfc_device_iter_exit(&iter);
666
667 out:
668         return NOTIFY_DONE;
669 }
670
671 void nfc_genl_data_init(struct nfc_genl_data *genl_data)
672 {
673         genl_data->poll_req_pid = 0;
674         mutex_init(&genl_data->genl_data_mutex);
675 }
676
677 void nfc_genl_data_exit(struct nfc_genl_data *genl_data)
678 {
679         mutex_destroy(&genl_data->genl_data_mutex);
680 }
681
682 static struct notifier_block nl_notifier = {
683         .notifier_call  = nfc_genl_rcv_nl_event,
684 };
685
686 /**
687  * nfc_genl_init() - Initialize netlink interface
688  *
689  * This initialization function registers the nfc netlink family.
690  */
691 int __init nfc_genl_init(void)
692 {
693         int rc;
694
695         rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops,
696                                         ARRAY_SIZE(nfc_genl_ops));
697         if (rc)
698                 return rc;
699
700         rc = genl_register_mc_group(&nfc_genl_family, &nfc_genl_event_mcgrp);
701
702         netlink_register_notifier(&nl_notifier);
703
704         return rc;
705 }
706
707 /**
708  * nfc_genl_exit() - Deinitialize netlink interface
709  *
710  * This exit function unregisters the nfc netlink family.
711  */
712 void nfc_genl_exit(void)
713 {
714         netlink_unregister_notifier(&nl_notifier);
715         genl_unregister_family(&nfc_genl_family);
716 }