#include <linux/mm.h>
#include <linux/interrupt.h>
-static struct protocol_struct {
- struct protocol_struct *next;
- unsigned int pid;
- int (*func)(struct sk_buff *, ax25_cb *);
-} *protocol_list = NULL;
+static struct ax25_protocol *protocol_list;
static DEFINE_RWLOCK(protocol_list_lock);
static struct linkfail_struct {
} *listen_list = NULL;
static DEFINE_SPINLOCK(listen_lock);
-int ax25_protocol_register(unsigned int pid,
- int (*func)(struct sk_buff *, ax25_cb *))
+/*
+ * Do not register the internal protocols AX25_P_TEXT, AX25_P_SEGMENT,
+ * AX25_P_IP or AX25_P_ARP ...
+ */
+void ax25_register_pid(struct ax25_protocol *ap)
{
- struct protocol_struct *protocol;
-
- if (pid == AX25_P_TEXT || pid == AX25_P_SEGMENT)
- return 0;
-#ifdef CONFIG_INET
- if (pid == AX25_P_IP || pid == AX25_P_ARP)
- return 0;
-#endif
- if ((protocol = kmalloc(sizeof(*protocol), GFP_ATOMIC)) == NULL)
- return 0;
-
- protocol->pid = pid;
- protocol->func = func;
-
- write_lock(&protocol_list_lock);
- protocol->next = protocol_list;
- protocol_list = protocol;
- write_unlock(&protocol_list_lock);
-
- return 1;
+ write_lock_bh(&protocol_list_lock);
+ ap->next = protocol_list;
+ protocol_list = ap;
+ write_unlock_bh(&protocol_list_lock);
}
-EXPORT_SYMBOL(ax25_protocol_register);
+EXPORT_SYMBOL_GPL(ax25_register_pid);
void ax25_protocol_release(unsigned int pid)
{
- struct protocol_struct *s, *protocol;
+ struct ax25_protocol *s, *protocol;
- write_lock(&protocol_list_lock);
+ write_lock_bh(&protocol_list_lock);
protocol = protocol_list;
if (protocol == NULL) {
- write_unlock(&protocol_list_lock);
+ write_unlock_bh(&protocol_list_lock);
return;
}
if (protocol->pid == pid) {
protocol_list = protocol->next;
- write_unlock(&protocol_list_lock);
+ write_unlock_bh(&protocol_list_lock);
kfree(protocol);
return;
}
if (protocol->next->pid == pid) {
s = protocol->next;
protocol->next = protocol->next->next;
- write_unlock(&protocol_list_lock);
+ write_unlock_bh(&protocol_list_lock);
kfree(s);
return;
}
protocol = protocol->next;
}
- write_unlock(&protocol_list_lock);
+ write_unlock_bh(&protocol_list_lock);
}
EXPORT_SYMBOL(ax25_protocol_release);
int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *)
{
int (*res)(struct sk_buff *, ax25_cb *) = NULL;
- struct protocol_struct *protocol;
+ struct ax25_protocol *protocol;
read_lock(&protocol_list_lock);
for (protocol = protocol_list; protocol != NULL; protocol = protocol->next)
int ax25_protocol_is_registered(unsigned int pid)
{
- struct protocol_struct *protocol;
+ struct ax25_protocol *protocol;
int res = 0;
- read_lock(&protocol_list_lock);
+ read_lock_bh(&protocol_list_lock);
for (protocol = protocol_list; protocol != NULL; protocol = protocol->next)
if (protocol->pid == pid) {
res = 1;
break;
}
- read_unlock(&protocol_list_lock);
+ read_unlock_bh(&protocol_list_lock);
return res;
}