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, write to the
  20 * Free Software Foundation, Inc.,
  21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22 */
  23
  24#include <linux/nfc.h>
  25#include <linux/module.h>
  26
  27#include "nfc.h"
  28
  29static DEFINE_RWLOCK(proto_tab_lock);
  30static const struct nfc_protocol *proto_tab[NFC_SOCKPROTO_MAX];
  31
  32static int nfc_sock_create(struct net *net, struct socket *sock, int proto,
  33                           int kern)
  34{
  35        int rc = -EPROTONOSUPPORT;
  36
  37        if (net != &init_net)
  38                return -EAFNOSUPPORT;
  39
  40        if (proto < 0 || proto >= NFC_SOCKPROTO_MAX)
  41                return -EINVAL;
  42
  43        read_lock(&proto_tab_lock);
  44        if (proto_tab[proto] && try_module_get(proto_tab[proto]->owner)) {
  45                rc = proto_tab[proto]->create(net, sock, proto_tab[proto]);
  46                module_put(proto_tab[proto]->owner);
  47        }
  48        read_unlock(&proto_tab_lock);
  49
  50        return rc;
  51}
  52
  53static struct net_proto_family nfc_sock_family_ops = {
  54        .owner  = THIS_MODULE,
  55        .family = PF_NFC,
  56        .create = nfc_sock_create,
  57};
  58
  59int nfc_proto_register(const struct nfc_protocol *nfc_proto)
  60{
  61        int rc;
  62
  63        if (nfc_proto->id < 0 || nfc_proto->id >= NFC_SOCKPROTO_MAX)
  64                return -EINVAL;
  65
  66        rc = proto_register(nfc_proto->proto, 0);
  67        if (rc)
  68                return rc;
  69
  70        write_lock(&proto_tab_lock);
  71        if (proto_tab[nfc_proto->id])
  72                rc = -EBUSY;
  73        else
  74                proto_tab[nfc_proto->id] = nfc_proto;
  75        write_unlock(&proto_tab_lock);
  76
  77        return rc;
  78}
  79EXPORT_SYMBOL(nfc_proto_register);
  80
  81void nfc_proto_unregister(const struct nfc_protocol *nfc_proto)
  82{
  83        write_lock(&proto_tab_lock);
  84        proto_tab[nfc_proto->id] = NULL;
  85        write_unlock(&proto_tab_lock);
  86
  87        proto_unregister(nfc_proto->proto);
  88}
  89EXPORT_SYMBOL(nfc_proto_unregister);
  90
  91int __init af_nfc_init(void)
  92{
  93        return sock_register(&nfc_sock_family_ops);
  94}
  95
  96void af_nfc_exit(void)
  97{
  98        sock_unregister(PF_NFC);
  99}
 100