diff options
author | Aloisio Almeida Jr <aloisio.almeida@openbossa.org> | 2011-07-01 18:31:35 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-07-05 15:26:58 -0400 |
commit | c7fe3b52c1283b8ba810eb6ecddf1c8a0bcc13ab (patch) | |
tree | 12f657e696a5ab06259382b59394f4092749849c | |
parent | 4d12b8b129f170d0fc3188de1e51a2a1b0f87730 (diff) |
NFC: add NFC socket family
Signed-off-by: Lauro Ramos Venancio <lauro.venancio@openbossa.org>
Signed-off-by: Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | include/linux/nfc.h | 3 | ||||
-rw-r--r-- | include/linux/socket.h | 4 | ||||
-rw-r--r-- | net/core/sock.c | 6 | ||||
-rw-r--r-- | net/nfc/Makefile | 2 | ||||
-rw-r--r-- | net/nfc/af_nfc.c | 98 | ||||
-rw-r--r-- | net/nfc/core.c | 7 | ||||
-rw-r--r-- | net/nfc/nfc.h | 14 |
7 files changed, 129 insertions, 5 deletions
diff --git a/include/linux/nfc.h b/include/linux/nfc.h index 1170476d270a..15f8cb3edcc6 100644 --- a/include/linux/nfc.h +++ b/include/linux/nfc.h | |||
@@ -109,4 +109,7 @@ enum nfc_attrs { | |||
109 | #define NFC_PROTO_ISO14443_MASK (1 << NFC_PROTO_ISO14443) | 109 | #define NFC_PROTO_ISO14443_MASK (1 << NFC_PROTO_ISO14443) |
110 | #define NFC_PROTO_NFC_DEP_MASK (1 << NFC_PROTO_NFC_DEP) | 110 | #define NFC_PROTO_NFC_DEP_MASK (1 << NFC_PROTO_NFC_DEP) |
111 | 111 | ||
112 | /* NFC socket protocols */ | ||
113 | #define NFC_SOCKPROTO_MAX 0 | ||
114 | |||
112 | #endif /*__LINUX_NFC_H */ | 115 | #endif /*__LINUX_NFC_H */ |
diff --git a/include/linux/socket.h b/include/linux/socket.h index 4ef98e422fde..e17f82266639 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h | |||
@@ -192,7 +192,8 @@ struct ucred { | |||
192 | #define AF_IEEE802154 36 /* IEEE802154 sockets */ | 192 | #define AF_IEEE802154 36 /* IEEE802154 sockets */ |
193 | #define AF_CAIF 37 /* CAIF sockets */ | 193 | #define AF_CAIF 37 /* CAIF sockets */ |
194 | #define AF_ALG 38 /* Algorithm sockets */ | 194 | #define AF_ALG 38 /* Algorithm sockets */ |
195 | #define AF_MAX 39 /* For now.. */ | 195 | #define AF_NFC 39 /* NFC sockets */ |
196 | #define AF_MAX 40 /* For now.. */ | ||
196 | 197 | ||
197 | /* Protocol families, same as address families. */ | 198 | /* Protocol families, same as address families. */ |
198 | #define PF_UNSPEC AF_UNSPEC | 199 | #define PF_UNSPEC AF_UNSPEC |
@@ -234,6 +235,7 @@ struct ucred { | |||
234 | #define PF_IEEE802154 AF_IEEE802154 | 235 | #define PF_IEEE802154 AF_IEEE802154 |
235 | #define PF_CAIF AF_CAIF | 236 | #define PF_CAIF AF_CAIF |
236 | #define PF_ALG AF_ALG | 237 | #define PF_ALG AF_ALG |
238 | #define PF_NFC AF_NFC | ||
237 | #define PF_MAX AF_MAX | 239 | #define PF_MAX AF_MAX |
238 | 240 | ||
239 | /* Maximum queue length specifiable by listen. */ | 241 | /* Maximum queue length specifiable by listen. */ |
diff --git a/net/core/sock.c b/net/core/sock.c index 6e819780c232..84d6de809352 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -158,7 +158,7 @@ static const char *const af_family_key_strings[AF_MAX+1] = { | |||
158 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , | 158 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , |
159 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , | 159 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , |
160 | "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , | 160 | "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , |
161 | "sk_lock-AF_MAX" | 161 | "sk_lock-AF_NFC" , "sk_lock-AF_MAX" |
162 | }; | 162 | }; |
163 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { | 163 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { |
164 | "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , | 164 | "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , |
@@ -174,7 +174,7 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = { | |||
174 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , | 174 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , |
175 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , | 175 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , |
176 | "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , | 176 | "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , |
177 | "slock-AF_MAX" | 177 | "slock-AF_NFC" , "slock-AF_MAX" |
178 | }; | 178 | }; |
179 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { | 179 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { |
180 | "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , | 180 | "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , |
@@ -190,7 +190,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = { | |||
190 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , | 190 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , |
191 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , | 191 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , |
192 | "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , | 192 | "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , |
193 | "clock-AF_MAX" | 193 | "clock-AF_NFC" , "clock-AF_MAX" |
194 | }; | 194 | }; |
195 | 195 | ||
196 | /* | 196 | /* |
diff --git a/net/nfc/Makefile b/net/nfc/Makefile index fa6fc16246d6..e081fdb86a59 100644 --- a/net/nfc/Makefile +++ b/net/nfc/Makefile | |||
@@ -4,4 +4,4 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_NFC) += nfc.o | 5 | obj-$(CONFIG_NFC) += nfc.o |
6 | 6 | ||
7 | nfc-objs := core.o netlink.o | 7 | nfc-objs := core.o netlink.o af_nfc.o |
diff --git a/net/nfc/af_nfc.c b/net/nfc/af_nfc.c new file mode 100644 index 000000000000..e982cef8f49d --- /dev/null +++ b/net/nfc/af_nfc.c | |||
@@ -0,0 +1,98 @@ | |||
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 | |||
26 | #include "nfc.h" | ||
27 | |||
28 | static DEFINE_RWLOCK(proto_tab_lock); | ||
29 | static const struct nfc_protocol *proto_tab[NFC_SOCKPROTO_MAX]; | ||
30 | |||
31 | static int nfc_sock_create(struct net *net, struct socket *sock, int proto, | ||
32 | int kern) | ||
33 | { | ||
34 | int rc = -EPROTONOSUPPORT; | ||
35 | |||
36 | if (net != &init_net) | ||
37 | return -EAFNOSUPPORT; | ||
38 | |||
39 | if (proto < 0 || proto >= NFC_SOCKPROTO_MAX) | ||
40 | return -EINVAL; | ||
41 | |||
42 | read_lock(&proto_tab_lock); | ||
43 | if (proto_tab[proto] && try_module_get(proto_tab[proto]->owner)) { | ||
44 | rc = proto_tab[proto]->create(net, sock, proto_tab[proto]); | ||
45 | module_put(proto_tab[proto]->owner); | ||
46 | } | ||
47 | read_unlock(&proto_tab_lock); | ||
48 | |||
49 | return rc; | ||
50 | } | ||
51 | |||
52 | static struct net_proto_family nfc_sock_family_ops = { | ||
53 | .owner = THIS_MODULE, | ||
54 | .family = PF_NFC, | ||
55 | .create = nfc_sock_create, | ||
56 | }; | ||
57 | |||
58 | int nfc_proto_register(const struct nfc_protocol *nfc_proto) | ||
59 | { | ||
60 | int rc; | ||
61 | |||
62 | if (nfc_proto->id < 0 || nfc_proto->id >= NFC_SOCKPROTO_MAX) | ||
63 | return -EINVAL; | ||
64 | |||
65 | rc = proto_register(nfc_proto->proto, 0); | ||
66 | if (rc) | ||
67 | return rc; | ||
68 | |||
69 | write_lock(&proto_tab_lock); | ||
70 | if (proto_tab[nfc_proto->id]) | ||
71 | rc = -EBUSY; | ||
72 | else | ||
73 | proto_tab[nfc_proto->id] = nfc_proto; | ||
74 | write_unlock(&proto_tab_lock); | ||
75 | |||
76 | return rc; | ||
77 | } | ||
78 | EXPORT_SYMBOL(nfc_proto_register); | ||
79 | |||
80 | void nfc_proto_unregister(const struct nfc_protocol *nfc_proto) | ||
81 | { | ||
82 | write_lock(&proto_tab_lock); | ||
83 | proto_tab[nfc_proto->id] = NULL; | ||
84 | write_unlock(&proto_tab_lock); | ||
85 | |||
86 | proto_unregister(nfc_proto->proto); | ||
87 | } | ||
88 | EXPORT_SYMBOL(nfc_proto_unregister); | ||
89 | |||
90 | int __init af_nfc_init(void) | ||
91 | { | ||
92 | return sock_register(&nfc_sock_family_ops); | ||
93 | } | ||
94 | |||
95 | void af_nfc_exit(void) | ||
96 | { | ||
97 | sock_unregister(PF_NFC); | ||
98 | } | ||
diff --git a/net/nfc/core.c b/net/nfc/core.c index c70f607455c5..e804dc50f42f 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c | |||
@@ -432,8 +432,14 @@ static int __init nfc_init(void) | |||
432 | /* the first generation must not be 0 */ | 432 | /* the first generation must not be 0 */ |
433 | nfc_devlist_generation = 1; | 433 | nfc_devlist_generation = 1; |
434 | 434 | ||
435 | rc = af_nfc_init(); | ||
436 | if (rc) | ||
437 | goto err_af_nfc; | ||
438 | |||
435 | return 0; | 439 | return 0; |
436 | 440 | ||
441 | err_af_nfc: | ||
442 | nfc_genl_exit(); | ||
437 | err_genl: | 443 | err_genl: |
438 | class_unregister(&nfc_class); | 444 | class_unregister(&nfc_class); |
439 | return rc; | 445 | return rc; |
@@ -441,6 +447,7 @@ err_genl: | |||
441 | 447 | ||
442 | static void __exit nfc_exit(void) | 448 | static void __exit nfc_exit(void) |
443 | { | 449 | { |
450 | af_nfc_exit(); | ||
444 | nfc_genl_exit(); | 451 | nfc_genl_exit(); |
445 | class_unregister(&nfc_class); | 452 | class_unregister(&nfc_class); |
446 | } | 453 | } |
diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index 2b31e808e6fb..8335f4de8f4f 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define __LOCAL_NFC_H | 25 | #define __LOCAL_NFC_H |
26 | 26 | ||
27 | #include <net/nfc.h> | 27 | #include <net/nfc.h> |
28 | #include <net/sock.h> | ||
28 | 29 | ||
29 | __attribute__((format (printf, 2, 3))) | 30 | __attribute__((format (printf, 2, 3))) |
30 | int nfc_printk(const char *level, const char *fmt, ...); | 31 | int nfc_printk(const char *level, const char *fmt, ...); |
@@ -33,6 +34,19 @@ int nfc_printk(const char *level, const char *fmt, ...); | |||
33 | #define nfc_err(fmt, arg...) nfc_printk(KERN_ERR, fmt, ##arg) | 34 | #define nfc_err(fmt, arg...) nfc_printk(KERN_ERR, fmt, ##arg) |
34 | #define nfc_dbg(fmt, arg...) pr_debug(fmt "\n", ##arg) | 35 | #define nfc_dbg(fmt, arg...) pr_debug(fmt "\n", ##arg) |
35 | 36 | ||
37 | struct nfc_protocol { | ||
38 | int id; | ||
39 | struct proto *proto; | ||
40 | struct module *owner; | ||
41 | int (*create)(struct net *net, struct socket *sock, | ||
42 | const struct nfc_protocol *nfc_proto); | ||
43 | }; | ||
44 | |||
45 | int __init af_nfc_init(void); | ||
46 | void af_nfc_exit(void); | ||
47 | int nfc_proto_register(const struct nfc_protocol *nfc_proto); | ||
48 | void nfc_proto_unregister(const struct nfc_protocol *nfc_proto); | ||
49 | |||
36 | extern int nfc_devlist_generation; | 50 | extern int nfc_devlist_generation; |
37 | extern struct mutex nfc_devlist_mutex; | 51 | extern struct mutex nfc_devlist_mutex; |
38 | 52 | ||