af_nfc.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2011 Instituto Nokia de Tecnologia
  4. *
  5. * Authors:
  6. * Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
  7. * Lauro Ramos Venancio <lauro.venancio@openbossa.org>
  8. */
  9. #include <linux/nfc.h>
  10. #include <linux/module.h>
  11. #include "nfc.h"
  12. static DEFINE_RWLOCK(proto_tab_lock);
  13. static const struct nfc_protocol *proto_tab[NFC_SOCKPROTO_MAX];
  14. static int nfc_sock_create(struct net *net, struct socket *sock, int proto,
  15. int kern)
  16. {
  17. int rc = -EPROTONOSUPPORT;
  18. if (net != &init_net)
  19. return -EAFNOSUPPORT;
  20. if (proto < 0 || proto >= NFC_SOCKPROTO_MAX)
  21. return -EINVAL;
  22. read_lock(&proto_tab_lock);
  23. if (proto_tab[proto] && try_module_get(proto_tab[proto]->owner)) {
  24. rc = proto_tab[proto]->create(net, sock, proto_tab[proto], kern);
  25. module_put(proto_tab[proto]->owner);
  26. }
  27. read_unlock(&proto_tab_lock);
  28. return rc;
  29. }
  30. static const struct net_proto_family nfc_sock_family_ops = {
  31. .owner = THIS_MODULE,
  32. .family = PF_NFC,
  33. .create = nfc_sock_create,
  34. };
  35. int nfc_proto_register(const struct nfc_protocol *nfc_proto)
  36. {
  37. int rc;
  38. if (nfc_proto->id < 0 || nfc_proto->id >= NFC_SOCKPROTO_MAX)
  39. return -EINVAL;
  40. rc = proto_register(nfc_proto->proto, 0);
  41. if (rc)
  42. return rc;
  43. write_lock(&proto_tab_lock);
  44. if (proto_tab[nfc_proto->id])
  45. rc = -EBUSY;
  46. else
  47. proto_tab[nfc_proto->id] = nfc_proto;
  48. write_unlock(&proto_tab_lock);
  49. if (rc)
  50. proto_unregister(nfc_proto->proto);
  51. return rc;
  52. }
  53. EXPORT_SYMBOL(nfc_proto_register);
  54. void nfc_proto_unregister(const struct nfc_protocol *nfc_proto)
  55. {
  56. write_lock(&proto_tab_lock);
  57. proto_tab[nfc_proto->id] = NULL;
  58. write_unlock(&proto_tab_lock);
  59. proto_unregister(nfc_proto->proto);
  60. }
  61. EXPORT_SYMBOL(nfc_proto_unregister);
  62. int __init af_nfc_init(void)
  63. {
  64. return sock_register(&nfc_sock_family_ops);
  65. }
  66. void af_nfc_exit(void)
  67. {
  68. sock_unregister(PF_NFC);
  69. }