2019-05-19 16:51:43 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2011-07-02 02:31:35 +04:00
/*
* Copyright ( C ) 2011 Instituto Nokia de Tecnologia
*
* Authors :
* Aloisio Almeida Jr < aloisio . almeida @ openbossa . org >
* Lauro Ramos Venancio < lauro . venancio @ openbossa . org >
*/
# include <linux/nfc.h>
2011-05-27 17:12:25 +04:00
# include <linux/module.h>
2011-07-02 02:31:35 +04:00
# include "nfc.h"
static DEFINE_RWLOCK ( proto_tab_lock ) ;
static const struct nfc_protocol * proto_tab [ NFC_SOCKPROTO_MAX ] ;
static int nfc_sock_create ( struct net * net , struct socket * sock , int proto ,
2012-03-05 04:03:53 +04:00
int kern )
2011-07-02 02:31:35 +04:00
{
int rc = - EPROTONOSUPPORT ;
if ( net ! = & init_net )
return - EAFNOSUPPORT ;
if ( proto < 0 | | proto > = NFC_SOCKPROTO_MAX )
return - EINVAL ;
read_lock ( & proto_tab_lock ) ;
if ( proto_tab [ proto ] & & try_module_get ( proto_tab [ proto ] - > owner ) ) {
2015-05-09 05:09:13 +03:00
rc = proto_tab [ proto ] - > create ( net , sock , proto_tab [ proto ] , kern ) ;
2011-07-02 02:31:35 +04:00
module_put ( proto_tab [ proto ] - > owner ) ;
}
read_unlock ( & proto_tab_lock ) ;
return rc ;
}
2017-05-15 05:26:47 +03:00
static const struct net_proto_family nfc_sock_family_ops = {
2011-07-02 02:31:35 +04:00
. owner = THIS_MODULE ,
. family = PF_NFC ,
. create = nfc_sock_create ,
} ;
int nfc_proto_register ( const struct nfc_protocol * nfc_proto )
{
int rc ;
if ( nfc_proto - > id < 0 | | nfc_proto - > id > = NFC_SOCKPROTO_MAX )
return - EINVAL ;
rc = proto_register ( nfc_proto - > proto , 0 ) ;
if ( rc )
return rc ;
write_lock ( & proto_tab_lock ) ;
if ( proto_tab [ nfc_proto - > id ] )
rc = - EBUSY ;
else
proto_tab [ nfc_proto - > id ] = nfc_proto ;
write_unlock ( & proto_tab_lock ) ;
2021-10-13 06:49:32 +03:00
if ( rc )
proto_unregister ( nfc_proto - > proto ) ;
2011-07-02 02:31:35 +04:00
return rc ;
}
EXPORT_SYMBOL ( nfc_proto_register ) ;
void nfc_proto_unregister ( const struct nfc_protocol * nfc_proto )
{
write_lock ( & proto_tab_lock ) ;
proto_tab [ nfc_proto - > id ] = NULL ;
write_unlock ( & proto_tab_lock ) ;
proto_unregister ( nfc_proto - > proto ) ;
}
EXPORT_SYMBOL ( nfc_proto_unregister ) ;
int __init af_nfc_init ( void )
{
return sock_register ( & nfc_sock_family_ops ) ;
}
2021-07-30 17:41:57 +03:00
void __exit af_nfc_exit ( void )
2011-07-02 02:31:35 +04:00
{
sock_unregister ( PF_NFC ) ;
}