OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [net/] [ax25/] [ax25_iface.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * This program is free software; you can redistribute it and/or modify
3
 * it under the terms of the GNU General Public License as published by
4
 * the Free Software Foundation; either version 2 of the License, or
5
 * (at your option) any later version.
6
 *
7
 * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
8
 */
9
#include <linux/errno.h>
10
#include <linux/types.h>
11
#include <linux/socket.h>
12
#include <linux/in.h>
13
#include <linux/kernel.h>
14
#include <linux/module.h>
15
#include <linux/spinlock.h>
16
#include <linux/timer.h>
17
#include <linux/string.h>
18
#include <linux/sockios.h>
19
#include <linux/net.h>
20
#include <net/ax25.h>
21
#include <linux/inet.h>
22
#include <linux/netdevice.h>
23
#include <linux/skbuff.h>
24
#include <net/sock.h>
25
#include <asm/uaccess.h>
26
#include <asm/system.h>
27
#include <linux/fcntl.h>
28
#include <linux/mm.h>
29
#include <linux/interrupt.h>
30
 
31
static struct ax25_protocol *protocol_list;
32
static DEFINE_RWLOCK(protocol_list_lock);
33
 
34
static HLIST_HEAD(ax25_linkfail_list);
35
static DEFINE_SPINLOCK(linkfail_lock);
36
 
37
static struct listen_struct {
38
        struct listen_struct *next;
39
        ax25_address  callsign;
40
        struct net_device *dev;
41
} *listen_list = NULL;
42
static DEFINE_SPINLOCK(listen_lock);
43
 
44
/*
45
 * Do not register the internal protocols AX25_P_TEXT, AX25_P_SEGMENT,
46
 * AX25_P_IP or AX25_P_ARP ...
47
 */
48
void ax25_register_pid(struct ax25_protocol *ap)
49
{
50
        write_lock_bh(&protocol_list_lock);
51
        ap->next = protocol_list;
52
        protocol_list = ap;
53
        write_unlock_bh(&protocol_list_lock);
54
}
55
 
56
EXPORT_SYMBOL_GPL(ax25_register_pid);
57
 
58
void ax25_protocol_release(unsigned int pid)
59
{
60
        struct ax25_protocol *s, *protocol;
61
 
62
        write_lock_bh(&protocol_list_lock);
63
        protocol = protocol_list;
64
        if (protocol == NULL) {
65
                write_unlock_bh(&protocol_list_lock);
66
                return;
67
        }
68
 
69
        if (protocol->pid == pid) {
70
                protocol_list = protocol->next;
71
                write_unlock_bh(&protocol_list_lock);
72
                return;
73
        }
74
 
75
        while (protocol != NULL && protocol->next != NULL) {
76
                if (protocol->next->pid == pid) {
77
                        s = protocol->next;
78
                        protocol->next = protocol->next->next;
79
                        write_unlock_bh(&protocol_list_lock);
80
                        return;
81
                }
82
 
83
                protocol = protocol->next;
84
        }
85
        write_unlock_bh(&protocol_list_lock);
86
}
87
 
88
EXPORT_SYMBOL(ax25_protocol_release);
89
 
90
void ax25_linkfail_register(struct ax25_linkfail *lf)
91
{
92
        spin_lock_bh(&linkfail_lock);
93
        hlist_add_head(&lf->lf_node, &ax25_linkfail_list);
94
        spin_unlock_bh(&linkfail_lock);
95
}
96
 
97
EXPORT_SYMBOL(ax25_linkfail_register);
98
 
99
void ax25_linkfail_release(struct ax25_linkfail *lf)
100
{
101
        spin_lock_bh(&linkfail_lock);
102
        hlist_del_init(&lf->lf_node);
103
        spin_unlock_bh(&linkfail_lock);
104
}
105
 
106
EXPORT_SYMBOL(ax25_linkfail_release);
107
 
108
int ax25_listen_register(ax25_address *callsign, struct net_device *dev)
109
{
110
        struct listen_struct *listen;
111
 
112
        if (ax25_listen_mine(callsign, dev))
113
                return 0;
114
 
115
        if ((listen = kmalloc(sizeof(*listen), GFP_ATOMIC)) == NULL)
116
                return -ENOMEM;
117
 
118
        listen->callsign = *callsign;
119
        listen->dev      = dev;
120
 
121
        spin_lock_bh(&listen_lock);
122
        listen->next = listen_list;
123
        listen_list  = listen;
124
        spin_unlock_bh(&listen_lock);
125
 
126
        return 0;
127
}
128
 
129
EXPORT_SYMBOL(ax25_listen_register);
130
 
131
void ax25_listen_release(ax25_address *callsign, struct net_device *dev)
132
{
133
        struct listen_struct *s, *listen;
134
 
135
        spin_lock_bh(&listen_lock);
136
        listen = listen_list;
137
        if (listen == NULL) {
138
                spin_unlock_bh(&listen_lock);
139
                return;
140
        }
141
 
142
        if (ax25cmp(&listen->callsign, callsign) == 0 && listen->dev == dev) {
143
                listen_list = listen->next;
144
                spin_unlock_bh(&listen_lock);
145
                kfree(listen);
146
                return;
147
        }
148
 
149
        while (listen != NULL && listen->next != NULL) {
150
                if (ax25cmp(&listen->next->callsign, callsign) == 0 && listen->next->dev == dev) {
151
                        s = listen->next;
152
                        listen->next = listen->next->next;
153
                        spin_unlock_bh(&listen_lock);
154
                        kfree(s);
155
                        return;
156
                }
157
 
158
                listen = listen->next;
159
        }
160
        spin_unlock_bh(&listen_lock);
161
}
162
 
163
EXPORT_SYMBOL(ax25_listen_release);
164
 
165
int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *)
166
{
167
        int (*res)(struct sk_buff *, ax25_cb *) = NULL;
168
        struct ax25_protocol *protocol;
169
 
170
        read_lock(&protocol_list_lock);
171
        for (protocol = protocol_list; protocol != NULL; protocol = protocol->next)
172
                if (protocol->pid == pid) {
173
                        res = protocol->func;
174
                        break;
175
                }
176
        read_unlock(&protocol_list_lock);
177
 
178
        return res;
179
}
180
 
181
int ax25_listen_mine(ax25_address *callsign, struct net_device *dev)
182
{
183
        struct listen_struct *listen;
184
 
185
        spin_lock_bh(&listen_lock);
186
        for (listen = listen_list; listen != NULL; listen = listen->next)
187
                if (ax25cmp(&listen->callsign, callsign) == 0 &&
188
                    (listen->dev == dev || listen->dev == NULL)) {
189
                        spin_unlock_bh(&listen_lock);
190
                        return 1;
191
        }
192
        spin_unlock_bh(&listen_lock);
193
 
194
        return 0;
195
}
196
 
197
void ax25_link_failed(ax25_cb *ax25, int reason)
198
{
199
        struct ax25_linkfail *lf;
200
        struct hlist_node *node;
201
 
202
        spin_lock_bh(&linkfail_lock);
203
        hlist_for_each_entry(lf, node, &ax25_linkfail_list, lf_node)
204
                lf->func(ax25, reason);
205
        spin_unlock_bh(&linkfail_lock);
206
}
207
 
208
int ax25_protocol_is_registered(unsigned int pid)
209
{
210
        struct ax25_protocol *protocol;
211
        int res = 0;
212
 
213
        read_lock_bh(&protocol_list_lock);
214
        for (protocol = protocol_list; protocol != NULL; protocol = protocol->next)
215
                if (protocol->pid == pid) {
216
                        res = 1;
217
                        break;
218
                }
219
        read_unlock_bh(&protocol_list_lock);
220
 
221
        return res;
222
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.