linux/net/nfc/af_nfc.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 Instituto Nokia de Tecnologia
   3 *
   4 * Authors:
   5 *    Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
   6 *    Lauro Ramos Venancio <lauro.venancio@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, see <http://www.gnu.org/licenses/>.
  20 */
  21
  22#include <linux/nfc.h>
  23#include <linux/module.h>
  24
  25#include "nfc.h"
  26
  27static DEFINE_RWLOCK(proto_tab_lock);
  28static const struct nfc_protocol *proto_tab[NFC_SOCKPROTO_MAX];
  29
  30static int nfc_sock_create(struct net *net, struct socket *sock, int proto,
  31                           int kern)
  32{
  33        int rc = -EPROTONOSUPPORT;
  34
  35        if (net != &init_net)
  36                return -EAFNOSUPPORT;
  37
  38        if (proto < 0 || proto >= NFC_SOCKPROTO_MAX)
  39                return -EINVAL;
  40
  41        read_lock(&proto_tab_lock);
  42        if (proto_tab[proto] && try_module_get(proto_tab[proto]->owner)) {
  43                rc = proto_tab[proto]->create(net, sock, proto_tab[proto], kern);
  44                module_put(proto_tab[proto]->owner);
  45        }
  46        read_unlock(&proto_tab_lock);
  47
  48        return rc;
  49}
  50
  51static struct net_proto_family nfc_sock_family_ops = {
  52        .owner  = THIS_MODULE,
  53        .family = PF_NFC,
  54        .create = nfc_sock_create,
  55};
  56
  57int nfc_proto_register(const struct nfc_protocol *nfc_proto)
  58{
  59        int rc;
  60
  61        if (nfc_proto->id < 0 || nfc_proto->id >= NFC_SOCKPROTO_MAX)
  62                return -EINVAL;
  63
  64        rc = proto_register(nfc_proto->proto, 0);
  65        if (rc)
  66                return rc;
  67
  68        write_lock(&proto_tab_lock);
  69        if (proto_tab[nfc_proto->id])
  70                rc = -EBUSY;
  71        else
  72                proto_tab[nfc_proto->id] = nfc_proto;
  73        write_unlock(&proto_tab_lock);
  74
  75        return rc;
  76}
  77EXPORT_SYMBOL(nfc_proto_register);
  78
  79void nfc_proto_unregister(const struct nfc_protocol *nfc_proto)
  80{
  81        write_lock(&proto_tab_lock);
  82        proto_tab[nfc_proto->id] = NULL;
  83        write_unlock(&proto_tab_lock);
  84
  85        proto_unregister(nfc_proto->proto);
  86}
  87EXPORT_SYMBOL(nfc_proto_unregister);
  88
  89int __init af_nfc_init(void)
  90{
  91        return sock_register(&nfc_sock_family_ops);
  92}
  93
  94void af_nfc_exit(void)
  95{
  96        sock_unregister(PF_NFC);
  97}
  98