Merge tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[deliverable/linux.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 #include "llcp/llcp.h"
33
34 static struct genl_multicast_group nfc_genl_event_mcgrp = {
35 .name = NFC_GENL_MCAST_EVENT_NAME,
36 };
37
38 static struct genl_family nfc_genl_family = {
39 .id = GENL_ID_GENERATE,
40 .hdrsize = 0,
41 .name = NFC_GENL_NAME,
42 .version = NFC_GENL_VERSION,
43 .maxattr = NFC_ATTR_MAX,
44 };
45
46 static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = {
47 [NFC_ATTR_DEVICE_INDEX] = { .type = NLA_U32 },
48 [NFC_ATTR_DEVICE_NAME] = { .type = NLA_STRING,
49 .len = NFC_DEVICE_NAME_MAXSIZE },
50 [NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 },
51 [NFC_ATTR_COMM_MODE] = { .type = NLA_U8 },
52 [NFC_ATTR_RF_MODE] = { .type = NLA_U8 },
53 [NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 },
54 [NFC_ATTR_IM_PROTOCOLS] = { .type = NLA_U32 },
55 [NFC_ATTR_TM_PROTOCOLS] = { .type = NLA_U32 },
56 };
57
58 static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,
59 struct netlink_callback *cb, int flags)
60 {
61 void *hdr;
62
63 hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
64 &nfc_genl_family, flags, NFC_CMD_GET_TARGET);
65 if (!hdr)
66 return -EMSGSIZE;
67
68 genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
69
70 if (nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target->idx) ||
71 nla_put_u32(msg, NFC_ATTR_PROTOCOLS, target->supported_protocols) ||
72 nla_put_u16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res) ||
73 nla_put_u8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res))
74 goto nla_put_failure;
75 if (target->nfcid1_len > 0 &&
76 nla_put(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len,
77 target->nfcid1))
78 goto nla_put_failure;
79 if (target->sensb_res_len > 0 &&
80 nla_put(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len,
81 target->sensb_res))
82 goto nla_put_failure;
83 if (target->sensf_res_len > 0 &&
84 nla_put(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len,
85 target->sensf_res))
86 goto nla_put_failure;
87
88 return genlmsg_end(msg, hdr);
89
90 nla_put_failure:
91 genlmsg_cancel(msg, hdr);
92 return -EMSGSIZE;
93 }
94
95 static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb)
96 {
97 struct nfc_dev *dev;
98 int rc;
99 u32 idx;
100
101 rc = nlmsg_parse(cb->nlh, GENL_HDRLEN + nfc_genl_family.hdrsize,
102 nfc_genl_family.attrbuf,
103 nfc_genl_family.maxattr,
104 nfc_genl_policy);
105 if (rc < 0)
106 return ERR_PTR(rc);
107
108 if (!nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX])
109 return ERR_PTR(-EINVAL);
110
111 idx = nla_get_u32(nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX]);
112
113 dev = nfc_get_device(idx);
114 if (!dev)
115 return ERR_PTR(-ENODEV);
116
117 return dev;
118 }
119
120 static int nfc_genl_dump_targets(struct sk_buff *skb,
121 struct netlink_callback *cb)
122 {
123 int i = cb->args[0];
124 struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
125 int rc;
126
127 if (!dev) {
128 dev = __get_device_from_cb(cb);
129 if (IS_ERR(dev))
130 return PTR_ERR(dev);
131
132 cb->args[1] = (long) dev;
133 }
134
135 device_lock(&dev->dev);
136
137 cb->seq = dev->targets_generation;
138
139 while (i < dev->n_targets) {
140 rc = nfc_genl_send_target(skb, &dev->targets[i], cb,
141 NLM_F_MULTI);
142 if (rc < 0)
143 break;
144
145 i++;
146 }
147
148 device_unlock(&dev->dev);
149
150 cb->args[0] = i;
151
152 return skb->len;
153 }
154
155 static int nfc_genl_dump_targets_done(struct netlink_callback *cb)
156 {
157 struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
158
159 if (dev)
160 nfc_put_device(dev);
161
162 return 0;
163 }
164
165 int nfc_genl_targets_found(struct nfc_dev *dev)
166 {
167 struct sk_buff *msg;
168 void *hdr;
169
170 dev->genl_data.poll_req_portid = 0;
171
172 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
173 if (!msg)
174 return -ENOMEM;
175
176 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
177 NFC_EVENT_TARGETS_FOUND);
178 if (!hdr)
179 goto free_msg;
180
181 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
182 goto nla_put_failure;
183
184 genlmsg_end(msg, hdr);
185
186 return genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
187
188 nla_put_failure:
189 genlmsg_cancel(msg, hdr);
190 free_msg:
191 nlmsg_free(msg);
192 return -EMSGSIZE;
193 }
194
195 int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx)
196 {
197 struct sk_buff *msg;
198 void *hdr;
199
200 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
201 if (!msg)
202 return -ENOMEM;
203
204 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
205 NFC_EVENT_TARGET_LOST);
206 if (!hdr)
207 goto free_msg;
208
209 if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
210 nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target_idx))
211 goto nla_put_failure;
212
213 genlmsg_end(msg, hdr);
214
215 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
216
217 return 0;
218
219 nla_put_failure:
220 genlmsg_cancel(msg, hdr);
221 free_msg:
222 nlmsg_free(msg);
223 return -EMSGSIZE;
224 }
225
226 int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol)
227 {
228 struct sk_buff *msg;
229 void *hdr;
230
231 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
232 if (!msg)
233 return -ENOMEM;
234
235 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
236 NFC_EVENT_TM_ACTIVATED);
237 if (!hdr)
238 goto free_msg;
239
240 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
241 goto nla_put_failure;
242 if (nla_put_u32(msg, NFC_ATTR_TM_PROTOCOLS, protocol))
243 goto nla_put_failure;
244
245 genlmsg_end(msg, hdr);
246
247 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
248
249 return 0;
250
251 nla_put_failure:
252 genlmsg_cancel(msg, hdr);
253 free_msg:
254 nlmsg_free(msg);
255 return -EMSGSIZE;
256 }
257
258 int nfc_genl_tm_deactivated(struct nfc_dev *dev)
259 {
260 struct sk_buff *msg;
261 void *hdr;
262
263 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
264 if (!msg)
265 return -ENOMEM;
266
267 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
268 NFC_EVENT_TM_DEACTIVATED);
269 if (!hdr)
270 goto free_msg;
271
272 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
273 goto nla_put_failure;
274
275 genlmsg_end(msg, hdr);
276
277 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
278
279 return 0;
280
281 nla_put_failure:
282 genlmsg_cancel(msg, hdr);
283 free_msg:
284 nlmsg_free(msg);
285 return -EMSGSIZE;
286 }
287
288 int nfc_genl_device_added(struct nfc_dev *dev)
289 {
290 struct sk_buff *msg;
291 void *hdr;
292
293 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
294 if (!msg)
295 return -ENOMEM;
296
297 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
298 NFC_EVENT_DEVICE_ADDED);
299 if (!hdr)
300 goto free_msg;
301
302 if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
303 nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
304 nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
305 nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up))
306 goto nla_put_failure;
307
308 genlmsg_end(msg, hdr);
309
310 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
311
312 return 0;
313
314 nla_put_failure:
315 genlmsg_cancel(msg, hdr);
316 free_msg:
317 nlmsg_free(msg);
318 return -EMSGSIZE;
319 }
320
321 int nfc_genl_device_removed(struct nfc_dev *dev)
322 {
323 struct sk_buff *msg;
324 void *hdr;
325
326 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
327 if (!msg)
328 return -ENOMEM;
329
330 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
331 NFC_EVENT_DEVICE_REMOVED);
332 if (!hdr)
333 goto free_msg;
334
335 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
336 goto nla_put_failure;
337
338 genlmsg_end(msg, hdr);
339
340 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
341
342 return 0;
343
344 nla_put_failure:
345 genlmsg_cancel(msg, hdr);
346 free_msg:
347 nlmsg_free(msg);
348 return -EMSGSIZE;
349 }
350
351 static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
352 u32 portid, u32 seq,
353 struct netlink_callback *cb,
354 int flags)
355 {
356 void *hdr;
357
358 hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, flags,
359 NFC_CMD_GET_DEVICE);
360 if (!hdr)
361 return -EMSGSIZE;
362
363 if (cb)
364 genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
365
366 if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
367 nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
368 nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
369 nla_put_u32(msg, NFC_ATTR_SE, dev->supported_se) ||
370 nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up) ||
371 nla_put_u8(msg, NFC_ATTR_RF_MODE, dev->rf_mode))
372 goto nla_put_failure;
373
374 return genlmsg_end(msg, hdr);
375
376 nla_put_failure:
377 genlmsg_cancel(msg, hdr);
378 return -EMSGSIZE;
379 }
380
381 static int nfc_genl_dump_devices(struct sk_buff *skb,
382 struct netlink_callback *cb)
383 {
384 struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
385 struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
386 bool first_call = false;
387
388 if (!iter) {
389 first_call = true;
390 iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL);
391 if (!iter)
392 return -ENOMEM;
393 cb->args[0] = (long) iter;
394 }
395
396 mutex_lock(&nfc_devlist_mutex);
397
398 cb->seq = nfc_devlist_generation;
399
400 if (first_call) {
401 nfc_device_iter_init(iter);
402 dev = nfc_device_iter_next(iter);
403 }
404
405 while (dev) {
406 int rc;
407
408 rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).portid,
409 cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
410 if (rc < 0)
411 break;
412
413 dev = nfc_device_iter_next(iter);
414 }
415
416 mutex_unlock(&nfc_devlist_mutex);
417
418 cb->args[1] = (long) dev;
419
420 return skb->len;
421 }
422
423 static int nfc_genl_dump_devices_done(struct netlink_callback *cb)
424 {
425 struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
426
427 nfc_device_iter_exit(iter);
428 kfree(iter);
429
430 return 0;
431 }
432
433 int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx,
434 u8 comm_mode, u8 rf_mode)
435 {
436 struct sk_buff *msg;
437 void *hdr;
438
439 pr_debug("DEP link is up\n");
440
441 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
442 if (!msg)
443 return -ENOMEM;
444
445 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, NFC_CMD_DEP_LINK_UP);
446 if (!hdr)
447 goto free_msg;
448
449 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
450 goto nla_put_failure;
451 if (rf_mode == NFC_RF_INITIATOR &&
452 nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target_idx))
453 goto nla_put_failure;
454 if (nla_put_u8(msg, NFC_ATTR_COMM_MODE, comm_mode) ||
455 nla_put_u8(msg, NFC_ATTR_RF_MODE, rf_mode))
456 goto nla_put_failure;
457
458 genlmsg_end(msg, hdr);
459
460 dev->dep_link_up = true;
461
462 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
463
464 return 0;
465
466 nla_put_failure:
467 genlmsg_cancel(msg, hdr);
468 free_msg:
469 nlmsg_free(msg);
470 return -EMSGSIZE;
471 }
472
473 int nfc_genl_dep_link_down_event(struct nfc_dev *dev)
474 {
475 struct sk_buff *msg;
476 void *hdr;
477
478 pr_debug("DEP link is down\n");
479
480 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
481 if (!msg)
482 return -ENOMEM;
483
484 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
485 NFC_CMD_DEP_LINK_DOWN);
486 if (!hdr)
487 goto free_msg;
488
489 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
490 goto nla_put_failure;
491
492 genlmsg_end(msg, hdr);
493
494 genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
495
496 return 0;
497
498 nla_put_failure:
499 genlmsg_cancel(msg, hdr);
500 free_msg:
501 nlmsg_free(msg);
502 return -EMSGSIZE;
503 }
504
505 static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info)
506 {
507 struct sk_buff *msg;
508 struct nfc_dev *dev;
509 u32 idx;
510 int rc = -ENOBUFS;
511
512 if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
513 return -EINVAL;
514
515 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
516
517 dev = nfc_get_device(idx);
518 if (!dev)
519 return -ENODEV;
520
521 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
522 if (!msg) {
523 rc = -ENOMEM;
524 goto out_putdev;
525 }
526
527 rc = nfc_genl_send_device(msg, dev, info->snd_portid, info->snd_seq,
528 NULL, 0);
529 if (rc < 0)
530 goto out_free;
531
532 nfc_put_device(dev);
533
534 return genlmsg_reply(msg, info);
535
536 out_free:
537 nlmsg_free(msg);
538 out_putdev:
539 nfc_put_device(dev);
540 return rc;
541 }
542
543 static int nfc_genl_dev_up(struct sk_buff *skb, struct genl_info *info)
544 {
545 struct nfc_dev *dev;
546 int rc;
547 u32 idx;
548
549 if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
550 return -EINVAL;
551
552 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
553
554 dev = nfc_get_device(idx);
555 if (!dev)
556 return -ENODEV;
557
558 rc = nfc_dev_up(dev);
559
560 nfc_put_device(dev);
561 return rc;
562 }
563
564 static int nfc_genl_dev_down(struct sk_buff *skb, struct genl_info *info)
565 {
566 struct nfc_dev *dev;
567 int rc;
568 u32 idx;
569
570 if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
571 return -EINVAL;
572
573 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
574
575 dev = nfc_get_device(idx);
576 if (!dev)
577 return -ENODEV;
578
579 rc = nfc_dev_down(dev);
580
581 nfc_put_device(dev);
582 return rc;
583 }
584
585 static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info)
586 {
587 struct nfc_dev *dev;
588 int rc;
589 u32 idx;
590 u32 im_protocols = 0, tm_protocols = 0;
591
592 pr_debug("Poll start\n");
593
594 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
595 ((!info->attrs[NFC_ATTR_IM_PROTOCOLS] &&
596 !info->attrs[NFC_ATTR_PROTOCOLS]) &&
597 !info->attrs[NFC_ATTR_TM_PROTOCOLS]))
598 return -EINVAL;
599
600 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
601
602 if (info->attrs[NFC_ATTR_TM_PROTOCOLS])
603 tm_protocols = nla_get_u32(info->attrs[NFC_ATTR_TM_PROTOCOLS]);
604
605 if (info->attrs[NFC_ATTR_IM_PROTOCOLS])
606 im_protocols = nla_get_u32(info->attrs[NFC_ATTR_IM_PROTOCOLS]);
607 else if (info->attrs[NFC_ATTR_PROTOCOLS])
608 im_protocols = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]);
609
610 dev = nfc_get_device(idx);
611 if (!dev)
612 return -ENODEV;
613
614 mutex_lock(&dev->genl_data.genl_data_mutex);
615
616 rc = nfc_start_poll(dev, im_protocols, tm_protocols);
617 if (!rc)
618 dev->genl_data.poll_req_portid = info->snd_portid;
619
620 mutex_unlock(&dev->genl_data.genl_data_mutex);
621
622 nfc_put_device(dev);
623 return rc;
624 }
625
626 static int nfc_genl_stop_poll(struct sk_buff *skb, struct genl_info *info)
627 {
628 struct nfc_dev *dev;
629 int rc;
630 u32 idx;
631
632 if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
633 return -EINVAL;
634
635 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
636
637 dev = nfc_get_device(idx);
638 if (!dev)
639 return -ENODEV;
640
641 device_lock(&dev->dev);
642
643 if (!dev->polling) {
644 device_unlock(&dev->dev);
645 return -EINVAL;
646 }
647
648 device_unlock(&dev->dev);
649
650 mutex_lock(&dev->genl_data.genl_data_mutex);
651
652 if (dev->genl_data.poll_req_portid != info->snd_portid) {
653 rc = -EBUSY;
654 goto out;
655 }
656
657 rc = nfc_stop_poll(dev);
658 dev->genl_data.poll_req_portid = 0;
659
660 out:
661 mutex_unlock(&dev->genl_data.genl_data_mutex);
662 nfc_put_device(dev);
663 return rc;
664 }
665
666 static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info)
667 {
668 struct nfc_dev *dev;
669 int rc, tgt_idx;
670 u32 idx;
671 u8 comm;
672
673 pr_debug("DEP link up\n");
674
675 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
676 !info->attrs[NFC_ATTR_COMM_MODE])
677 return -EINVAL;
678
679 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
680 if (!info->attrs[NFC_ATTR_TARGET_INDEX])
681 tgt_idx = NFC_TARGET_IDX_ANY;
682 else
683 tgt_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);
684
685 comm = nla_get_u8(info->attrs[NFC_ATTR_COMM_MODE]);
686
687 if (comm != NFC_COMM_ACTIVE && comm != NFC_COMM_PASSIVE)
688 return -EINVAL;
689
690 dev = nfc_get_device(idx);
691 if (!dev)
692 return -ENODEV;
693
694 rc = nfc_dep_link_up(dev, tgt_idx, comm);
695
696 nfc_put_device(dev);
697
698 return rc;
699 }
700
701 static int nfc_genl_dep_link_down(struct sk_buff *skb, struct genl_info *info)
702 {
703 struct nfc_dev *dev;
704 int rc;
705 u32 idx;
706
707 if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
708 return -EINVAL;
709
710 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
711
712 dev = nfc_get_device(idx);
713 if (!dev)
714 return -ENODEV;
715
716 rc = nfc_dep_link_down(dev);
717
718 nfc_put_device(dev);
719 return rc;
720 }
721
722 static int nfc_genl_send_params(struct sk_buff *msg,
723 struct nfc_llcp_local *local,
724 u32 portid, u32 seq)
725 {
726 void *hdr;
727
728 hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, 0,
729 NFC_CMD_LLC_GET_PARAMS);
730 if (!hdr)
731 return -EMSGSIZE;
732
733 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, local->dev->idx) ||
734 nla_put_u8(msg, NFC_ATTR_LLC_PARAM_LTO, local->lto) ||
735 nla_put_u8(msg, NFC_ATTR_LLC_PARAM_RW, local->rw) ||
736 nla_put_u16(msg, NFC_ATTR_LLC_PARAM_MIUX, be16_to_cpu(local->miux)))
737 goto nla_put_failure;
738
739 return genlmsg_end(msg, hdr);
740
741 nla_put_failure:
742
743 genlmsg_cancel(msg, hdr);
744 return -EMSGSIZE;
745 }
746
747 static int nfc_genl_llc_get_params(struct sk_buff *skb, struct genl_info *info)
748 {
749 struct nfc_dev *dev;
750 struct nfc_llcp_local *local;
751 int rc = 0;
752 struct sk_buff *msg = NULL;
753 u32 idx;
754
755 if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
756 return -EINVAL;
757
758 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
759
760 dev = nfc_get_device(idx);
761 if (!dev)
762 return -ENODEV;
763
764 device_lock(&dev->dev);
765
766 local = nfc_llcp_find_local(dev);
767 if (!local) {
768 rc = -ENODEV;
769 goto exit;
770 }
771
772 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
773 if (!msg) {
774 rc = -ENOMEM;
775 goto exit;
776 }
777
778 rc = nfc_genl_send_params(msg, local, info->snd_portid, info->snd_seq);
779
780 exit:
781 device_unlock(&dev->dev);
782
783 nfc_put_device(dev);
784
785 if (rc < 0) {
786 if (msg)
787 nlmsg_free(msg);
788
789 return rc;
790 }
791
792 return genlmsg_reply(msg, info);
793 }
794
795 static int nfc_genl_llc_set_params(struct sk_buff *skb, struct genl_info *info)
796 {
797 struct nfc_dev *dev;
798 struct nfc_llcp_local *local;
799 u8 rw = 0;
800 u16 miux = 0;
801 u32 idx;
802 int rc = 0;
803
804 if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
805 (!info->attrs[NFC_ATTR_LLC_PARAM_LTO] &&
806 !info->attrs[NFC_ATTR_LLC_PARAM_RW] &&
807 !info->attrs[NFC_ATTR_LLC_PARAM_MIUX]))
808 return -EINVAL;
809
810 if (info->attrs[NFC_ATTR_LLC_PARAM_RW]) {
811 rw = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_RW]);
812
813 if (rw > LLCP_MAX_RW)
814 return -EINVAL;
815 }
816
817 if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX]) {
818 miux = nla_get_u16(info->attrs[NFC_ATTR_LLC_PARAM_MIUX]);
819
820 if (miux > LLCP_MAX_MIUX)
821 return -EINVAL;
822 }
823
824 idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
825
826 dev = nfc_get_device(idx);
827 if (!dev)
828 return -ENODEV;
829
830 device_lock(&dev->dev);
831
832 local = nfc_llcp_find_local(dev);
833 if (!local) {
834 nfc_put_device(dev);
835 rc = -ENODEV;
836 goto exit;
837 }
838
839 if (info->attrs[NFC_ATTR_LLC_PARAM_LTO]) {
840 if (dev->dep_link_up) {
841 rc = -EINPROGRESS;
842 goto exit;
843 }
844
845 local->lto = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_LTO]);
846 }
847
848 if (info->attrs[NFC_ATTR_LLC_PARAM_RW])
849 local->rw = rw;
850
851 if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX])
852 local->miux = cpu_to_be16(miux);
853
854 exit:
855 device_unlock(&dev->dev);
856
857 nfc_put_device(dev);
858
859 return rc;
860 }
861
862 static struct genl_ops nfc_genl_ops[] = {
863 {
864 .cmd = NFC_CMD_GET_DEVICE,
865 .doit = nfc_genl_get_device,
866 .dumpit = nfc_genl_dump_devices,
867 .done = nfc_genl_dump_devices_done,
868 .policy = nfc_genl_policy,
869 },
870 {
871 .cmd = NFC_CMD_DEV_UP,
872 .doit = nfc_genl_dev_up,
873 .policy = nfc_genl_policy,
874 },
875 {
876 .cmd = NFC_CMD_DEV_DOWN,
877 .doit = nfc_genl_dev_down,
878 .policy = nfc_genl_policy,
879 },
880 {
881 .cmd = NFC_CMD_START_POLL,
882 .doit = nfc_genl_start_poll,
883 .policy = nfc_genl_policy,
884 },
885 {
886 .cmd = NFC_CMD_STOP_POLL,
887 .doit = nfc_genl_stop_poll,
888 .policy = nfc_genl_policy,
889 },
890 {
891 .cmd = NFC_CMD_DEP_LINK_UP,
892 .doit = nfc_genl_dep_link_up,
893 .policy = nfc_genl_policy,
894 },
895 {
896 .cmd = NFC_CMD_DEP_LINK_DOWN,
897 .doit = nfc_genl_dep_link_down,
898 .policy = nfc_genl_policy,
899 },
900 {
901 .cmd = NFC_CMD_GET_TARGET,
902 .dumpit = nfc_genl_dump_targets,
903 .done = nfc_genl_dump_targets_done,
904 .policy = nfc_genl_policy,
905 },
906 {
907 .cmd = NFC_CMD_LLC_GET_PARAMS,
908 .doit = nfc_genl_llc_get_params,
909 .policy = nfc_genl_policy,
910 },
911 {
912 .cmd = NFC_CMD_LLC_SET_PARAMS,
913 .doit = nfc_genl_llc_set_params,
914 .policy = nfc_genl_policy,
915 },
916 };
917
918
919 struct urelease_work {
920 struct work_struct w;
921 int portid;
922 };
923
924 static void nfc_urelease_event_work(struct work_struct *work)
925 {
926 struct urelease_work *w = container_of(work, struct urelease_work, w);
927 struct class_dev_iter iter;
928 struct nfc_dev *dev;
929
930 pr_debug("portid %d\n", w->portid);
931
932 mutex_lock(&nfc_devlist_mutex);
933
934 nfc_device_iter_init(&iter);
935 dev = nfc_device_iter_next(&iter);
936
937 while (dev) {
938 mutex_lock(&dev->genl_data.genl_data_mutex);
939
940 if (dev->genl_data.poll_req_portid == w->portid) {
941 nfc_stop_poll(dev);
942 dev->genl_data.poll_req_portid = 0;
943 }
944
945 mutex_unlock(&dev->genl_data.genl_data_mutex);
946
947 dev = nfc_device_iter_next(&iter);
948 }
949
950 nfc_device_iter_exit(&iter);
951
952 mutex_unlock(&nfc_devlist_mutex);
953
954 kfree(w);
955 }
956
957 static int nfc_genl_rcv_nl_event(struct notifier_block *this,
958 unsigned long event, void *ptr)
959 {
960 struct netlink_notify *n = ptr;
961 struct urelease_work *w;
962
963 if (event != NETLINK_URELEASE || n->protocol != NETLINK_GENERIC)
964 goto out;
965
966 pr_debug("NETLINK_URELEASE event from id %d\n", n->portid);
967
968 w = kmalloc(sizeof(*w), GFP_ATOMIC);
969 if (w) {
970 INIT_WORK((struct work_struct *) w, nfc_urelease_event_work);
971 w->portid = n->portid;
972 schedule_work((struct work_struct *) w);
973 }
974
975 out:
976 return NOTIFY_DONE;
977 }
978
979 void nfc_genl_data_init(struct nfc_genl_data *genl_data)
980 {
981 genl_data->poll_req_portid = 0;
982 mutex_init(&genl_data->genl_data_mutex);
983 }
984
985 void nfc_genl_data_exit(struct nfc_genl_data *genl_data)
986 {
987 mutex_destroy(&genl_data->genl_data_mutex);
988 }
989
990 static struct notifier_block nl_notifier = {
991 .notifier_call = nfc_genl_rcv_nl_event,
992 };
993
994 /**
995 * nfc_genl_init() - Initialize netlink interface
996 *
997 * This initialization function registers the nfc netlink family.
998 */
999 int __init nfc_genl_init(void)
1000 {
1001 int rc;
1002
1003 rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops,
1004 ARRAY_SIZE(nfc_genl_ops));
1005 if (rc)
1006 return rc;
1007
1008 rc = genl_register_mc_group(&nfc_genl_family, &nfc_genl_event_mcgrp);
1009
1010 netlink_register_notifier(&nl_notifier);
1011
1012 return rc;
1013 }
1014
1015 /**
1016 * nfc_genl_exit() - Deinitialize netlink interface
1017 *
1018 * This exit function unregisters the nfc netlink family.
1019 */
1020 void nfc_genl_exit(void)
1021 {
1022 netlink_unregister_notifier(&nl_notifier);
1023 genl_unregister_family(&nfc_genl_family);
1024 }
This page took 0.059794 seconds and 6 git commands to generate.