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