netlink.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838
  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. #define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
  24. #include <net/genetlink.h>
  25. #include <linux/nfc.h>
  26. #include <linux/slab.h>
  27. #include "nfc.h"
  28. static struct genl_multicast_group nfc_genl_event_mcgrp = {
  29. .name = NFC_GENL_MCAST_EVENT_NAME,
  30. };
  31. static struct genl_family nfc_genl_family = {
  32. .id = GENL_ID_GENERATE,
  33. .hdrsize = 0,
  34. .name = NFC_GENL_NAME,
  35. .version = NFC_GENL_VERSION,
  36. .maxattr = NFC_ATTR_MAX,
  37. };
  38. static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = {
  39. [NFC_ATTR_DEVICE_INDEX] = { .type = NLA_U32 },
  40. [NFC_ATTR_DEVICE_NAME] = { .type = NLA_STRING,
  41. .len = NFC_DEVICE_NAME_MAXSIZE },
  42. [NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 },
  43. [NFC_ATTR_COMM_MODE] = { .type = NLA_U8 },
  44. [NFC_ATTR_RF_MODE] = { .type = NLA_U8 },
  45. [NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 },
  46. [NFC_ATTR_IM_PROTOCOLS] = { .type = NLA_U32 },
  47. [NFC_ATTR_TM_PROTOCOLS] = { .type = NLA_U32 },
  48. };
  49. static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,
  50. struct netlink_callback *cb, int flags)
  51. {
  52. void *hdr;
  53. hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
  54. &nfc_genl_family, flags, NFC_CMD_GET_TARGET);
  55. if (!hdr)
  56. return -EMSGSIZE;
  57. genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
  58. if (nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target->idx) ||
  59. nla_put_u32(msg, NFC_ATTR_PROTOCOLS, target->supported_protocols) ||
  60. nla_put_u16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res) ||
  61. nla_put_u8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res))
  62. goto nla_put_failure;
  63. if (target->nfcid1_len > 0 &&
  64. nla_put(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len,
  65. target->nfcid1))
  66. goto nla_put_failure;
  67. if (target->sensb_res_len > 0 &&
  68. nla_put(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len,
  69. target->sensb_res))
  70. goto nla_put_failure;
  71. if (target->sensf_res_len > 0 &&
  72. nla_put(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len,
  73. target->sensf_res))
  74. goto nla_put_failure;
  75. return genlmsg_end(msg, hdr);
  76. nla_put_failure:
  77. genlmsg_cancel(msg, hdr);
  78. return -EMSGSIZE;
  79. }
  80. static struct nfc_dev *__get_device_from_cb(struct netlink_callback *cb)
  81. {
  82. struct nfc_dev *dev;
  83. int rc;
  84. u32 idx;
  85. rc = nlmsg_parse(cb->nlh, GENL_HDRLEN + nfc_genl_family.hdrsize,
  86. nfc_genl_family.attrbuf,
  87. nfc_genl_family.maxattr,
  88. nfc_genl_policy);
  89. if (rc < 0)
  90. return ERR_PTR(rc);
  91. if (!nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX])
  92. return ERR_PTR(-EINVAL);
  93. idx = nla_get_u32(nfc_genl_family.attrbuf[NFC_ATTR_DEVICE_INDEX]);
  94. dev = nfc_get_device(idx);
  95. if (!dev)
  96. return ERR_PTR(-ENODEV);
  97. return dev;
  98. }
  99. static int nfc_genl_dump_targets(struct sk_buff *skb,
  100. struct netlink_callback *cb)
  101. {
  102. int i = cb->args[0];
  103. struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
  104. int rc;
  105. if (!dev) {
  106. dev = __get_device_from_cb(cb);
  107. if (IS_ERR(dev))
  108. return PTR_ERR(dev);
  109. cb->args[1] = (long) dev;
  110. }
  111. device_lock(&dev->dev);
  112. cb->seq = dev->targets_generation;
  113. while (i < dev->n_targets) {
  114. rc = nfc_genl_send_target(skb, &dev->targets[i], cb,
  115. NLM_F_MULTI);
  116. if (rc < 0)
  117. break;
  118. i++;
  119. }
  120. device_unlock(&dev->dev);
  121. cb->args[0] = i;
  122. return skb->len;
  123. }
  124. static int nfc_genl_dump_targets_done(struct netlink_callback *cb)
  125. {
  126. struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
  127. if (dev)
  128. nfc_put_device(dev);
  129. return 0;
  130. }
  131. int nfc_genl_targets_found(struct nfc_dev *dev)
  132. {
  133. struct sk_buff *msg;
  134. void *hdr;
  135. dev->genl_data.poll_req_pid = 0;
  136. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
  137. if (!msg)
  138. return -ENOMEM;
  139. hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
  140. NFC_EVENT_TARGETS_FOUND);
  141. if (!hdr)
  142. goto free_msg;
  143. if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
  144. goto nla_put_failure;
  145. genlmsg_end(msg, hdr);
  146. return genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
  147. nla_put_failure:
  148. genlmsg_cancel(msg, hdr);
  149. free_msg:
  150. nlmsg_free(msg);
  151. return -EMSGSIZE;
  152. }
  153. int nfc_genl_target_lost(struct nfc_dev *dev, u32 target_idx)
  154. {
  155. struct sk_buff *msg;
  156. void *hdr;
  157. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  158. if (!msg)
  159. return -ENOMEM;
  160. hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
  161. NFC_EVENT_TARGET_LOST);
  162. if (!hdr)
  163. goto free_msg;
  164. if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
  165. nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target_idx))
  166. goto nla_put_failure;
  167. genlmsg_end(msg, hdr);
  168. genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
  169. return 0;
  170. nla_put_failure:
  171. genlmsg_cancel(msg, hdr);
  172. free_msg:
  173. nlmsg_free(msg);
  174. return -EMSGSIZE;
  175. }
  176. int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol)
  177. {
  178. struct sk_buff *msg;
  179. void *hdr;
  180. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  181. if (!msg)
  182. return -ENOMEM;
  183. hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
  184. NFC_EVENT_TM_ACTIVATED);
  185. if (!hdr)
  186. goto free_msg;
  187. if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
  188. goto nla_put_failure;
  189. if (nla_put_u32(msg, NFC_ATTR_TM_PROTOCOLS, protocol))
  190. goto nla_put_failure;
  191. genlmsg_end(msg, hdr);
  192. genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
  193. return 0;
  194. nla_put_failure:
  195. genlmsg_cancel(msg, hdr);
  196. free_msg:
  197. nlmsg_free(msg);
  198. return -EMSGSIZE;
  199. }
  200. int nfc_genl_tm_deactivated(struct nfc_dev *dev)
  201. {
  202. struct sk_buff *msg;
  203. void *hdr;
  204. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  205. if (!msg)
  206. return -ENOMEM;
  207. hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
  208. NFC_EVENT_TM_DEACTIVATED);
  209. if (!hdr)
  210. goto free_msg;
  211. if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
  212. goto nla_put_failure;
  213. genlmsg_end(msg, hdr);
  214. genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
  215. return 0;
  216. nla_put_failure:
  217. genlmsg_cancel(msg, hdr);
  218. free_msg:
  219. nlmsg_free(msg);
  220. return -EMSGSIZE;
  221. }
  222. int nfc_genl_device_added(struct nfc_dev *dev)
  223. {
  224. struct sk_buff *msg;
  225. void *hdr;
  226. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  227. if (!msg)
  228. return -ENOMEM;
  229. hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
  230. NFC_EVENT_DEVICE_ADDED);
  231. if (!hdr)
  232. goto free_msg;
  233. if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
  234. nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
  235. nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
  236. nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up))
  237. goto nla_put_failure;
  238. genlmsg_end(msg, hdr);
  239. genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
  240. return 0;
  241. nla_put_failure:
  242. genlmsg_cancel(msg, hdr);
  243. free_msg:
  244. nlmsg_free(msg);
  245. return -EMSGSIZE;
  246. }
  247. int nfc_genl_device_removed(struct nfc_dev *dev)
  248. {
  249. struct sk_buff *msg;
  250. void *hdr;
  251. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  252. if (!msg)
  253. return -ENOMEM;
  254. hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
  255. NFC_EVENT_DEVICE_REMOVED);
  256. if (!hdr)
  257. goto free_msg;
  258. if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
  259. goto nla_put_failure;
  260. genlmsg_end(msg, hdr);
  261. genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
  262. return 0;
  263. nla_put_failure:
  264. genlmsg_cancel(msg, hdr);
  265. free_msg:
  266. nlmsg_free(msg);
  267. return -EMSGSIZE;
  268. }
  269. static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
  270. u32 pid, u32 seq,
  271. struct netlink_callback *cb,
  272. int flags)
  273. {
  274. void *hdr;
  275. hdr = genlmsg_put(msg, pid, seq, &nfc_genl_family, flags,
  276. NFC_CMD_GET_DEVICE);
  277. if (!hdr)
  278. return -EMSGSIZE;
  279. if (cb)
  280. genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
  281. if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
  282. nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
  283. nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
  284. nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up))
  285. goto nla_put_failure;
  286. return genlmsg_end(msg, hdr);
  287. nla_put_failure:
  288. genlmsg_cancel(msg, hdr);
  289. return -EMSGSIZE;
  290. }
  291. static int nfc_genl_dump_devices(struct sk_buff *skb,
  292. struct netlink_callback *cb)
  293. {
  294. struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
  295. struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
  296. bool first_call = false;
  297. if (!iter) {
  298. first_call = true;
  299. iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL);
  300. if (!iter)
  301. return -ENOMEM;
  302. cb->args[0] = (long) iter;
  303. }
  304. mutex_lock(&nfc_devlist_mutex);
  305. cb->seq = nfc_devlist_generation;
  306. if (first_call) {
  307. nfc_device_iter_init(iter);
  308. dev = nfc_device_iter_next(iter);
  309. }
  310. while (dev) {
  311. int rc;
  312. rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).pid,
  313. cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
  314. if (rc < 0)
  315. break;
  316. dev = nfc_device_iter_next(iter);
  317. }
  318. mutex_unlock(&nfc_devlist_mutex);
  319. cb->args[1] = (long) dev;
  320. return skb->len;
  321. }
  322. static int nfc_genl_dump_devices_done(struct netlink_callback *cb)
  323. {
  324. struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
  325. nfc_device_iter_exit(iter);
  326. kfree(iter);
  327. return 0;
  328. }
  329. int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx,
  330. u8 comm_mode, u8 rf_mode)
  331. {
  332. struct sk_buff *msg;
  333. void *hdr;
  334. pr_debug("DEP link is up\n");
  335. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
  336. if (!msg)
  337. return -ENOMEM;
  338. hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, NFC_CMD_DEP_LINK_UP);
  339. if (!hdr)
  340. goto free_msg;
  341. if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
  342. goto nla_put_failure;
  343. if (rf_mode == NFC_RF_INITIATOR &&
  344. nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target_idx))
  345. goto nla_put_failure;
  346. if (nla_put_u8(msg, NFC_ATTR_COMM_MODE, comm_mode) ||
  347. nla_put_u8(msg, NFC_ATTR_RF_MODE, rf_mode))
  348. goto nla_put_failure;
  349. genlmsg_end(msg, hdr);
  350. dev->dep_link_up = true;
  351. genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
  352. return 0;
  353. nla_put_failure:
  354. genlmsg_cancel(msg, hdr);
  355. free_msg:
  356. nlmsg_free(msg);
  357. return -EMSGSIZE;
  358. }
  359. int nfc_genl_dep_link_down_event(struct nfc_dev *dev)
  360. {
  361. struct sk_buff *msg;
  362. void *hdr;
  363. pr_debug("DEP link is down\n");
  364. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
  365. if (!msg)
  366. return -ENOMEM;
  367. hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
  368. NFC_CMD_DEP_LINK_DOWN);
  369. if (!hdr)
  370. goto free_msg;
  371. if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
  372. goto nla_put_failure;
  373. genlmsg_end(msg, hdr);
  374. genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_ATOMIC);
  375. return 0;
  376. nla_put_failure:
  377. genlmsg_cancel(msg, hdr);
  378. free_msg:
  379. nlmsg_free(msg);
  380. return -EMSGSIZE;
  381. }
  382. static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info)
  383. {
  384. struct sk_buff *msg;
  385. struct nfc_dev *dev;
  386. u32 idx;
  387. int rc = -ENOBUFS;
  388. if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
  389. return -EINVAL;
  390. idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
  391. dev = nfc_get_device(idx);
  392. if (!dev)
  393. return -ENODEV;
  394. msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  395. if (!msg) {
  396. rc = -ENOMEM;
  397. goto out_putdev;
  398. }
  399. rc = nfc_genl_send_device(msg, dev, info->snd_pid, info->snd_seq,
  400. NULL, 0);
  401. if (rc < 0)
  402. goto out_free;
  403. nfc_put_device(dev);
  404. return genlmsg_reply(msg, info);
  405. out_free:
  406. nlmsg_free(msg);
  407. out_putdev:
  408. nfc_put_device(dev);
  409. return rc;
  410. }
  411. static int nfc_genl_dev_up(struct sk_buff *skb, struct genl_info *info)
  412. {
  413. struct nfc_dev *dev;
  414. int rc;
  415. u32 idx;
  416. if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
  417. return -EINVAL;
  418. idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
  419. dev = nfc_get_device(idx);
  420. if (!dev)
  421. return -ENODEV;
  422. rc = nfc_dev_up(dev);
  423. nfc_put_device(dev);
  424. return rc;
  425. }
  426. static int nfc_genl_dev_down(struct sk_buff *skb, struct genl_info *info)
  427. {
  428. struct nfc_dev *dev;
  429. int rc;
  430. u32 idx;
  431. if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
  432. return -EINVAL;
  433. idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
  434. dev = nfc_get_device(idx);
  435. if (!dev)
  436. return -ENODEV;
  437. rc = nfc_dev_down(dev);
  438. nfc_put_device(dev);
  439. return rc;
  440. }
  441. static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info)
  442. {
  443. struct nfc_dev *dev;
  444. int rc;
  445. u32 idx;
  446. u32 im_protocols = 0, tm_protocols = 0;
  447. pr_debug("Poll start\n");
  448. if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
  449. ((!info->attrs[NFC_ATTR_IM_PROTOCOLS] &&
  450. !info->attrs[NFC_ATTR_PROTOCOLS]) &&
  451. !info->attrs[NFC_ATTR_TM_PROTOCOLS]))
  452. return -EINVAL;
  453. idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
  454. if (info->attrs[NFC_ATTR_TM_PROTOCOLS])
  455. tm_protocols = nla_get_u32(info->attrs[NFC_ATTR_TM_PROTOCOLS]);
  456. if (info->attrs[NFC_ATTR_IM_PROTOCOLS])
  457. im_protocols = nla_get_u32(info->attrs[NFC_ATTR_IM_PROTOCOLS]);
  458. else if (info->attrs[NFC_ATTR_PROTOCOLS])
  459. im_protocols = nla_get_u32(info->attrs[NFC_ATTR_PROTOCOLS]);
  460. dev = nfc_get_device(idx);
  461. if (!dev)
  462. return -ENODEV;
  463. mutex_lock(&dev->genl_data.genl_data_mutex);
  464. rc = nfc_start_poll(dev, im_protocols, tm_protocols);
  465. if (!rc)
  466. dev->genl_data.poll_req_pid = info->snd_pid;
  467. mutex_unlock(&dev->genl_data.genl_data_mutex);
  468. nfc_put_device(dev);
  469. return rc;
  470. }
  471. static int nfc_genl_stop_poll(struct sk_buff *skb, struct genl_info *info)
  472. {
  473. struct nfc_dev *dev;
  474. int rc;
  475. u32 idx;
  476. if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
  477. return -EINVAL;
  478. idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
  479. dev = nfc_get_device(idx);
  480. if (!dev)
  481. return -ENODEV;
  482. device_lock(&dev->dev);
  483. if (!dev->polling) {
  484. device_unlock(&dev->dev);
  485. return -EINVAL;
  486. }
  487. device_unlock(&dev->dev);
  488. mutex_lock(&dev->genl_data.genl_data_mutex);
  489. if (dev->genl_data.poll_req_pid != info->snd_pid) {
  490. rc = -EBUSY;
  491. goto out;
  492. }
  493. rc = nfc_stop_poll(dev);
  494. dev->genl_data.poll_req_pid = 0;
  495. out:
  496. mutex_unlock(&dev->genl_data.genl_data_mutex);
  497. nfc_put_device(dev);
  498. return rc;
  499. }
  500. static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info)
  501. {
  502. struct nfc_dev *dev;
  503. int rc, tgt_idx;
  504. u32 idx;
  505. u8 comm;
  506. pr_debug("DEP link up\n");
  507. if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
  508. !info->attrs[NFC_ATTR_COMM_MODE])
  509. return -EINVAL;
  510. idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
  511. if (!info->attrs[NFC_ATTR_TARGET_INDEX])
  512. tgt_idx = NFC_TARGET_IDX_ANY;
  513. else
  514. tgt_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);
  515. comm = nla_get_u8(info->attrs[NFC_ATTR_COMM_MODE]);
  516. if (comm != NFC_COMM_ACTIVE && comm != NFC_COMM_PASSIVE)
  517. return -EINVAL;
  518. dev = nfc_get_device(idx);
  519. if (!dev)
  520. return -ENODEV;
  521. rc = nfc_dep_link_up(dev, tgt_idx, comm);
  522. nfc_put_device(dev);
  523. return rc;
  524. }
  525. static int nfc_genl_dep_link_down(struct sk_buff *skb, struct genl_info *info)
  526. {
  527. struct nfc_dev *dev;
  528. int rc;
  529. u32 idx;
  530. if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
  531. return -EINVAL;
  532. idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
  533. dev = nfc_get_device(idx);
  534. if (!dev)
  535. return -ENODEV;
  536. rc = nfc_dep_link_down(dev);
  537. nfc_put_device(dev);
  538. return rc;
  539. }
  540. static struct genl_ops nfc_genl_ops[] = {
  541. {
  542. .cmd = NFC_CMD_GET_DEVICE,
  543. .doit = nfc_genl_get_device,
  544. .dumpit = nfc_genl_dump_devices,
  545. .done = nfc_genl_dump_devices_done,
  546. .policy = nfc_genl_policy,
  547. },
  548. {
  549. .cmd = NFC_CMD_DEV_UP,
  550. .doit = nfc_genl_dev_up,
  551. .policy = nfc_genl_policy,
  552. },
  553. {
  554. .cmd = NFC_CMD_DEV_DOWN,
  555. .doit = nfc_genl_dev_down,
  556. .policy = nfc_genl_policy,
  557. },
  558. {
  559. .cmd = NFC_CMD_START_POLL,
  560. .doit = nfc_genl_start_poll,
  561. .policy = nfc_genl_policy,
  562. },
  563. {
  564. .cmd = NFC_CMD_STOP_POLL,
  565. .doit = nfc_genl_stop_poll,
  566. .policy = nfc_genl_policy,
  567. },
  568. {
  569. .cmd = NFC_CMD_DEP_LINK_UP,
  570. .doit = nfc_genl_dep_link_up,
  571. .policy = nfc_genl_policy,
  572. },
  573. {
  574. .cmd = NFC_CMD_DEP_LINK_DOWN,
  575. .doit = nfc_genl_dep_link_down,
  576. .policy = nfc_genl_policy,
  577. },
  578. {
  579. .cmd = NFC_CMD_GET_TARGET,
  580. .dumpit = nfc_genl_dump_targets,
  581. .done = nfc_genl_dump_targets_done,
  582. .policy = nfc_genl_policy,
  583. },
  584. };
  585. static int nfc_genl_rcv_nl_event(struct notifier_block *this,
  586. unsigned long event, void *ptr)
  587. {
  588. struct netlink_notify *n = ptr;
  589. struct class_dev_iter iter;
  590. struct nfc_dev *dev;
  591. if (event != NETLINK_URELEASE || n->protocol != NETLINK_GENERIC)
  592. goto out;
  593. pr_debug("NETLINK_URELEASE event from id %d\n", n->pid);
  594. nfc_device_iter_init(&iter);
  595. dev = nfc_device_iter_next(&iter);
  596. while (dev) {
  597. if (dev->genl_data.poll_req_pid == n->pid) {
  598. nfc_stop_poll(dev);
  599. dev->genl_data.poll_req_pid = 0;
  600. }
  601. dev = nfc_device_iter_next(&iter);
  602. }
  603. nfc_device_iter_exit(&iter);
  604. out:
  605. return NOTIFY_DONE;
  606. }
  607. void nfc_genl_data_init(struct nfc_genl_data *genl_data)
  608. {
  609. genl_data->poll_req_pid = 0;
  610. mutex_init(&genl_data->genl_data_mutex);
  611. }
  612. void nfc_genl_data_exit(struct nfc_genl_data *genl_data)
  613. {
  614. mutex_destroy(&genl_data->genl_data_mutex);
  615. }
  616. static struct notifier_block nl_notifier = {
  617. .notifier_call = nfc_genl_rcv_nl_event,
  618. };
  619. /**
  620. * nfc_genl_init() - Initialize netlink interface
  621. *
  622. * This initialization function registers the nfc netlink family.
  623. */
  624. int __init nfc_genl_init(void)
  625. {
  626. int rc;
  627. rc = genl_register_family_with_ops(&nfc_genl_family, nfc_genl_ops,
  628. ARRAY_SIZE(nfc_genl_ops));
  629. if (rc)
  630. return rc;
  631. rc = genl_register_mc_group(&nfc_genl_family, &nfc_genl_event_mcgrp);
  632. netlink_register_notifier(&nl_notifier);
  633. return rc;
  634. }
  635. /**
  636. * nfc_genl_exit() - Deinitialize netlink interface
  637. *
  638. * This exit function unregisters the nfc netlink family.
  639. */
  640. void nfc_genl_exit(void)
  641. {
  642. netlink_unregister_notifier(&nl_notifier);
  643. genl_unregister_family(&nfc_genl_family);
  644. }