linux/net/nfc/af_nfc.c
<<
>>
Prefs
   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
  10#include <linux/nfc.h>
  11#include <linux/module.h>
  12
  13#include "nfc.h"
  14
  15static DEFINE_RWLOCK(proto_tab_lock);
  16static const struct nfc_protocol *proto_tab[NFC_SOCKPROTO_MAX];
  17
  18static int nfc_sock_create(struct net *net, struct socket *sock, int proto,
  19                           int kern)
  20{
  21        int rc = -EPROTONOSUPPORT;
  22
  23        if (net != &init_net)
  24                return -EAFNOSUPPORT;
  25
  26        if (proto < 0 || proto >= NFC_SOCKPROTO_MAX)
  27                return -EINVAL;
  28
  29        read_lock(&proto_tab_lock);
  30        if (proto_tab[proto] && try_module_get(proto_tab[proto]->owner)) {
  31                rc = proto_tab[proto]->create(net, sock, proto_tab[proto], kern);
  32                module_put(proto_tab[proto]->owner);
  33        }
  34        read_unlock(&proto_tab_lock);
  35
  36        return rc;
  37}
  38
  39static const struct net_proto_family nfc_sock_family_ops = {
  40        .owner  = THIS_MODULE,
  41        .family = PF_NFC,
  42        .create = nfc_sock_create,
  43};
  44
  45int nfc_proto_register(const struct nfc_protocol *nfc_proto)
  46{
  47        int rc;
  48
  49        if (nfc_proto->id < 0 || nfc_proto->id >= NFC_SOCKPROTO_MAX)
  50                return -EINVAL;
  51
  52        rc = proto_register(nfc_proto->proto, 0);
  53        if (rc)
  54                return rc;
  55
  56        write_lock(&proto_tab_lock);
  57        if (proto_tab[nfc_proto->id])
  58                rc = -EBUSY;
  59        else
  60                proto_tab[nfc_proto->id] = nfc_proto;
  61        write_unlock(&proto_tab_lock);
  62
  63        return rc;
  64}
  65EXPORT_SYMBOL(nfc_proto_register);
  66
  67void nfc_proto_unregister(const struct nfc_protocol *nfc_proto)
  68{
  69        write_lock(&proto_tab_lock);
  70        proto_tab[nfc_proto->id] = NULL;
  71        write_unlock(&proto_tab_lock);
  72
  73        proto_unregister(nfc_proto->proto);
  74}
  75EXPORT_SYMBOL(nfc_proto_unregister);
  76
  77int __init af_nfc_init(void)
  78{
  79        return sock_register(&nfc_sock_family_ops);
  80}
  81
  82void af_nfc_exit(void)
  83{
  84        sock_unregister(PF_NFC);
  85}
  86