aboutsummaryrefslogtreecommitdiffstats
path: root/net/irda
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /net/irda
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'net/irda')
-rw-r--r--net/irda/Kconfig96
-rw-r--r--net/irda/Makefile15
-rw-r--r--net/irda/af_irda.c2586
-rw-r--r--net/irda/discovery.c419
-rw-r--r--net/irda/ircomm/Kconfig12
-rw-r--r--net/irda/ircomm/Makefile8
-rw-r--r--net/irda/ircomm/ircomm_core.c587
-rw-r--r--net/irda/ircomm/ircomm_event.c251
-rw-r--r--net/irda/ircomm/ircomm_lmp.c372
-rw-r--r--net/irda/ircomm/ircomm_param.c511
-rw-r--r--net/irda/ircomm/ircomm_ttp.c369
-rw-r--r--net/irda/ircomm/ircomm_tty.c1405
-rw-r--r--net/irda/ircomm/ircomm_tty_attach.c1006
-rw-r--r--net/irda/ircomm/ircomm_tty_ioctl.c428
-rw-r--r--net/irda/irda_device.c489
-rw-r--r--net/irda/iriap.c1089
-rw-r--r--net/irda/iriap_event.c502
-rw-r--r--net/irda/irias_object.c580
-rw-r--r--net/irda/irlan/Kconfig14
-rw-r--r--net/irda/irlan/Makefile7
-rw-r--r--net/irda/irlan/irlan_client.c576
-rw-r--r--net/irda/irlan/irlan_client_event.c533
-rw-r--r--net/irda/irlan/irlan_common.c1200
-rw-r--r--net/irda/irlan/irlan_eth.c387
-rw-r--r--net/irda/irlan/irlan_event.c60
-rw-r--r--net/irda/irlan/irlan_filter.c246
-rw-r--r--net/irda/irlan/irlan_provider.c413
-rw-r--r--net/irda/irlan/irlan_provider_event.c241
-rw-r--r--net/irda/irlap.c1258
-rw-r--r--net/irda/irlap_event.c2334
-rw-r--r--net/irda/irlap_frame.c1437
-rw-r--r--net/irda/irlmp.c2041
-rw-r--r--net/irda/irlmp_event.c912
-rw-r--r--net/irda/irlmp_frame.c491
-rw-r--r--net/irda/irmod.c185
-rw-r--r--net/irda/irnet/Kconfig13
-rw-r--r--net/irda/irnet/Makefile7
-rw-r--r--net/irda/irnet/irnet.h529
-rw-r--r--net/irda/irnet/irnet_irda.c1866
-rw-r--r--net/irda/irnet/irnet_irda.h186
-rw-r--r--net/irda/irnet/irnet_ppp.c1142
-rw-r--r--net/irda/irnet/irnet_ppp.h119
-rw-r--r--net/irda/irproc.c100
-rw-r--r--net/irda/irqueue.c915
-rw-r--r--net/irda/irsysctl.c297
-rw-r--r--net/irda/irttp.c1912
-rw-r--r--net/irda/parameters.c589
-rw-r--r--net/irda/qos.c774
-rw-r--r--net/irda/timer.c233
-rw-r--r--net/irda/wrapper.c491
50 files changed, 32233 insertions, 0 deletions
diff --git a/net/irda/Kconfig b/net/irda/Kconfig
new file mode 100644
index 00000000000..9efb17ba48a
--- /dev/null
+++ b/net/irda/Kconfig
@@ -0,0 +1,96 @@
1#
2# IrDA protocol configuration
3#
4
5menuconfig IRDA
6 depends on NET
7 tristate "IrDA (infrared) subsystem support"
8 select CRC_CCITT
9 ---help---
10 Say Y here if you want to build support for the IrDA (TM) protocols.
11 The Infrared Data Associations (tm) specifies standards for wireless
12 infrared communication and is supported by most laptops and PDA's.
13
14 To use Linux support for the IrDA (tm) protocols, you will also need
15 some user-space utilities like irattach. For more information, see
16 the file <file:Documentation/networking/irda.txt>. You also want to
17 read the IR-HOWTO, available at
18 <http://www.tldp.org/docs.html#howto>.
19
20 If you want to exchange bits of data (vCal, vCard) with a PDA, you
21 will need to install some OBEX application, such as OpenObex :
22 <http://sourceforge.net/projects/openobex/>
23
24 To compile this support as a module, choose M here: the module will
25 be called irda.
26
27comment "IrDA protocols"
28 depends on IRDA
29
30source "net/irda/irlan/Kconfig"
31
32source "net/irda/irnet/Kconfig"
33
34source "net/irda/ircomm/Kconfig"
35
36config IRDA_ULTRA
37 bool "Ultra (connectionless) protocol"
38 depends on IRDA
39 help
40 Say Y here to support the connectionless Ultra IRDA protocol.
41 Ultra allows to exchange data over IrDA with really simple devices
42 (watch, beacon) without the overhead of the IrDA protocol (no handshaking,
43 no management frames, simple fixed header).
44 Ultra is available as a special socket : socket(AF_IRDA, SOCK_DGRAM, 1);
45
46comment "IrDA options"
47 depends on IRDA
48
49config IRDA_CACHE_LAST_LSAP
50 bool "Cache last LSAP"
51 depends on IRDA
52 help
53 Say Y here if you want IrLMP to cache the last LSAP used. This
54 makes sense since most frames will be sent/received on the same
55 connection. Enabling this option will save a hash-lookup per frame.
56
57 If unsure, say Y.
58
59config IRDA_FAST_RR
60 bool "Fast RRs (low latency)"
61 depends on IRDA
62 ---help---
63 Say Y here is you want IrLAP to send fast RR (Receive Ready) frames
64 when acting as a primary station.
65 Disabling this option will make latency over IrDA very bad. Enabling
66 this option will make the IrDA stack send more packet than strictly
67 necessary, thus reduce your battery life (but not that much).
68
69 Fast RR will make IrLAP send out a RR frame immediately when
70 receiving a frame if its own transmit queue is currently empty. This
71 will give a lot of speed improvement when receiving much data since
72 the secondary station will not have to wait the max. turn around
73 time (usually 500ms) before it is allowed to transmit the next time.
74 If the transmit queue of the secondary is also empty, the primary will
75 start backing-off before sending another RR frame, waiting longer
76 each time until the back-off reaches the max. turn around time.
77 This back-off increase in controlled via
78 /proc/sys/net/irda/fast_poll_increase
79
80 If unsure, say Y.
81
82config IRDA_DEBUG
83 bool "Debug information"
84 depends on IRDA
85 help
86 Say Y here if you want the IrDA subsystem to write debug information
87 to your syslog. You can change the debug level in
88 /proc/sys/net/irda/debug .
89 When this option is enabled, the IrDA also perform many extra internal
90 verifications which will usually prevent the kernel to crash in case of
91 bugs.
92
93 If unsure, say Y (since it makes it easier to find the bugs).
94
95source "drivers/net/irda/Kconfig"
96
diff --git a/net/irda/Makefile b/net/irda/Makefile
new file mode 100644
index 00000000000..d1366c2a39c
--- /dev/null
+++ b/net/irda/Makefile
@@ -0,0 +1,15 @@
1#
2# Makefile for the Linux IrDA protocol layer.
3#
4
5obj-$(CONFIG_IRDA) += irda.o
6obj-$(CONFIG_IRLAN) += irlan/
7obj-$(CONFIG_IRNET) += irnet/
8obj-$(CONFIG_IRCOMM) += ircomm/
9
10irda-y := iriap.o iriap_event.o irlmp.o irlmp_event.o irlmp_frame.o \
11 irlap.o irlap_event.o irlap_frame.o timer.o qos.o irqueue.o \
12 irttp.o irda_device.o irias_object.o wrapper.o af_irda.o \
13 discovery.o parameters.o irmod.o
14irda-$(CONFIG_PROC_FS) += irproc.o
15irda-$(CONFIG_SYSCTL) += irsysctl.o
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
new file mode 100644
index 00000000000..92c6e8d4e73
--- /dev/null
+++ b/net/irda/af_irda.c
@@ -0,0 +1,2586 @@
1/*********************************************************************
2 *
3 * Filename: af_irda.c
4 * Version: 0.9
5 * Description: IrDA sockets implementation
6 * Status: Stable
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun May 31 10:12:43 1998
9 * Modified at: Sat Dec 25 21:10:23 1999
10 * Modified by: Dag Brattli <dag@brattli.net>
11 * Sources: af_netroom.c, af_ax25.c, af_rose.c, af_x25.c etc.
12 *
13 * Copyright (c) 1999 Dag Brattli <dagb@cs.uit.no>
14 * Copyright (c) 1999-2003 Jean Tourrilhes <jt@hpl.hp.com>
15 * All Rights Reserved.
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License as
19 * published by the Free Software Foundation; either version 2 of
20 * the License, or (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
30 * MA 02111-1307 USA
31 *
32 * Linux-IrDA now supports four different types of IrDA sockets:
33 *
34 * o SOCK_STREAM: TinyTP connections with SAR disabled. The
35 * max SDU size is 0 for conn. of this type
36 * o SOCK_SEQPACKET: TinyTP connections with SAR enabled. TTP may
37 * fragment the messages, but will preserve
38 * the message boundaries
39 * o SOCK_DGRAM: IRDAPROTO_UNITDATA: TinyTP connections with Unitdata
40 * (unreliable) transfers
41 * IRDAPROTO_ULTRA: Connectionless and unreliable data
42 *
43 ********************************************************************/
44
45#include <linux/config.h>
46#include <linux/module.h>
47#include <linux/types.h>
48#include <linux/socket.h>
49#include <linux/sockios.h>
50#include <linux/init.h>
51#include <linux/net.h>
52#include <linux/irda.h>
53#include <linux/poll.h>
54
55#include <asm/ioctls.h> /* TIOCOUTQ, TIOCINQ */
56#include <asm/uaccess.h>
57
58#include <net/sock.h>
59#include <net/tcp.h>
60
61#include <net/irda/af_irda.h>
62
63static int irda_create(struct socket *sock, int protocol);
64
65static struct proto_ops irda_stream_ops;
66static struct proto_ops irda_seqpacket_ops;
67static struct proto_ops irda_dgram_ops;
68
69#ifdef CONFIG_IRDA_ULTRA
70static struct proto_ops irda_ultra_ops;
71#define ULTRA_MAX_DATA 382
72#endif /* CONFIG_IRDA_ULTRA */
73
74#define IRDA_MAX_HEADER (TTP_MAX_HEADER)
75
76/*
77 * Function irda_data_indication (instance, sap, skb)
78 *
79 * Received some data from TinyTP. Just queue it on the receive queue
80 *
81 */
82static int irda_data_indication(void *instance, void *sap, struct sk_buff *skb)
83{
84 struct irda_sock *self;
85 struct sock *sk;
86 int err;
87
88 IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
89
90 self = instance;
91 sk = instance;
92 IRDA_ASSERT(sk != NULL, return -1;);
93
94 err = sock_queue_rcv_skb(sk, skb);
95 if (err) {
96 IRDA_DEBUG(1, "%s(), error: no more mem!\n", __FUNCTION__);
97 self->rx_flow = FLOW_STOP;
98
99 /* When we return error, TTP will need to requeue the skb */
100 return err;
101 }
102
103 return 0;
104}
105
106/*
107 * Function irda_disconnect_indication (instance, sap, reason, skb)
108 *
109 * Connection has been closed. Check reason to find out why
110 *
111 */
112static void irda_disconnect_indication(void *instance, void *sap,
113 LM_REASON reason, struct sk_buff *skb)
114{
115 struct irda_sock *self;
116 struct sock *sk;
117
118 self = instance;
119
120 IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
121
122 /* Don't care about it, but let's not leak it */
123 if(skb)
124 dev_kfree_skb(skb);
125
126 sk = instance;
127 if (sk == NULL) {
128 IRDA_DEBUG(0, "%s(%p) : BUG : sk is NULL\n",
129 __FUNCTION__, self);
130 return;
131 }
132
133 /* Prevent race conditions with irda_release() and irda_shutdown() */
134 if (!sock_flag(sk, SOCK_DEAD) && sk->sk_state != TCP_CLOSE) {
135 sk->sk_state = TCP_CLOSE;
136 sk->sk_err = ECONNRESET;
137 sk->sk_shutdown |= SEND_SHUTDOWN;
138
139 sk->sk_state_change(sk);
140 /* Uh-oh... Should use sock_orphan ? */
141 sock_set_flag(sk, SOCK_DEAD);
142
143 /* Close our TSAP.
144 * If we leave it open, IrLMP put it back into the list of
145 * unconnected LSAPs. The problem is that any incoming request
146 * can then be matched to this socket (and it will be, because
147 * it is at the head of the list). This would prevent any
148 * listening socket waiting on the same TSAP to get those
149 * requests. Some apps forget to close sockets, or hang to it
150 * a bit too long, so we may stay in this dead state long
151 * enough to be noticed...
152 * Note : all socket function do check sk->sk_state, so we are
153 * safe...
154 * Jean II
155 */
156 if (self->tsap) {
157 irttp_close_tsap(self->tsap);
158 self->tsap = NULL;
159 }
160 }
161
162 /* Note : once we are there, there is not much you want to do
163 * with the socket anymore, apart from closing it.
164 * For example, bind() and connect() won't reset sk->sk_err,
165 * sk->sk_shutdown and sk->sk_flags to valid values...
166 * Jean II
167 */
168}
169
170/*
171 * Function irda_connect_confirm (instance, sap, qos, max_sdu_size, skb)
172 *
173 * Connections has been confirmed by the remote device
174 *
175 */
176static void irda_connect_confirm(void *instance, void *sap,
177 struct qos_info *qos,
178 __u32 max_sdu_size, __u8 max_header_size,
179 struct sk_buff *skb)
180{
181 struct irda_sock *self;
182 struct sock *sk;
183
184 self = instance;
185
186 IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
187
188 sk = instance;
189 if (sk == NULL) {
190 dev_kfree_skb(skb);
191 return;
192 }
193
194 dev_kfree_skb(skb);
195 // Should be ??? skb_queue_tail(&sk->sk_receive_queue, skb);
196
197 /* How much header space do we need to reserve */
198 self->max_header_size = max_header_size;
199
200 /* IrTTP max SDU size in transmit direction */
201 self->max_sdu_size_tx = max_sdu_size;
202
203 /* Find out what the largest chunk of data that we can transmit is */
204 switch (sk->sk_type) {
205 case SOCK_STREAM:
206 if (max_sdu_size != 0) {
207 IRDA_ERROR("%s: max_sdu_size must be 0\n",
208 __FUNCTION__);
209 return;
210 }
211 self->max_data_size = irttp_get_max_seg_size(self->tsap);
212 break;
213 case SOCK_SEQPACKET:
214 if (max_sdu_size == 0) {
215 IRDA_ERROR("%s: max_sdu_size cannot be 0\n",
216 __FUNCTION__);
217 return;
218 }
219 self->max_data_size = max_sdu_size;
220 break;
221 default:
222 self->max_data_size = irttp_get_max_seg_size(self->tsap);
223 };
224
225 IRDA_DEBUG(2, "%s(), max_data_size=%d\n", __FUNCTION__,
226 self->max_data_size);
227
228 memcpy(&self->qos_tx, qos, sizeof(struct qos_info));
229
230 /* We are now connected! */
231 sk->sk_state = TCP_ESTABLISHED;
232 sk->sk_state_change(sk);
233}
234
235/*
236 * Function irda_connect_indication(instance, sap, qos, max_sdu_size, userdata)
237 *
238 * Incoming connection
239 *
240 */
241static void irda_connect_indication(void *instance, void *sap,
242 struct qos_info *qos, __u32 max_sdu_size,
243 __u8 max_header_size, struct sk_buff *skb)
244{
245 struct irda_sock *self;
246 struct sock *sk;
247
248 self = instance;
249
250 IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
251
252 sk = instance;
253 if (sk == NULL) {
254 dev_kfree_skb(skb);
255 return;
256 }
257
258 /* How much header space do we need to reserve */
259 self->max_header_size = max_header_size;
260
261 /* IrTTP max SDU size in transmit direction */
262 self->max_sdu_size_tx = max_sdu_size;
263
264 /* Find out what the largest chunk of data that we can transmit is */
265 switch (sk->sk_type) {
266 case SOCK_STREAM:
267 if (max_sdu_size != 0) {
268 IRDA_ERROR("%s: max_sdu_size must be 0\n",
269 __FUNCTION__);
270 kfree_skb(skb);
271 return;
272 }
273 self->max_data_size = irttp_get_max_seg_size(self->tsap);
274 break;
275 case SOCK_SEQPACKET:
276 if (max_sdu_size == 0) {
277 IRDA_ERROR("%s: max_sdu_size cannot be 0\n",
278 __FUNCTION__);
279 kfree_skb(skb);
280 return;
281 }
282 self->max_data_size = max_sdu_size;
283 break;
284 default:
285 self->max_data_size = irttp_get_max_seg_size(self->tsap);
286 };
287
288 IRDA_DEBUG(2, "%s(), max_data_size=%d\n", __FUNCTION__,
289 self->max_data_size);
290
291 memcpy(&self->qos_tx, qos, sizeof(struct qos_info));
292
293 skb_queue_tail(&sk->sk_receive_queue, skb);
294 sk->sk_state_change(sk);
295}
296
297/*
298 * Function irda_connect_response (handle)
299 *
300 * Accept incoming connection
301 *
302 */
303static void irda_connect_response(struct irda_sock *self)
304{
305 struct sk_buff *skb;
306
307 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
308
309 IRDA_ASSERT(self != NULL, return;);
310
311 skb = dev_alloc_skb(64);
312 if (skb == NULL) {
313 IRDA_DEBUG(0, "%s() Unable to allocate sk_buff!\n",
314 __FUNCTION__);
315 return;
316 }
317
318 /* Reserve space for MUX_CONTROL and LAP header */
319 skb_reserve(skb, IRDA_MAX_HEADER);
320
321 irttp_connect_response(self->tsap, self->max_sdu_size_rx, skb);
322}
323
324/*
325 * Function irda_flow_indication (instance, sap, flow)
326 *
327 * Used by TinyTP to tell us if it can accept more data or not
328 *
329 */
330static void irda_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
331{
332 struct irda_sock *self;
333 struct sock *sk;
334
335 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
336
337 self = instance;
338 sk = instance;
339 IRDA_ASSERT(sk != NULL, return;);
340
341 switch (flow) {
342 case FLOW_STOP:
343 IRDA_DEBUG(1, "%s(), IrTTP wants us to slow down\n",
344 __FUNCTION__);
345 self->tx_flow = flow;
346 break;
347 case FLOW_START:
348 self->tx_flow = flow;
349 IRDA_DEBUG(1, "%s(), IrTTP wants us to start again\n",
350 __FUNCTION__);
351 wake_up_interruptible(sk->sk_sleep);
352 break;
353 default:
354 IRDA_DEBUG(0, "%s(), Unknown flow command!\n", __FUNCTION__);
355 /* Unknown flow command, better stop */
356 self->tx_flow = flow;
357 break;
358 }
359}
360
361/*
362 * Function irda_getvalue_confirm (obj_id, value, priv)
363 *
364 * Got answer from remote LM-IAS, just pass object to requester...
365 *
366 * Note : duplicate from above, but we need our own version that
367 * doesn't touch the dtsap_sel and save the full value structure...
368 */
369static void irda_getvalue_confirm(int result, __u16 obj_id,
370 struct ias_value *value, void *priv)
371{
372 struct irda_sock *self;
373
374 self = (struct irda_sock *) priv;
375 if (!self) {
376 IRDA_WARNING("%s: lost myself!\n", __FUNCTION__);
377 return;
378 }
379
380 IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
381
382 /* We probably don't need to make any more queries */
383 iriap_close(self->iriap);
384 self->iriap = NULL;
385
386 /* Check if request succeeded */
387 if (result != IAS_SUCCESS) {
388 IRDA_DEBUG(1, "%s(), IAS query failed! (%d)\n", __FUNCTION__,
389 result);
390
391 self->errno = result; /* We really need it later */
392
393 /* Wake up any processes waiting for result */
394 wake_up_interruptible(&self->query_wait);
395
396 return;
397 }
398
399 /* Pass the object to the caller (so the caller must delete it) */
400 self->ias_result = value;
401 self->errno = 0;
402
403 /* Wake up any processes waiting for result */
404 wake_up_interruptible(&self->query_wait);
405}
406
407/*
408 * Function irda_selective_discovery_indication (discovery)
409 *
410 * Got a selective discovery indication from IrLMP.
411 *
412 * IrLMP is telling us that this node is new and matching our hint bit
413 * filter. Wake up any process waiting for answer...
414 */
415static void irda_selective_discovery_indication(discinfo_t *discovery,
416 DISCOVERY_MODE mode,
417 void *priv)
418{
419 struct irda_sock *self;
420
421 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
422
423 self = (struct irda_sock *) priv;
424 if (!self) {
425 IRDA_WARNING("%s: lost myself!\n", __FUNCTION__);
426 return;
427 }
428
429 /* Pass parameter to the caller */
430 self->cachedaddr = discovery->daddr;
431
432 /* Wake up process if its waiting for device to be discovered */
433 wake_up_interruptible(&self->query_wait);
434}
435
436/*
437 * Function irda_discovery_timeout (priv)
438 *
439 * Timeout in the selective discovery process
440 *
441 * We were waiting for a node to be discovered, but nothing has come up
442 * so far. Wake up the user and tell him that we failed...
443 */
444static void irda_discovery_timeout(u_long priv)
445{
446 struct irda_sock *self;
447
448 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
449
450 self = (struct irda_sock *) priv;
451 IRDA_ASSERT(self != NULL, return;);
452
453 /* Nothing for the caller */
454 self->cachelog = NULL;
455 self->cachedaddr = 0;
456 self->errno = -ETIME;
457
458 /* Wake up process if its still waiting... */
459 wake_up_interruptible(&self->query_wait);
460}
461
462/*
463 * Function irda_open_tsap (self)
464 *
465 * Open local Transport Service Access Point (TSAP)
466 *
467 */
468static int irda_open_tsap(struct irda_sock *self, __u8 tsap_sel, char *name)
469{
470 notify_t notify;
471
472 if (self->tsap) {
473 IRDA_WARNING("%s: busy!\n", __FUNCTION__);
474 return -EBUSY;
475 }
476
477 /* Initialize callbacks to be used by the IrDA stack */
478 irda_notify_init(&notify);
479 notify.connect_confirm = irda_connect_confirm;
480 notify.connect_indication = irda_connect_indication;
481 notify.disconnect_indication = irda_disconnect_indication;
482 notify.data_indication = irda_data_indication;
483 notify.udata_indication = irda_data_indication;
484 notify.flow_indication = irda_flow_indication;
485 notify.instance = self;
486 strncpy(notify.name, name, NOTIFY_MAX_NAME);
487
488 self->tsap = irttp_open_tsap(tsap_sel, DEFAULT_INITIAL_CREDIT,
489 &notify);
490 if (self->tsap == NULL) {
491 IRDA_DEBUG(0, "%s(), Unable to allocate TSAP!\n",
492 __FUNCTION__);
493 return -ENOMEM;
494 }
495 /* Remember which TSAP selector we actually got */
496 self->stsap_sel = self->tsap->stsap_sel;
497
498 return 0;
499}
500
501/*
502 * Function irda_open_lsap (self)
503 *
504 * Open local Link Service Access Point (LSAP). Used for opening Ultra
505 * sockets
506 */
507#ifdef CONFIG_IRDA_ULTRA
508static int irda_open_lsap(struct irda_sock *self, int pid)
509{
510 notify_t notify;
511
512 if (self->lsap) {
513 IRDA_WARNING("%s(), busy!\n", __FUNCTION__);
514 return -EBUSY;
515 }
516
517 /* Initialize callbacks to be used by the IrDA stack */
518 irda_notify_init(&notify);
519 notify.udata_indication = irda_data_indication;
520 notify.instance = self;
521 strncpy(notify.name, "Ultra", NOTIFY_MAX_NAME);
522
523 self->lsap = irlmp_open_lsap(LSAP_CONNLESS, &notify, pid);
524 if (self->lsap == NULL) {
525 IRDA_DEBUG( 0, "%s(), Unable to allocate LSAP!\n", __FUNCTION__);
526 return -ENOMEM;
527 }
528
529 return 0;
530}
531#endif /* CONFIG_IRDA_ULTRA */
532
533/*
534 * Function irda_find_lsap_sel (self, name)
535 *
536 * Try to lookup LSAP selector in remote LM-IAS
537 *
538 * Basically, we start a IAP query, and then go to sleep. When the query
539 * return, irda_getvalue_confirm will wake us up, and we can examine the
540 * result of the query...
541 * Note that in some case, the query fail even before we go to sleep,
542 * creating some races...
543 */
544static int irda_find_lsap_sel(struct irda_sock *self, char *name)
545{
546 IRDA_DEBUG(2, "%s(%p, %s)\n", __FUNCTION__, self, name);
547
548 IRDA_ASSERT(self != NULL, return -1;);
549
550 if (self->iriap) {
551 IRDA_WARNING("%s(): busy with a previous query\n",
552 __FUNCTION__);
553 return -EBUSY;
554 }
555
556 self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
557 irda_getvalue_confirm);
558 if(self->iriap == NULL)
559 return -ENOMEM;
560
561 /* Treat unexpected wakeup as disconnect */
562 self->errno = -EHOSTUNREACH;
563
564 /* Query remote LM-IAS */
565 iriap_getvaluebyclass_request(self->iriap, self->saddr, self->daddr,
566 name, "IrDA:TinyTP:LsapSel");
567
568 /* Wait for answer, if not yet finished (or failed) */
569 if (wait_event_interruptible(self->query_wait, (self->iriap==NULL)))
570 /* Treat signals as disconnect */
571 return -EHOSTUNREACH;
572
573 /* Check what happened */
574 if (self->errno)
575 {
576 /* Requested object/attribute doesn't exist */
577 if((self->errno == IAS_CLASS_UNKNOWN) ||
578 (self->errno == IAS_ATTRIB_UNKNOWN))
579 return (-EADDRNOTAVAIL);
580 else
581 return (-EHOSTUNREACH);
582 }
583
584 /* Get the remote TSAP selector */
585 switch (self->ias_result->type) {
586 case IAS_INTEGER:
587 IRDA_DEBUG(4, "%s() int=%d\n",
588 __FUNCTION__, self->ias_result->t.integer);
589
590 if (self->ias_result->t.integer != -1)
591 self->dtsap_sel = self->ias_result->t.integer;
592 else
593 self->dtsap_sel = 0;
594 break;
595 default:
596 self->dtsap_sel = 0;
597 IRDA_DEBUG(0, "%s(), bad type!\n", __FUNCTION__);
598 break;
599 }
600 if (self->ias_result)
601 irias_delete_value(self->ias_result);
602
603 if (self->dtsap_sel)
604 return 0;
605
606 return -EADDRNOTAVAIL;
607}
608
609/*
610 * Function irda_discover_daddr_and_lsap_sel (self, name)
611 *
612 * This try to find a device with the requested service.
613 *
614 * It basically look into the discovery log. For each address in the list,
615 * it queries the LM-IAS of the device to find if this device offer
616 * the requested service.
617 * If there is more than one node supporting the service, we complain
618 * to the user (it should move devices around).
619 * The, we set both the destination address and the lsap selector to point
620 * on the service on the unique device we have found.
621 *
622 * Note : this function fails if there is more than one device in range,
623 * because IrLMP doesn't disconnect the LAP when the last LSAP is closed.
624 * Moreover, we would need to wait the LAP disconnection...
625 */
626static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name)
627{
628 discinfo_t *discoveries; /* Copy of the discovery log */
629 int number; /* Number of nodes in the log */
630 int i;
631 int err = -ENETUNREACH;
632 __u32 daddr = DEV_ADDR_ANY; /* Address we found the service on */
633 __u8 dtsap_sel = 0x0; /* TSAP associated with it */
634
635 IRDA_DEBUG(2, "%s(), name=%s\n", __FUNCTION__, name);
636
637 IRDA_ASSERT(self != NULL, return -1;);
638
639 /* Ask lmp for the current discovery log
640 * Note : we have to use irlmp_get_discoveries(), as opposed
641 * to play with the cachelog directly, because while we are
642 * making our ias query, le log might change... */
643 discoveries = irlmp_get_discoveries(&number, self->mask.word,
644 self->nslots);
645 /* Check if the we got some results */
646 if (discoveries == NULL)
647 return -ENETUNREACH; /* No nodes discovered */
648
649 /*
650 * Now, check all discovered devices (if any), and connect
651 * client only about the services that the client is
652 * interested in...
653 */
654 for(i = 0; i < number; i++) {
655 /* Try the address in the log */
656 self->daddr = discoveries[i].daddr;
657 self->saddr = 0x0;
658 IRDA_DEBUG(1, "%s(), trying daddr = %08x\n",
659 __FUNCTION__, self->daddr);
660
661 /* Query remote LM-IAS for this service */
662 err = irda_find_lsap_sel(self, name);
663 switch (err) {
664 case 0:
665 /* We found the requested service */
666 if(daddr != DEV_ADDR_ANY) {
667 IRDA_DEBUG(1, "%s(), discovered service ''%s'' in two different devices !!!\n",
668 __FUNCTION__, name);
669 self->daddr = DEV_ADDR_ANY;
670 kfree(discoveries);
671 return(-ENOTUNIQ);
672 }
673 /* First time we found that one, save it ! */
674 daddr = self->daddr;
675 dtsap_sel = self->dtsap_sel;
676 break;
677 case -EADDRNOTAVAIL:
678 /* Requested service simply doesn't exist on this node */
679 break;
680 default:
681 /* Something bad did happen :-( */
682 IRDA_DEBUG(0, "%s(), unexpected IAS query failure\n", __FUNCTION__);
683 self->daddr = DEV_ADDR_ANY;
684 kfree(discoveries);
685 return(-EHOSTUNREACH);
686 break;
687 }
688 }
689 /* Cleanup our copy of the discovery log */
690 kfree(discoveries);
691
692 /* Check out what we found */
693 if(daddr == DEV_ADDR_ANY) {
694 IRDA_DEBUG(1, "%s(), cannot discover service ''%s'' in any device !!!\n",
695 __FUNCTION__, name);
696 self->daddr = DEV_ADDR_ANY;
697 return(-EADDRNOTAVAIL);
698 }
699
700 /* Revert back to discovered device & service */
701 self->daddr = daddr;
702 self->saddr = 0x0;
703 self->dtsap_sel = dtsap_sel;
704
705 IRDA_DEBUG(1, "%s(), discovered requested service ''%s'' at address %08x\n",
706 __FUNCTION__, name, self->daddr);
707
708 return 0;
709}
710
711/*
712 * Function irda_getname (sock, uaddr, uaddr_len, peer)
713 *
714 * Return the our own, or peers socket address (sockaddr_irda)
715 *
716 */
717static int irda_getname(struct socket *sock, struct sockaddr *uaddr,
718 int *uaddr_len, int peer)
719{
720 struct sockaddr_irda saddr;
721 struct sock *sk = sock->sk;
722 struct irda_sock *self = irda_sk(sk);
723
724 if (peer) {
725 if (sk->sk_state != TCP_ESTABLISHED)
726 return -ENOTCONN;
727
728 saddr.sir_family = AF_IRDA;
729 saddr.sir_lsap_sel = self->dtsap_sel;
730 saddr.sir_addr = self->daddr;
731 } else {
732 saddr.sir_family = AF_IRDA;
733 saddr.sir_lsap_sel = self->stsap_sel;
734 saddr.sir_addr = self->saddr;
735 }
736
737 IRDA_DEBUG(1, "%s(), tsap_sel = %#x\n", __FUNCTION__, saddr.sir_lsap_sel);
738 IRDA_DEBUG(1, "%s(), addr = %08x\n", __FUNCTION__, saddr.sir_addr);
739
740 /* uaddr_len come to us uninitialised */
741 *uaddr_len = sizeof (struct sockaddr_irda);
742 memcpy(uaddr, &saddr, *uaddr_len);
743
744 return 0;
745}
746
747/*
748 * Function irda_listen (sock, backlog)
749 *
750 * Just move to the listen state
751 *
752 */
753static int irda_listen(struct socket *sock, int backlog)
754{
755 struct sock *sk = sock->sk;
756
757 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
758
759 if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) &&
760 (sk->sk_type != SOCK_DGRAM))
761 return -EOPNOTSUPP;
762
763 if (sk->sk_state != TCP_LISTEN) {
764 sk->sk_max_ack_backlog = backlog;
765 sk->sk_state = TCP_LISTEN;
766
767 return 0;
768 }
769
770 return -EOPNOTSUPP;
771}
772
773/*
774 * Function irda_bind (sock, uaddr, addr_len)
775 *
776 * Used by servers to register their well known TSAP
777 *
778 */
779static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
780{
781 struct sock *sk = sock->sk;
782 struct sockaddr_irda *addr = (struct sockaddr_irda *) uaddr;
783 struct irda_sock *self = irda_sk(sk);
784 int err;
785
786 IRDA_ASSERT(self != NULL, return -1;);
787
788 IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
789
790 if (addr_len != sizeof(struct sockaddr_irda))
791 return -EINVAL;
792
793#ifdef CONFIG_IRDA_ULTRA
794 /* Special care for Ultra sockets */
795 if ((sk->sk_type == SOCK_DGRAM) &&
796 (sk->sk_protocol == IRDAPROTO_ULTRA)) {
797 self->pid = addr->sir_lsap_sel;
798 if (self->pid & 0x80) {
799 IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __FUNCTION__);
800 return -EOPNOTSUPP;
801 }
802 err = irda_open_lsap(self, self->pid);
803 if (err < 0)
804 return err;
805
806 /* Pretend we are connected */
807 sock->state = SS_CONNECTED;
808 sk->sk_state = TCP_ESTABLISHED;
809
810 return 0;
811 }
812#endif /* CONFIG_IRDA_ULTRA */
813
814 err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name);
815 if (err < 0)
816 return err;
817
818 /* Register with LM-IAS */
819 self->ias_obj = irias_new_object(addr->sir_name, jiffies);
820 irias_add_integer_attrib(self->ias_obj, "IrDA:TinyTP:LsapSel",
821 self->stsap_sel, IAS_KERNEL_ATTR);
822 irias_insert_object(self->ias_obj);
823
824 return 0;
825}
826
827/*
828 * Function irda_accept (sock, newsock, flags)
829 *
830 * Wait for incoming connection
831 *
832 */
833static int irda_accept(struct socket *sock, struct socket *newsock, int flags)
834{
835 struct sock *sk = sock->sk;
836 struct irda_sock *new, *self = irda_sk(sk);
837 struct sock *newsk;
838 struct sk_buff *skb;
839 int err;
840
841 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
842
843 IRDA_ASSERT(self != NULL, return -1;);
844
845 err = irda_create(newsock, sk->sk_protocol);
846 if (err)
847 return err;
848
849 if (sock->state != SS_UNCONNECTED)
850 return -EINVAL;
851
852 if ((sk = sock->sk) == NULL)
853 return -EINVAL;
854
855 if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) &&
856 (sk->sk_type != SOCK_DGRAM))
857 return -EOPNOTSUPP;
858
859 if (sk->sk_state != TCP_LISTEN)
860 return -EINVAL;
861
862 /*
863 * The read queue this time is holding sockets ready to use
864 * hooked into the SABM we saved
865 */
866
867 /*
868 * We can perform the accept only if there is incoming data
869 * on the listening socket.
870 * So, we will block the caller until we receive any data.
871 * If the caller was waiting on select() or poll() before
872 * calling us, the data is waiting for us ;-)
873 * Jean II
874 */
875 skb = skb_dequeue(&sk->sk_receive_queue);
876 if (skb == NULL) {
877 int ret = 0;
878 DECLARE_WAITQUEUE(waitq, current);
879
880 /* Non blocking operation */
881 if (flags & O_NONBLOCK)
882 return -EWOULDBLOCK;
883
884 /* The following code is a cut'n'paste of the
885 * wait_event_interruptible() macro.
886 * We don't us the macro because the condition has
887 * side effects : we want to make sure that only one
888 * skb get dequeued - Jean II */
889 add_wait_queue(sk->sk_sleep, &waitq);
890 for (;;) {
891 set_current_state(TASK_INTERRUPTIBLE);
892 skb = skb_dequeue(&sk->sk_receive_queue);
893 if (skb != NULL)
894 break;
895 if (!signal_pending(current)) {
896 schedule();
897 continue;
898 }
899 ret = -ERESTARTSYS;
900 break;
901 }
902 current->state = TASK_RUNNING;
903 remove_wait_queue(sk->sk_sleep, &waitq);
904 if(ret)
905 return -ERESTARTSYS;
906 }
907
908 newsk = newsock->sk;
909 newsk->sk_state = TCP_ESTABLISHED;
910
911 new = irda_sk(newsk);
912 IRDA_ASSERT(new != NULL, return -1;);
913
914 /* Now attach up the new socket */
915 new->tsap = irttp_dup(self->tsap, new);
916 if (!new->tsap) {
917 IRDA_DEBUG(0, "%s(), dup failed!\n", __FUNCTION__);
918 kfree_skb(skb);
919 return -1;
920 }
921
922 new->stsap_sel = new->tsap->stsap_sel;
923 new->dtsap_sel = new->tsap->dtsap_sel;
924 new->saddr = irttp_get_saddr(new->tsap);
925 new->daddr = irttp_get_daddr(new->tsap);
926
927 new->max_sdu_size_tx = self->max_sdu_size_tx;
928 new->max_sdu_size_rx = self->max_sdu_size_rx;
929 new->max_data_size = self->max_data_size;
930 new->max_header_size = self->max_header_size;
931
932 memcpy(&new->qos_tx, &self->qos_tx, sizeof(struct qos_info));
933
934 /* Clean up the original one to keep it in listen state */
935 irttp_listen(self->tsap);
936
937 /* Wow ! What is that ? Jean II */
938 skb->sk = NULL;
939 skb->destructor = NULL;
940 kfree_skb(skb);
941 sk->sk_ack_backlog--;
942
943 newsock->state = SS_CONNECTED;
944
945 irda_connect_response(new);
946
947 return 0;
948}
949
950/*
951 * Function irda_connect (sock, uaddr, addr_len, flags)
952 *
953 * Connect to a IrDA device
954 *
955 * The main difference with a "standard" connect is that with IrDA we need
956 * to resolve the service name into a TSAP selector (in TCP, port number
957 * doesn't have to be resolved).
958 * Because of this service name resoltion, we can offer "auto-connect",
959 * where we connect to a service without specifying a destination address.
960 *
961 * Note : by consulting "errno", the user space caller may learn the cause
962 * of the failure. Most of them are visible in the function, others may come
963 * from subroutines called and are listed here :
964 * o EBUSY : already processing a connect
965 * o EHOSTUNREACH : bad addr->sir_addr argument
966 * o EADDRNOTAVAIL : bad addr->sir_name argument
967 * o ENOTUNIQ : more than one node has addr->sir_name (auto-connect)
968 * o ENETUNREACH : no node found on the network (auto-connect)
969 */
970static int irda_connect(struct socket *sock, struct sockaddr *uaddr,
971 int addr_len, int flags)
972{
973 struct sock *sk = sock->sk;
974 struct sockaddr_irda *addr = (struct sockaddr_irda *) uaddr;
975 struct irda_sock *self = irda_sk(sk);
976 int err;
977
978 IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
979
980 /* Don't allow connect for Ultra sockets */
981 if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA))
982 return -ESOCKTNOSUPPORT;
983
984 if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
985 sock->state = SS_CONNECTED;
986 return 0; /* Connect completed during a ERESTARTSYS event */
987 }
988
989 if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) {
990 sock->state = SS_UNCONNECTED;
991 return -ECONNREFUSED;
992 }
993
994 if (sk->sk_state == TCP_ESTABLISHED)
995 return -EISCONN; /* No reconnect on a seqpacket socket */
996
997 sk->sk_state = TCP_CLOSE;
998 sock->state = SS_UNCONNECTED;
999
1000 if (addr_len != sizeof(struct sockaddr_irda))
1001 return -EINVAL;
1002
1003 /* Check if user supplied any destination device address */
1004 if ((!addr->sir_addr) || (addr->sir_addr == DEV_ADDR_ANY)) {
1005 /* Try to find one suitable */
1006 err = irda_discover_daddr_and_lsap_sel(self, addr->sir_name);
1007 if (err) {
1008 IRDA_DEBUG(0, "%s(), auto-connect failed!\n", __FUNCTION__);
1009 return err;
1010 }
1011 } else {
1012 /* Use the one provided by the user */
1013 self->daddr = addr->sir_addr;
1014 IRDA_DEBUG(1, "%s(), daddr = %08x\n", __FUNCTION__, self->daddr);
1015
1016 /* If we don't have a valid service name, we assume the
1017 * user want to connect on a specific LSAP. Prevent
1018 * the use of invalid LSAPs (IrLMP 1.1 p10). Jean II */
1019 if((addr->sir_name[0] != '\0') ||
1020 (addr->sir_lsap_sel >= 0x70)) {
1021 /* Query remote LM-IAS using service name */
1022 err = irda_find_lsap_sel(self, addr->sir_name);
1023 if (err) {
1024 IRDA_DEBUG(0, "%s(), connect failed!\n", __FUNCTION__);
1025 return err;
1026 }
1027 } else {
1028 /* Directly connect to the remote LSAP
1029 * specified by the sir_lsap field.
1030 * Please use with caution, in IrDA LSAPs are
1031 * dynamic and there is no "well-known" LSAP. */
1032 self->dtsap_sel = addr->sir_lsap_sel;
1033 }
1034 }
1035
1036 /* Check if we have opened a local TSAP */
1037 if (!self->tsap)
1038 irda_open_tsap(self, LSAP_ANY, addr->sir_name);
1039
1040 /* Move to connecting socket, start sending Connect Requests */
1041 sock->state = SS_CONNECTING;
1042 sk->sk_state = TCP_SYN_SENT;
1043
1044 /* Connect to remote device */
1045 err = irttp_connect_request(self->tsap, self->dtsap_sel,
1046 self->saddr, self->daddr, NULL,
1047 self->max_sdu_size_rx, NULL);
1048 if (err) {
1049 IRDA_DEBUG(0, "%s(), connect failed!\n", __FUNCTION__);
1050 return err;
1051 }
1052
1053 /* Now the loop */
1054 if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
1055 return -EINPROGRESS;
1056
1057 if (wait_event_interruptible(*(sk->sk_sleep),
1058 (sk->sk_state != TCP_SYN_SENT)))
1059 return -ERESTARTSYS;
1060
1061 if (sk->sk_state != TCP_ESTABLISHED) {
1062 sock->state = SS_UNCONNECTED;
1063 return sock_error(sk); /* Always set at this point */
1064 }
1065
1066 sock->state = SS_CONNECTED;
1067
1068 /* At this point, IrLMP has assigned our source address */
1069 self->saddr = irttp_get_saddr(self->tsap);
1070
1071 return 0;
1072}
1073
1074static struct proto irda_proto = {
1075 .name = "IRDA",
1076 .owner = THIS_MODULE,
1077 .obj_size = sizeof(struct irda_sock),
1078};
1079
1080/*
1081 * Function irda_create (sock, protocol)
1082 *
1083 * Create IrDA socket
1084 *
1085 */
1086static int irda_create(struct socket *sock, int protocol)
1087{
1088 struct sock *sk;
1089 struct irda_sock *self;
1090
1091 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
1092
1093 /* Check for valid socket type */
1094 switch (sock->type) {
1095 case SOCK_STREAM: /* For TTP connections with SAR disabled */
1096 case SOCK_SEQPACKET: /* For TTP connections with SAR enabled */
1097 case SOCK_DGRAM: /* For TTP Unitdata or LMP Ultra transfers */
1098 break;
1099 default:
1100 return -ESOCKTNOSUPPORT;
1101 }
1102
1103 /* Allocate networking socket */
1104 sk = sk_alloc(PF_IRDA, GFP_ATOMIC, &irda_proto, 1);
1105 if (sk == NULL)
1106 return -ENOMEM;
1107
1108 self = irda_sk(sk);
1109 IRDA_DEBUG(2, "%s() : self is %p\n", __FUNCTION__, self);
1110
1111 init_waitqueue_head(&self->query_wait);
1112
1113 /* Initialise networking socket struct */
1114 sock_init_data(sock, sk); /* Note : set sk->sk_refcnt to 1 */
1115 sk->sk_family = PF_IRDA;
1116 sk->sk_protocol = protocol;
1117
1118 switch (sock->type) {
1119 case SOCK_STREAM:
1120 sock->ops = &irda_stream_ops;
1121 self->max_sdu_size_rx = TTP_SAR_DISABLE;
1122 break;
1123 case SOCK_SEQPACKET:
1124 sock->ops = &irda_seqpacket_ops;
1125 self->max_sdu_size_rx = TTP_SAR_UNBOUND;
1126 break;
1127 case SOCK_DGRAM:
1128 switch (protocol) {
1129#ifdef CONFIG_IRDA_ULTRA
1130 case IRDAPROTO_ULTRA:
1131 sock->ops = &irda_ultra_ops;
1132 /* Initialise now, because we may send on unbound
1133 * sockets. Jean II */
1134 self->max_data_size = ULTRA_MAX_DATA - LMP_PID_HEADER;
1135 self->max_header_size = IRDA_MAX_HEADER + LMP_PID_HEADER;
1136 break;
1137#endif /* CONFIG_IRDA_ULTRA */
1138 case IRDAPROTO_UNITDATA:
1139 sock->ops = &irda_dgram_ops;
1140 /* We let Unitdata conn. be like seqpack conn. */
1141 self->max_sdu_size_rx = TTP_SAR_UNBOUND;
1142 break;
1143 default:
1144 IRDA_ERROR("%s: protocol not supported!\n",
1145 __FUNCTION__);
1146 return -ESOCKTNOSUPPORT;
1147 }
1148 break;
1149 default:
1150 return -ESOCKTNOSUPPORT;
1151 }
1152
1153 /* Register as a client with IrLMP */
1154 self->ckey = irlmp_register_client(0, NULL, NULL, NULL);
1155 self->mask.word = 0xffff;
1156 self->rx_flow = self->tx_flow = FLOW_START;
1157 self->nslots = DISCOVERY_DEFAULT_SLOTS;
1158 self->daddr = DEV_ADDR_ANY; /* Until we get connected */
1159 self->saddr = 0x0; /* so IrLMP assign us any link */
1160 return 0;
1161}
1162
1163/*
1164 * Function irda_destroy_socket (self)
1165 *
1166 * Destroy socket
1167 *
1168 */
1169static void irda_destroy_socket(struct irda_sock *self)
1170{
1171 IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
1172
1173 IRDA_ASSERT(self != NULL, return;);
1174
1175 /* Unregister with IrLMP */
1176 irlmp_unregister_client(self->ckey);
1177 irlmp_unregister_service(self->skey);
1178
1179 /* Unregister with LM-IAS */
1180 if (self->ias_obj) {
1181 irias_delete_object(self->ias_obj);
1182 self->ias_obj = NULL;
1183 }
1184
1185 if (self->iriap) {
1186 iriap_close(self->iriap);
1187 self->iriap = NULL;
1188 }
1189
1190 if (self->tsap) {
1191 irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
1192 irttp_close_tsap(self->tsap);
1193 self->tsap = NULL;
1194 }
1195#ifdef CONFIG_IRDA_ULTRA
1196 if (self->lsap) {
1197 irlmp_close_lsap(self->lsap);
1198 self->lsap = NULL;
1199 }
1200#endif /* CONFIG_IRDA_ULTRA */
1201}
1202
1203/*
1204 * Function irda_release (sock)
1205 */
1206static int irda_release(struct socket *sock)
1207{
1208 struct sock *sk = sock->sk;
1209
1210 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
1211
1212 if (sk == NULL)
1213 return 0;
1214
1215 sk->sk_state = TCP_CLOSE;
1216 sk->sk_shutdown |= SEND_SHUTDOWN;
1217 sk->sk_state_change(sk);
1218
1219 /* Destroy IrDA socket */
1220 irda_destroy_socket(irda_sk(sk));
1221
1222 sock_orphan(sk);
1223 sock->sk = NULL;
1224
1225 /* Purge queues (see sock_init_data()) */
1226 skb_queue_purge(&sk->sk_receive_queue);
1227
1228 /* Destroy networking socket if we are the last reference on it,
1229 * i.e. if(sk->sk_refcnt == 0) -> sk_free(sk) */
1230 sock_put(sk);
1231
1232 /* Notes on socket locking and deallocation... - Jean II
1233 * In theory we should put pairs of sock_hold() / sock_put() to
1234 * prevent the socket to be destroyed whenever there is an
1235 * outstanding request or outstanding incoming packet or event.
1236 *
1237 * 1) This may include IAS request, both in connect and getsockopt.
1238 * Unfortunately, the situation is a bit more messy than it looks,
1239 * because we close iriap and kfree(self) above.
1240 *
1241 * 2) This may include selective discovery in getsockopt.
1242 * Same stuff as above, irlmp registration and self are gone.
1243 *
1244 * Probably 1 and 2 may not matter, because it's all triggered
1245 * by a process and the socket layer already prevent the
1246 * socket to go away while a process is holding it, through
1247 * sockfd_put() and fput()...
1248 *
1249 * 3) This may include deferred TSAP closure. In particular,
1250 * we may receive a late irda_disconnect_indication()
1251 * Fortunately, (tsap_cb *)->close_pend should protect us
1252 * from that.
1253 *
1254 * I did some testing on SMP, and it looks solid. And the socket
1255 * memory leak is now gone... - Jean II
1256 */
1257
1258 return 0;
1259}
1260
1261/*
1262 * Function irda_sendmsg (iocb, sock, msg, len)
1263 *
1264 * Send message down to TinyTP. This function is used for both STREAM and
1265 * SEQPACK services. This is possible since it forces the client to
1266 * fragment the message if necessary
1267 */
1268static int irda_sendmsg(struct kiocb *iocb, struct socket *sock,
1269 struct msghdr *msg, size_t len)
1270{
1271 struct sock *sk = sock->sk;
1272 struct irda_sock *self;
1273 struct sk_buff *skb;
1274 unsigned char *asmptr;
1275 int err;
1276
1277 IRDA_DEBUG(4, "%s(), len=%zd\n", __FUNCTION__, len);
1278
1279 /* Note : socket.c set MSG_EOR on SEQPACKET sockets */
1280 if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
1281 return -EINVAL;
1282
1283 if (sk->sk_shutdown & SEND_SHUTDOWN) {
1284 send_sig(SIGPIPE, current, 0);
1285 return -EPIPE;
1286 }
1287
1288 if (sk->sk_state != TCP_ESTABLISHED)
1289 return -ENOTCONN;
1290
1291 self = irda_sk(sk);
1292 IRDA_ASSERT(self != NULL, return -1;);
1293
1294 /* Check if IrTTP is wants us to slow down */
1295
1296 if (wait_event_interruptible(*(sk->sk_sleep),
1297 (self->tx_flow != FLOW_STOP || sk->sk_state != TCP_ESTABLISHED)))
1298 return -ERESTARTSYS;
1299
1300 /* Check if we are still connected */
1301 if (sk->sk_state != TCP_ESTABLISHED)
1302 return -ENOTCONN;
1303
1304 /* Check that we don't send out to big frames */
1305 if (len > self->max_data_size) {
1306 IRDA_DEBUG(2, "%s(), Chopping frame from %zd to %d bytes!\n",
1307 __FUNCTION__, len, self->max_data_size);
1308 len = self->max_data_size;
1309 }
1310
1311 skb = sock_alloc_send_skb(sk, len + self->max_header_size + 16,
1312 msg->msg_flags & MSG_DONTWAIT, &err);
1313 if (!skb)
1314 return -ENOBUFS;
1315
1316 skb_reserve(skb, self->max_header_size + 16);
1317
1318 asmptr = skb->h.raw = skb_put(skb, len);
1319 err = memcpy_fromiovec(asmptr, msg->msg_iov, len);
1320 if (err) {
1321 kfree_skb(skb);
1322 return err;
1323 }
1324
1325 /*
1326 * Just send the message to TinyTP, and let it deal with possible
1327 * errors. No need to duplicate all that here
1328 */
1329 err = irttp_data_request(self->tsap, skb);
1330 if (err) {
1331 IRDA_DEBUG(0, "%s(), err=%d\n", __FUNCTION__, err);
1332 return err;
1333 }
1334 /* Tell client how much data we actually sent */
1335 return len;
1336}
1337
1338/*
1339 * Function irda_recvmsg_dgram (iocb, sock, msg, size, flags)
1340 *
1341 * Try to receive message and copy it to user. The frame is discarded
1342 * after being read, regardless of how much the user actually read
1343 */
1344static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
1345 struct msghdr *msg, size_t size, int flags)
1346{
1347 struct sock *sk = sock->sk;
1348 struct irda_sock *self = irda_sk(sk);
1349 struct sk_buff *skb;
1350 size_t copied;
1351 int err;
1352
1353 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1354
1355 IRDA_ASSERT(self != NULL, return -1;);
1356
1357 skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
1358 flags & MSG_DONTWAIT, &err);
1359 if (!skb)
1360 return err;
1361
1362 skb->h.raw = skb->data;
1363 copied = skb->len;
1364
1365 if (copied > size) {
1366 IRDA_DEBUG(2, "%s(), Received truncated frame (%zd < %zd)!\n",
1367 __FUNCTION__, copied, size);
1368 copied = size;
1369 msg->msg_flags |= MSG_TRUNC;
1370 }
1371 skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
1372
1373 skb_free_datagram(sk, skb);
1374
1375 /*
1376 * Check if we have previously stopped IrTTP and we know
1377 * have more free space in our rx_queue. If so tell IrTTP
1378 * to start delivering frames again before our rx_queue gets
1379 * empty
1380 */
1381 if (self->rx_flow == FLOW_STOP) {
1382 if ((atomic_read(&sk->sk_rmem_alloc) << 2) <= sk->sk_rcvbuf) {
1383 IRDA_DEBUG(2, "%s(), Starting IrTTP\n", __FUNCTION__);
1384 self->rx_flow = FLOW_START;
1385 irttp_flow_request(self->tsap, FLOW_START);
1386 }
1387 }
1388
1389 return copied;
1390}
1391
1392/*
1393 * Function irda_recvmsg_stream (iocb, sock, msg, size, flags)
1394 */
1395static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
1396 struct msghdr *msg, size_t size, int flags)
1397{
1398 struct sock *sk = sock->sk;
1399 struct irda_sock *self = irda_sk(sk);
1400 int noblock = flags & MSG_DONTWAIT;
1401 size_t copied = 0;
1402 int target = 1;
1403 DECLARE_WAITQUEUE(waitq, current);
1404
1405 IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
1406
1407 IRDA_ASSERT(self != NULL, return -1;);
1408
1409 if (sock->flags & __SO_ACCEPTCON)
1410 return(-EINVAL);
1411
1412 if (flags & MSG_OOB)
1413 return -EOPNOTSUPP;
1414
1415 if (flags & MSG_WAITALL)
1416 target = size;
1417
1418 msg->msg_namelen = 0;
1419
1420 do {
1421 int chunk;
1422 struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue);
1423
1424 if (skb==NULL) {
1425 int ret = 0;
1426
1427 if (copied >= target)
1428 break;
1429
1430 /* The following code is a cut'n'paste of the
1431 * wait_event_interruptible() macro.
1432 * We don't us the macro because the test condition
1433 * is messy. - Jean II */
1434 set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
1435 add_wait_queue(sk->sk_sleep, &waitq);
1436 set_current_state(TASK_INTERRUPTIBLE);
1437
1438 /*
1439 * POSIX 1003.1g mandates this order.
1440 */
1441 if (sk->sk_err)
1442 ret = sock_error(sk);
1443 else if (sk->sk_shutdown & RCV_SHUTDOWN)
1444 ;
1445 else if (noblock)
1446 ret = -EAGAIN;
1447 else if (signal_pending(current))
1448 ret = -ERESTARTSYS;
1449 else if (skb_peek(&sk->sk_receive_queue) == NULL)
1450 /* Wait process until data arrives */
1451 schedule();
1452
1453 current->state = TASK_RUNNING;
1454 remove_wait_queue(sk->sk_sleep, &waitq);
1455 clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
1456
1457 if(ret)
1458 return(ret);
1459 if (sk->sk_shutdown & RCV_SHUTDOWN)
1460 break;
1461
1462 continue;
1463 }
1464
1465 chunk = min_t(unsigned int, skb->len, size);
1466 if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
1467 skb_queue_head(&sk->sk_receive_queue, skb);
1468 if (copied == 0)
1469 copied = -EFAULT;
1470 break;
1471 }
1472 copied += chunk;
1473 size -= chunk;
1474
1475 /* Mark read part of skb as used */
1476 if (!(flags & MSG_PEEK)) {
1477 skb_pull(skb, chunk);
1478
1479 /* put the skb back if we didn't use it up.. */
1480 if (skb->len) {
1481 IRDA_DEBUG(1, "%s(), back on q!\n",
1482 __FUNCTION__);
1483 skb_queue_head(&sk->sk_receive_queue, skb);
1484 break;
1485 }
1486
1487 kfree_skb(skb);
1488 } else {
1489 IRDA_DEBUG(0, "%s() questionable!?\n", __FUNCTION__);
1490
1491 /* put message back and return */
1492 skb_queue_head(&sk->sk_receive_queue, skb);
1493 break;
1494 }
1495 } while (size);
1496
1497 /*
1498 * Check if we have previously stopped IrTTP and we know
1499 * have more free space in our rx_queue. If so tell IrTTP
1500 * to start delivering frames again before our rx_queue gets
1501 * empty
1502 */
1503 if (self->rx_flow == FLOW_STOP) {
1504 if ((atomic_read(&sk->sk_rmem_alloc) << 2) <= sk->sk_rcvbuf) {
1505 IRDA_DEBUG(2, "%s(), Starting IrTTP\n", __FUNCTION__);
1506 self->rx_flow = FLOW_START;
1507 irttp_flow_request(self->tsap, FLOW_START);
1508 }
1509 }
1510
1511 return copied;
1512}
1513
1514/*
1515 * Function irda_sendmsg_dgram (iocb, sock, msg, len)
1516 *
1517 * Send message down to TinyTP for the unreliable sequenced
1518 * packet service...
1519 *
1520 */
1521static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
1522 struct msghdr *msg, size_t len)
1523{
1524 struct sock *sk = sock->sk;
1525 struct irda_sock *self;
1526 struct sk_buff *skb;
1527 unsigned char *asmptr;
1528 int err;
1529
1530 IRDA_DEBUG(4, "%s(), len=%zd\n", __FUNCTION__, len);
1531
1532 if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
1533 return -EINVAL;
1534
1535 if (sk->sk_shutdown & SEND_SHUTDOWN) {
1536 send_sig(SIGPIPE, current, 0);
1537 return -EPIPE;
1538 }
1539
1540 if (sk->sk_state != TCP_ESTABLISHED)
1541 return -ENOTCONN;
1542
1543 self = irda_sk(sk);
1544 IRDA_ASSERT(self != NULL, return -1;);
1545
1546 /*
1547 * Check that we don't send out to big frames. This is an unreliable
1548 * service, so we have no fragmentation and no coalescence
1549 */
1550 if (len > self->max_data_size) {
1551 IRDA_DEBUG(0, "%s(), Warning to much data! "
1552 "Chopping frame from %zd to %d bytes!\n",
1553 __FUNCTION__, len, self->max_data_size);
1554 len = self->max_data_size;
1555 }
1556
1557 skb = sock_alloc_send_skb(sk, len + self->max_header_size,
1558 msg->msg_flags & MSG_DONTWAIT, &err);
1559 if (!skb)
1560 return -ENOBUFS;
1561
1562 skb_reserve(skb, self->max_header_size);
1563
1564 IRDA_DEBUG(4, "%s(), appending user data\n", __FUNCTION__);
1565 asmptr = skb->h.raw = skb_put(skb, len);
1566 err = memcpy_fromiovec(asmptr, msg->msg_iov, len);
1567 if (err) {
1568 kfree_skb(skb);
1569 return err;
1570 }
1571
1572 /*
1573 * Just send the message to TinyTP, and let it deal with possible
1574 * errors. No need to duplicate all that here
1575 */
1576 err = irttp_udata_request(self->tsap, skb);
1577 if (err) {
1578 IRDA_DEBUG(0, "%s(), err=%d\n", __FUNCTION__, err);
1579 return err;
1580 }
1581 return len;
1582}
1583
1584/*
1585 * Function irda_sendmsg_ultra (iocb, sock, msg, len)
1586 *
1587 * Send message down to IrLMP for the unreliable Ultra
1588 * packet service...
1589 */
1590#ifdef CONFIG_IRDA_ULTRA
1591static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
1592 struct msghdr *msg, size_t len)
1593{
1594 struct sock *sk = sock->sk;
1595 struct irda_sock *self;
1596 __u8 pid = 0;
1597 int bound = 0;
1598 struct sk_buff *skb;
1599 unsigned char *asmptr;
1600 int err;
1601
1602 IRDA_DEBUG(4, "%s(), len=%zd\n", __FUNCTION__, len);
1603
1604 if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
1605 return -EINVAL;
1606
1607 if (sk->sk_shutdown & SEND_SHUTDOWN) {
1608 send_sig(SIGPIPE, current, 0);
1609 return -EPIPE;
1610 }
1611
1612 self = irda_sk(sk);
1613 IRDA_ASSERT(self != NULL, return -1;);
1614
1615 /* Check if an address was specified with sendto. Jean II */
1616 if (msg->msg_name) {
1617 struct sockaddr_irda *addr = (struct sockaddr_irda *) msg->msg_name;
1618 /* Check address, extract pid. Jean II */
1619 if (msg->msg_namelen < sizeof(*addr))
1620 return -EINVAL;
1621 if (addr->sir_family != AF_IRDA)
1622 return -EINVAL;
1623
1624 pid = addr->sir_lsap_sel;
1625 if (pid & 0x80) {
1626 IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __FUNCTION__);
1627 return -EOPNOTSUPP;
1628 }
1629 } else {
1630 /* Check that the socket is properly bound to an Ultra
1631 * port. Jean II */
1632 if ((self->lsap == NULL) ||
1633 (sk->sk_state != TCP_ESTABLISHED)) {
1634 IRDA_DEBUG(0, "%s(), socket not bound to Ultra PID.\n",
1635 __FUNCTION__);
1636 return -ENOTCONN;
1637 }
1638 /* Use PID from socket */
1639 bound = 1;
1640 }
1641
1642 /*
1643 * Check that we don't send out to big frames. This is an unreliable
1644 * service, so we have no fragmentation and no coalescence
1645 */
1646 if (len > self->max_data_size) {
1647 IRDA_DEBUG(0, "%s(), Warning to much data! "
1648 "Chopping frame from %zd to %d bytes!\n",
1649 __FUNCTION__, len, self->max_data_size);
1650 len = self->max_data_size;
1651 }
1652
1653 skb = sock_alloc_send_skb(sk, len + self->max_header_size,
1654 msg->msg_flags & MSG_DONTWAIT, &err);
1655 if (!skb)
1656 return -ENOBUFS;
1657
1658 skb_reserve(skb, self->max_header_size);
1659
1660 IRDA_DEBUG(4, "%s(), appending user data\n", __FUNCTION__);
1661 asmptr = skb->h.raw = skb_put(skb, len);
1662 err = memcpy_fromiovec(asmptr, msg->msg_iov, len);
1663 if (err) {
1664 kfree_skb(skb);
1665 return err;
1666 }
1667
1668 err = irlmp_connless_data_request((bound ? self->lsap : NULL),
1669 skb, pid);
1670 if (err) {
1671 IRDA_DEBUG(0, "%s(), err=%d\n", __FUNCTION__, err);
1672 return err;
1673 }
1674 return len;
1675}
1676#endif /* CONFIG_IRDA_ULTRA */
1677
1678/*
1679 * Function irda_shutdown (sk, how)
1680 */
1681static int irda_shutdown(struct socket *sock, int how)
1682{
1683 struct sock *sk = sock->sk;
1684 struct irda_sock *self = irda_sk(sk);
1685
1686 IRDA_ASSERT(self != NULL, return -1;);
1687
1688 IRDA_DEBUG(1, "%s(%p)\n", __FUNCTION__, self);
1689
1690 sk->sk_state = TCP_CLOSE;
1691 sk->sk_shutdown |= SEND_SHUTDOWN;
1692 sk->sk_state_change(sk);
1693
1694 if (self->iriap) {
1695 iriap_close(self->iriap);
1696 self->iriap = NULL;
1697 }
1698
1699 if (self->tsap) {
1700 irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
1701 irttp_close_tsap(self->tsap);
1702 self->tsap = NULL;
1703 }
1704
1705 /* A few cleanup so the socket look as good as new... */
1706 self->rx_flow = self->tx_flow = FLOW_START; /* needed ??? */
1707 self->daddr = DEV_ADDR_ANY; /* Until we get re-connected */
1708 self->saddr = 0x0; /* so IrLMP assign us any link */
1709
1710 return 0;
1711}
1712
1713/*
1714 * Function irda_poll (file, sock, wait)
1715 */
1716static unsigned int irda_poll(struct file * file, struct socket *sock,
1717 poll_table *wait)
1718{
1719 struct sock *sk = sock->sk;
1720 struct irda_sock *self = irda_sk(sk);
1721 unsigned int mask;
1722
1723 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1724
1725 poll_wait(file, sk->sk_sleep, wait);
1726 mask = 0;
1727
1728 /* Exceptional events? */
1729 if (sk->sk_err)
1730 mask |= POLLERR;
1731 if (sk->sk_shutdown & RCV_SHUTDOWN) {
1732 IRDA_DEBUG(0, "%s(), POLLHUP\n", __FUNCTION__);
1733 mask |= POLLHUP;
1734 }
1735
1736 /* Readable? */
1737 if (!skb_queue_empty(&sk->sk_receive_queue)) {
1738 IRDA_DEBUG(4, "Socket is readable\n");
1739 mask |= POLLIN | POLLRDNORM;
1740 }
1741
1742 /* Connection-based need to check for termination and startup */
1743 switch (sk->sk_type) {
1744 case SOCK_STREAM:
1745 if (sk->sk_state == TCP_CLOSE) {
1746 IRDA_DEBUG(0, "%s(), POLLHUP\n", __FUNCTION__);
1747 mask |= POLLHUP;
1748 }
1749
1750 if (sk->sk_state == TCP_ESTABLISHED) {
1751 if ((self->tx_flow == FLOW_START) &&
1752 sock_writeable(sk))
1753 {
1754 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
1755 }
1756 }
1757 break;
1758 case SOCK_SEQPACKET:
1759 if ((self->tx_flow == FLOW_START) &&
1760 sock_writeable(sk))
1761 {
1762 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
1763 }
1764 break;
1765 case SOCK_DGRAM:
1766 if (sock_writeable(sk))
1767 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
1768 break;
1769 default:
1770 break;
1771 }
1772 return mask;
1773}
1774
1775/*
1776 * Function irda_ioctl (sock, cmd, arg)
1777 */
1778static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1779{
1780 struct sock *sk = sock->sk;
1781
1782 IRDA_DEBUG(4, "%s(), cmd=%#x\n", __FUNCTION__, cmd);
1783
1784 switch (cmd) {
1785 case TIOCOUTQ: {
1786 long amount;
1787 amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
1788 if (amount < 0)
1789 amount = 0;
1790 if (put_user(amount, (unsigned int __user *)arg))
1791 return -EFAULT;
1792 return 0;
1793 }
1794
1795 case TIOCINQ: {
1796 struct sk_buff *skb;
1797 long amount = 0L;
1798 /* These two are safe on a single CPU system as only user tasks fiddle here */
1799 if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
1800 amount = skb->len;
1801 if (put_user(amount, (unsigned int __user *)arg))
1802 return -EFAULT;
1803 return 0;
1804 }
1805
1806 case SIOCGSTAMP:
1807 if (sk != NULL)
1808 return sock_get_timestamp(sk, (struct timeval __user *)arg);
1809 return -EINVAL;
1810
1811 case SIOCGIFADDR:
1812 case SIOCSIFADDR:
1813 case SIOCGIFDSTADDR:
1814 case SIOCSIFDSTADDR:
1815 case SIOCGIFBRDADDR:
1816 case SIOCSIFBRDADDR:
1817 case SIOCGIFNETMASK:
1818 case SIOCSIFNETMASK:
1819 case SIOCGIFMETRIC:
1820 case SIOCSIFMETRIC:
1821 return -EINVAL;
1822 default:
1823 IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __FUNCTION__);
1824 return dev_ioctl(cmd, (void __user *) arg);
1825 }
1826
1827 /*NOTREACHED*/
1828 return 0;
1829}
1830
1831/*
1832 * Function irda_setsockopt (sock, level, optname, optval, optlen)
1833 *
1834 * Set some options for the socket
1835 *
1836 */
1837static int irda_setsockopt(struct socket *sock, int level, int optname,
1838 char __user *optval, int optlen)
1839{
1840 struct sock *sk = sock->sk;
1841 struct irda_sock *self = irda_sk(sk);
1842 struct irda_ias_set *ias_opt;
1843 struct ias_object *ias_obj;
1844 struct ias_attrib * ias_attr; /* Attribute in IAS object */
1845 int opt;
1846
1847 IRDA_ASSERT(self != NULL, return -1;);
1848
1849 IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
1850
1851 if (level != SOL_IRLMP)
1852 return -ENOPROTOOPT;
1853
1854 switch (optname) {
1855 case IRLMP_IAS_SET:
1856 /* The user want to add an attribute to an existing IAS object
1857 * (in the IAS database) or to create a new object with this
1858 * attribute.
1859 * We first query IAS to know if the object exist, and then
1860 * create the right attribute...
1861 */
1862
1863 if (optlen != sizeof(struct irda_ias_set))
1864 return -EINVAL;
1865
1866 ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
1867 if (ias_opt == NULL)
1868 return -ENOMEM;
1869
1870 /* Copy query to the driver. */
1871 if (copy_from_user(ias_opt, optval, optlen)) {
1872 kfree(ias_opt);
1873 return -EFAULT;
1874 }
1875
1876 /* Find the object we target.
1877 * If the user gives us an empty string, we use the object
1878 * associated with this socket. This will workaround
1879 * duplicated class name - Jean II */
1880 if(ias_opt->irda_class_name[0] == '\0') {
1881 if(self->ias_obj == NULL) {
1882 kfree(ias_opt);
1883 return -EINVAL;
1884 }
1885 ias_obj = self->ias_obj;
1886 } else
1887 ias_obj = irias_find_object(ias_opt->irda_class_name);
1888
1889 /* Only ROOT can mess with the global IAS database.
1890 * Users can only add attributes to the object associated
1891 * with the socket they own - Jean II */
1892 if((!capable(CAP_NET_ADMIN)) &&
1893 ((ias_obj == NULL) || (ias_obj != self->ias_obj))) {
1894 kfree(ias_opt);
1895 return -EPERM;
1896 }
1897
1898 /* If the object doesn't exist, create it */
1899 if(ias_obj == (struct ias_object *) NULL) {
1900 /* Create a new object */
1901 ias_obj = irias_new_object(ias_opt->irda_class_name,
1902 jiffies);
1903 }
1904
1905 /* Do we have the attribute already ? */
1906 if(irias_find_attrib(ias_obj, ias_opt->irda_attrib_name)) {
1907 kfree(ias_opt);
1908 return -EINVAL;
1909 }
1910
1911 /* Look at the type */
1912 switch(ias_opt->irda_attrib_type) {
1913 case IAS_INTEGER:
1914 /* Add an integer attribute */
1915 irias_add_integer_attrib(
1916 ias_obj,
1917 ias_opt->irda_attrib_name,
1918 ias_opt->attribute.irda_attrib_int,
1919 IAS_USER_ATTR);
1920 break;
1921 case IAS_OCT_SEQ:
1922 /* Check length */
1923 if(ias_opt->attribute.irda_attrib_octet_seq.len >
1924 IAS_MAX_OCTET_STRING) {
1925 kfree(ias_opt);
1926 return -EINVAL;
1927 }
1928 /* Add an octet sequence attribute */
1929 irias_add_octseq_attrib(
1930 ias_obj,
1931 ias_opt->irda_attrib_name,
1932 ias_opt->attribute.irda_attrib_octet_seq.octet_seq,
1933 ias_opt->attribute.irda_attrib_octet_seq.len,
1934 IAS_USER_ATTR);
1935 break;
1936 case IAS_STRING:
1937 /* Should check charset & co */
1938 /* Check length */
1939 /* The length is encoded in a __u8, and
1940 * IAS_MAX_STRING == 256, so there is no way
1941 * userspace can pass us a string too large.
1942 * Jean II */
1943 /* NULL terminate the string (avoid troubles) */
1944 ias_opt->attribute.irda_attrib_string.string[ias_opt->attribute.irda_attrib_string.len] = '\0';
1945 /* Add a string attribute */
1946 irias_add_string_attrib(
1947 ias_obj,
1948 ias_opt->irda_attrib_name,
1949 ias_opt->attribute.irda_attrib_string.string,
1950 IAS_USER_ATTR);
1951 break;
1952 default :
1953 kfree(ias_opt);
1954 return -EINVAL;
1955 }
1956 irias_insert_object(ias_obj);
1957 kfree(ias_opt);
1958 break;
1959 case IRLMP_IAS_DEL:
1960 /* The user want to delete an object from our local IAS
1961 * database. We just need to query the IAS, check is the
1962 * object is not owned by the kernel and delete it.
1963 */
1964
1965 if (optlen != sizeof(struct irda_ias_set))
1966 return -EINVAL;
1967
1968 ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
1969 if (ias_opt == NULL)
1970 return -ENOMEM;
1971
1972 /* Copy query to the driver. */
1973 if (copy_from_user(ias_opt, optval, optlen)) {
1974 kfree(ias_opt);
1975 return -EFAULT;
1976 }
1977
1978 /* Find the object we target.
1979 * If the user gives us an empty string, we use the object
1980 * associated with this socket. This will workaround
1981 * duplicated class name - Jean II */
1982 if(ias_opt->irda_class_name[0] == '\0')
1983 ias_obj = self->ias_obj;
1984 else
1985 ias_obj = irias_find_object(ias_opt->irda_class_name);
1986 if(ias_obj == (struct ias_object *) NULL) {
1987 kfree(ias_opt);
1988 return -EINVAL;
1989 }
1990
1991 /* Only ROOT can mess with the global IAS database.
1992 * Users can only del attributes from the object associated
1993 * with the socket they own - Jean II */
1994 if((!capable(CAP_NET_ADMIN)) &&
1995 ((ias_obj == NULL) || (ias_obj != self->ias_obj))) {
1996 kfree(ias_opt);
1997 return -EPERM;
1998 }
1999
2000 /* Find the attribute (in the object) we target */
2001 ias_attr = irias_find_attrib(ias_obj,
2002 ias_opt->irda_attrib_name);
2003 if(ias_attr == (struct ias_attrib *) NULL) {
2004 kfree(ias_opt);
2005 return -EINVAL;
2006 }
2007
2008 /* Check is the user space own the object */
2009 if(ias_attr->value->owner != IAS_USER_ATTR) {
2010 IRDA_DEBUG(1, "%s(), attempting to delete a kernel attribute\n", __FUNCTION__);
2011 kfree(ias_opt);
2012 return -EPERM;
2013 }
2014
2015 /* Remove the attribute (and maybe the object) */
2016 irias_delete_attrib(ias_obj, ias_attr, 1);
2017 kfree(ias_opt);
2018 break;
2019 case IRLMP_MAX_SDU_SIZE:
2020 if (optlen < sizeof(int))
2021 return -EINVAL;
2022
2023 if (get_user(opt, (int __user *)optval))
2024 return -EFAULT;
2025
2026 /* Only possible for a seqpacket service (TTP with SAR) */
2027 if (sk->sk_type != SOCK_SEQPACKET) {
2028 IRDA_DEBUG(2, "%s(), setting max_sdu_size = %d\n",
2029 __FUNCTION__, opt);
2030 self->max_sdu_size_rx = opt;
2031 } else {
2032 IRDA_WARNING("%s: not allowed to set MAXSDUSIZE for this socket type!\n",
2033 __FUNCTION__);
2034 return -ENOPROTOOPT;
2035 }
2036 break;
2037 case IRLMP_HINTS_SET:
2038 if (optlen < sizeof(int))
2039 return -EINVAL;
2040
2041 /* The input is really a (__u8 hints[2]), easier as an int */
2042 if (get_user(opt, (int __user *)optval))
2043 return -EFAULT;
2044
2045 /* Unregister any old registration */
2046 if (self->skey)
2047 irlmp_unregister_service(self->skey);
2048
2049 self->skey = irlmp_register_service((__u16) opt);
2050 break;
2051 case IRLMP_HINT_MASK_SET:
2052 /* As opposed to the previous case which set the hint bits
2053 * that we advertise, this one set the filter we use when
2054 * making a discovery (nodes which don't match any hint
2055 * bit in the mask are not reported).
2056 */
2057 if (optlen < sizeof(int))
2058 return -EINVAL;
2059
2060 /* The input is really a (__u8 hints[2]), easier as an int */
2061 if (get_user(opt, (int __user *)optval))
2062 return -EFAULT;
2063
2064 /* Set the new hint mask */
2065 self->mask.word = (__u16) opt;
2066 /* Mask out extension bits */
2067 self->mask.word &= 0x7f7f;
2068 /* Check if no bits */
2069 if(!self->mask.word)
2070 self->mask.word = 0xFFFF;
2071
2072 break;
2073 default:
2074 return -ENOPROTOOPT;
2075 }
2076 return 0;
2077}
2078
2079/*
2080 * Function irda_extract_ias_value(ias_opt, ias_value)
2081 *
2082 * Translate internal IAS value structure to the user space representation
2083 *
2084 * The external representation of IAS values, as we exchange them with
2085 * user space program is quite different from the internal representation,
2086 * as stored in the IAS database (because we need a flat structure for
2087 * crossing kernel boundary).
2088 * This function transform the former in the latter. We also check
2089 * that the value type is valid.
2090 */
2091static int irda_extract_ias_value(struct irda_ias_set *ias_opt,
2092 struct ias_value *ias_value)
2093{
2094 /* Look at the type */
2095 switch (ias_value->type) {
2096 case IAS_INTEGER:
2097 /* Copy the integer */
2098 ias_opt->attribute.irda_attrib_int = ias_value->t.integer;
2099 break;
2100 case IAS_OCT_SEQ:
2101 /* Set length */
2102 ias_opt->attribute.irda_attrib_octet_seq.len = ias_value->len;
2103 /* Copy over */
2104 memcpy(ias_opt->attribute.irda_attrib_octet_seq.octet_seq,
2105 ias_value->t.oct_seq, ias_value->len);
2106 break;
2107 case IAS_STRING:
2108 /* Set length */
2109 ias_opt->attribute.irda_attrib_string.len = ias_value->len;
2110 ias_opt->attribute.irda_attrib_string.charset = ias_value->charset;
2111 /* Copy over */
2112 memcpy(ias_opt->attribute.irda_attrib_string.string,
2113 ias_value->t.string, ias_value->len);
2114 /* NULL terminate the string (avoid troubles) */
2115 ias_opt->attribute.irda_attrib_string.string[ias_value->len] = '\0';
2116 break;
2117 case IAS_MISSING:
2118 default :
2119 return -EINVAL;
2120 }
2121
2122 /* Copy type over */
2123 ias_opt->irda_attrib_type = ias_value->type;
2124
2125 return 0;
2126}
2127
2128/*
2129 * Function irda_getsockopt (sock, level, optname, optval, optlen)
2130 */
2131static int irda_getsockopt(struct socket *sock, int level, int optname,
2132 char __user *optval, int __user *optlen)
2133{
2134 struct sock *sk = sock->sk;
2135 struct irda_sock *self = irda_sk(sk);
2136 struct irda_device_list list;
2137 struct irda_device_info *discoveries;
2138 struct irda_ias_set * ias_opt; /* IAS get/query params */
2139 struct ias_object * ias_obj; /* Object in IAS */
2140 struct ias_attrib * ias_attr; /* Attribute in IAS object */
2141 int daddr = DEV_ADDR_ANY; /* Dest address for IAS queries */
2142 int val = 0;
2143 int len = 0;
2144 int err;
2145 int offset, total;
2146
2147 IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
2148
2149 if (level != SOL_IRLMP)
2150 return -ENOPROTOOPT;
2151
2152 if (get_user(len, optlen))
2153 return -EFAULT;
2154
2155 if(len < 0)
2156 return -EINVAL;
2157
2158 switch (optname) {
2159 case IRLMP_ENUMDEVICES:
2160 /* Ask lmp for the current discovery log */
2161 discoveries = irlmp_get_discoveries(&list.len, self->mask.word,
2162 self->nslots);
2163 /* Check if the we got some results */
2164 if (discoveries == NULL)
2165 return -EAGAIN; /* Didn't find any devices */
2166 err = 0;
2167
2168 /* Write total list length back to client */
2169 if (copy_to_user(optval, &list,
2170 sizeof(struct irda_device_list) -
2171 sizeof(struct irda_device_info)))
2172 err = -EFAULT;
2173
2174 /* Offset to first device entry */
2175 offset = sizeof(struct irda_device_list) -
2176 sizeof(struct irda_device_info);
2177
2178 /* Copy the list itself - watch for overflow */
2179 if(list.len > 2048)
2180 {
2181 err = -EINVAL;
2182 goto bed;
2183 }
2184 total = offset + (list.len * sizeof(struct irda_device_info));
2185 if (total > len)
2186 total = len;
2187 if (copy_to_user(optval+offset, discoveries, total - offset))
2188 err = -EFAULT;
2189
2190 /* Write total number of bytes used back to client */
2191 if (put_user(total, optlen))
2192 err = -EFAULT;
2193bed:
2194 /* Free up our buffer */
2195 kfree(discoveries);
2196 if (err)
2197 return err;
2198 break;
2199 case IRLMP_MAX_SDU_SIZE:
2200 val = self->max_data_size;
2201 len = sizeof(int);
2202 if (put_user(len, optlen))
2203 return -EFAULT;
2204
2205 if (copy_to_user(optval, &val, len))
2206 return -EFAULT;
2207 break;
2208 case IRLMP_IAS_GET:
2209 /* The user want an object from our local IAS database.
2210 * We just need to query the IAS and return the value
2211 * that we found */
2212
2213 /* Check that the user has allocated the right space for us */
2214 if (len != sizeof(struct irda_ias_set))
2215 return -EINVAL;
2216
2217 ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
2218 if (ias_opt == NULL)
2219 return -ENOMEM;
2220
2221 /* Copy query to the driver. */
2222 if (copy_from_user(ias_opt, optval, len)) {
2223 kfree(ias_opt);
2224 return -EFAULT;
2225 }
2226
2227 /* Find the object we target.
2228 * If the user gives us an empty string, we use the object
2229 * associated with this socket. This will workaround
2230 * duplicated class name - Jean II */
2231 if(ias_opt->irda_class_name[0] == '\0')
2232 ias_obj = self->ias_obj;
2233 else
2234 ias_obj = irias_find_object(ias_opt->irda_class_name);
2235 if(ias_obj == (struct ias_object *) NULL) {
2236 kfree(ias_opt);
2237 return -EINVAL;
2238 }
2239
2240 /* Find the attribute (in the object) we target */
2241 ias_attr = irias_find_attrib(ias_obj,
2242 ias_opt->irda_attrib_name);
2243 if(ias_attr == (struct ias_attrib *) NULL) {
2244 kfree(ias_opt);
2245 return -EINVAL;
2246 }
2247
2248 /* Translate from internal to user structure */
2249 err = irda_extract_ias_value(ias_opt, ias_attr->value);
2250 if(err) {
2251 kfree(ias_opt);
2252 return err;
2253 }
2254
2255 /* Copy reply to the user */
2256 if (copy_to_user(optval, ias_opt,
2257 sizeof(struct irda_ias_set))) {
2258 kfree(ias_opt);
2259 return -EFAULT;
2260 }
2261 /* Note : don't need to put optlen, we checked it */
2262 kfree(ias_opt);
2263 break;
2264 case IRLMP_IAS_QUERY:
2265 /* The user want an object from a remote IAS database.
2266 * We need to use IAP to query the remote database and
2267 * then wait for the answer to come back. */
2268
2269 /* Check that the user has allocated the right space for us */
2270 if (len != sizeof(struct irda_ias_set))
2271 return -EINVAL;
2272
2273 ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC);
2274 if (ias_opt == NULL)
2275 return -ENOMEM;
2276
2277 /* Copy query to the driver. */
2278 if (copy_from_user(ias_opt, optval, len)) {
2279 kfree(ias_opt);
2280 return -EFAULT;
2281 }
2282
2283 /* At this point, there are two cases...
2284 * 1) the socket is connected - that's the easy case, we
2285 * just query the device we are connected to...
2286 * 2) the socket is not connected - the user doesn't want
2287 * to connect and/or may not have a valid service name
2288 * (so can't create a fake connection). In this case,
2289 * we assume that the user pass us a valid destination
2290 * address in the requesting structure...
2291 */
2292 if(self->daddr != DEV_ADDR_ANY) {
2293 /* We are connected - reuse known daddr */
2294 daddr = self->daddr;
2295 } else {
2296 /* We are not connected, we must specify a valid
2297 * destination address */
2298 daddr = ias_opt->daddr;
2299 if((!daddr) || (daddr == DEV_ADDR_ANY)) {
2300 kfree(ias_opt);
2301 return -EINVAL;
2302 }
2303 }
2304
2305 /* Check that we can proceed with IAP */
2306 if (self->iriap) {
2307 IRDA_WARNING("%s: busy with a previous query\n",
2308 __FUNCTION__);
2309 kfree(ias_opt);
2310 return -EBUSY;
2311 }
2312
2313 self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
2314 irda_getvalue_confirm);
2315
2316 if (self->iriap == NULL) {
2317 kfree(ias_opt);
2318 return -ENOMEM;
2319 }
2320
2321 /* Treat unexpected wakeup as disconnect */
2322 self->errno = -EHOSTUNREACH;
2323
2324 /* Query remote LM-IAS */
2325 iriap_getvaluebyclass_request(self->iriap,
2326 self->saddr, daddr,
2327 ias_opt->irda_class_name,
2328 ias_opt->irda_attrib_name);
2329
2330 /* Wait for answer, if not yet finished (or failed) */
2331 if (wait_event_interruptible(self->query_wait,
2332 (self->iriap == NULL))) {
2333 /* pending request uses copy of ias_opt-content
2334 * we can free it regardless! */
2335 kfree(ias_opt);
2336 /* Treat signals as disconnect */
2337 return -EHOSTUNREACH;
2338 }
2339
2340 /* Check what happened */
2341 if (self->errno)
2342 {
2343 kfree(ias_opt);
2344 /* Requested object/attribute doesn't exist */
2345 if((self->errno == IAS_CLASS_UNKNOWN) ||
2346 (self->errno == IAS_ATTRIB_UNKNOWN))
2347 return (-EADDRNOTAVAIL);
2348 else
2349 return (-EHOSTUNREACH);
2350 }
2351
2352 /* Translate from internal to user structure */
2353 err = irda_extract_ias_value(ias_opt, self->ias_result);
2354 if (self->ias_result)
2355 irias_delete_value(self->ias_result);
2356 if (err) {
2357 kfree(ias_opt);
2358 return err;
2359 }
2360
2361 /* Copy reply to the user */
2362 if (copy_to_user(optval, ias_opt,
2363 sizeof(struct irda_ias_set))) {
2364 kfree(ias_opt);
2365 return -EFAULT;
2366 }
2367 /* Note : don't need to put optlen, we checked it */
2368 kfree(ias_opt);
2369 break;
2370 case IRLMP_WAITDEVICE:
2371 /* This function is just another way of seeing life ;-)
2372 * IRLMP_ENUMDEVICES assumes that you have a static network,
2373 * and that you just want to pick one of the devices present.
2374 * On the other hand, in here we assume that no device is
2375 * present and that at some point in the future a device will
2376 * come into range. When this device arrive, we just wake
2377 * up the caller, so that he has time to connect to it before
2378 * the device goes away...
2379 * Note : once the node has been discovered for more than a
2380 * few second, it won't trigger this function, unless it
2381 * goes away and come back changes its hint bits (so we
2382 * might call it IRLMP_WAITNEWDEVICE).
2383 */
2384
2385 /* Check that the user is passing us an int */
2386 if (len != sizeof(int))
2387 return -EINVAL;
2388 /* Get timeout in ms (max time we block the caller) */
2389 if (get_user(val, (int __user *)optval))
2390 return -EFAULT;
2391
2392 /* Tell IrLMP we want to be notified */
2393 irlmp_update_client(self->ckey, self->mask.word,
2394 irda_selective_discovery_indication,
2395 NULL, (void *) self);
2396
2397 /* Do some discovery (and also return cached results) */
2398 irlmp_discovery_request(self->nslots);
2399
2400 /* Wait until a node is discovered */
2401 if (!self->cachedaddr) {
2402 int ret = 0;
2403
2404 IRDA_DEBUG(1, "%s(), nothing discovered yet, going to sleep...\n", __FUNCTION__);
2405
2406 /* Set watchdog timer to expire in <val> ms. */
2407 self->errno = 0;
2408 init_timer(&self->watchdog);
2409 self->watchdog.function = irda_discovery_timeout;
2410 self->watchdog.data = (unsigned long) self;
2411 self->watchdog.expires = jiffies + (val * HZ/1000);
2412 add_timer(&(self->watchdog));
2413
2414 /* Wait for IR-LMP to call us back */
2415 __wait_event_interruptible(self->query_wait,
2416 (self->cachedaddr != 0 || self->errno == -ETIME),
2417 ret);
2418
2419 /* If watchdog is still activated, kill it! */
2420 if(timer_pending(&(self->watchdog)))
2421 del_timer(&(self->watchdog));
2422
2423 IRDA_DEBUG(1, "%s(), ...waking up !\n", __FUNCTION__);
2424
2425 if (ret != 0)
2426 return ret;
2427 }
2428 else
2429 IRDA_DEBUG(1, "%s(), found immediately !\n",
2430 __FUNCTION__);
2431
2432 /* Tell IrLMP that we have been notified */
2433 irlmp_update_client(self->ckey, self->mask.word,
2434 NULL, NULL, NULL);
2435
2436 /* Check if the we got some results */
2437 if (!self->cachedaddr)
2438 return -EAGAIN; /* Didn't find any devices */
2439 daddr = self->cachedaddr;
2440 /* Cleanup */
2441 self->cachedaddr = 0;
2442
2443 /* We return the daddr of the device that trigger the
2444 * wakeup. As irlmp pass us only the new devices, we
2445 * are sure that it's not an old device.
2446 * If the user want more details, he should query
2447 * the whole discovery log and pick one device...
2448 */
2449 if (put_user(daddr, (int __user *)optval))
2450 return -EFAULT;
2451
2452 break;
2453 default:
2454 return -ENOPROTOOPT;
2455 }
2456
2457 return 0;
2458}
2459
2460static struct net_proto_family irda_family_ops = {
2461 .family = PF_IRDA,
2462 .create = irda_create,
2463 .owner = THIS_MODULE,
2464};
2465
2466static struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
2467 .family = PF_IRDA,
2468 .owner = THIS_MODULE,
2469 .release = irda_release,
2470 .bind = irda_bind,
2471 .connect = irda_connect,
2472 .socketpair = sock_no_socketpair,
2473 .accept = irda_accept,
2474 .getname = irda_getname,
2475 .poll = irda_poll,
2476 .ioctl = irda_ioctl,
2477 .listen = irda_listen,
2478 .shutdown = irda_shutdown,
2479 .setsockopt = irda_setsockopt,
2480 .getsockopt = irda_getsockopt,
2481 .sendmsg = irda_sendmsg,
2482 .recvmsg = irda_recvmsg_stream,
2483 .mmap = sock_no_mmap,
2484 .sendpage = sock_no_sendpage,
2485};
2486
2487static struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
2488 .family = PF_IRDA,
2489 .owner = THIS_MODULE,
2490 .release = irda_release,
2491 .bind = irda_bind,
2492 .connect = irda_connect,
2493 .socketpair = sock_no_socketpair,
2494 .accept = irda_accept,
2495 .getname = irda_getname,
2496 .poll = datagram_poll,
2497 .ioctl = irda_ioctl,
2498 .listen = irda_listen,
2499 .shutdown = irda_shutdown,
2500 .setsockopt = irda_setsockopt,
2501 .getsockopt = irda_getsockopt,
2502 .sendmsg = irda_sendmsg,
2503 .recvmsg = irda_recvmsg_dgram,
2504 .mmap = sock_no_mmap,
2505 .sendpage = sock_no_sendpage,
2506};
2507
2508static struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
2509 .family = PF_IRDA,
2510 .owner = THIS_MODULE,
2511 .release = irda_release,
2512 .bind = irda_bind,
2513 .connect = irda_connect,
2514 .socketpair = sock_no_socketpair,
2515 .accept = irda_accept,
2516 .getname = irda_getname,
2517 .poll = datagram_poll,
2518 .ioctl = irda_ioctl,
2519 .listen = irda_listen,
2520 .shutdown = irda_shutdown,
2521 .setsockopt = irda_setsockopt,
2522 .getsockopt = irda_getsockopt,
2523 .sendmsg = irda_sendmsg_dgram,
2524 .recvmsg = irda_recvmsg_dgram,
2525 .mmap = sock_no_mmap,
2526 .sendpage = sock_no_sendpage,
2527};
2528
2529#ifdef CONFIG_IRDA_ULTRA
2530static struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
2531 .family = PF_IRDA,
2532 .owner = THIS_MODULE,
2533 .release = irda_release,
2534 .bind = irda_bind,
2535 .connect = sock_no_connect,
2536 .socketpair = sock_no_socketpair,
2537 .accept = sock_no_accept,
2538 .getname = irda_getname,
2539 .poll = datagram_poll,
2540 .ioctl = irda_ioctl,
2541 .listen = sock_no_listen,
2542 .shutdown = irda_shutdown,
2543 .setsockopt = irda_setsockopt,
2544 .getsockopt = irda_getsockopt,
2545 .sendmsg = irda_sendmsg_ultra,
2546 .recvmsg = irda_recvmsg_dgram,
2547 .mmap = sock_no_mmap,
2548 .sendpage = sock_no_sendpage,
2549};
2550#endif /* CONFIG_IRDA_ULTRA */
2551
2552#include <linux/smp_lock.h>
2553SOCKOPS_WRAP(irda_stream, PF_IRDA);
2554SOCKOPS_WRAP(irda_seqpacket, PF_IRDA);
2555SOCKOPS_WRAP(irda_dgram, PF_IRDA);
2556#ifdef CONFIG_IRDA_ULTRA
2557SOCKOPS_WRAP(irda_ultra, PF_IRDA);
2558#endif /* CONFIG_IRDA_ULTRA */
2559
2560/*
2561 * Function irsock_init (pro)
2562 *
2563 * Initialize IrDA protocol
2564 *
2565 */
2566int __init irsock_init(void)
2567{
2568 int rc = proto_register(&irda_proto, 0);
2569
2570 if (rc == 0)
2571 rc = sock_register(&irda_family_ops);
2572
2573 return rc;
2574}
2575
2576/*
2577 * Function irsock_cleanup (void)
2578 *
2579 * Remove IrDA protocol
2580 *
2581 */
2582void __exit irsock_cleanup(void)
2583{
2584 sock_unregister(PF_IRDA);
2585 proto_unregister(&irda_proto);
2586}
diff --git a/net/irda/discovery.c b/net/irda/discovery.c
new file mode 100644
index 00000000000..c4ba5fa1446
--- /dev/null
+++ b/net/irda/discovery.c
@@ -0,0 +1,419 @@
1/*********************************************************************
2 *
3 * Filename: discovery.c
4 * Version: 0.1
5 * Description: Routines for handling discoveries at the IrLMP layer
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Tue Apr 6 15:33:50 1999
9 * Modified at: Sat Oct 9 17:11:31 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 * Modified at: Fri May 28 3:11 CST 1999
12 * Modified by: Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
13 *
14 * Copyright (c) 1999 Dag Brattli, All Rights Reserved.
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 * MA 02111-1307 USA
30 *
31 ********************************************************************/
32
33#include <linux/string.h>
34#include <linux/socket.h>
35#include <linux/seq_file.h>
36
37#include <net/irda/irda.h>
38#include <net/irda/irlmp.h>
39
40#include <net/irda/discovery.h>
41
42/*
43 * Function irlmp_add_discovery (cachelog, discovery)
44 *
45 * Add a new discovery to the cachelog, and remove any old discoveries
46 * from the same device
47 *
48 * Note : we try to preserve the time this device was *first* discovered
49 * (as opposed to the time of last discovery used for cleanup). This is
50 * used by clients waiting for discovery events to tell if the device
51 * discovered is "new" or just the same old one. They can't rely there
52 * on a binary flag (new/old), because not all discovery events are
53 * propagated to them, and they might not always listen, so they would
54 * miss some new devices popping up...
55 * Jean II
56 */
57void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *new)
58{
59 discovery_t *discovery, *node;
60 unsigned long flags;
61
62 /* Set time of first discovery if node is new (see below) */
63 new->firststamp = new->timestamp;
64
65 spin_lock_irqsave(&cachelog->hb_spinlock, flags);
66
67 /*
68 * Remove all discoveries of devices that has previously been
69 * discovered on the same link with the same name (info), or the
70 * same daddr. We do this since some devices (mostly PDAs) change
71 * their device address between every discovery.
72 */
73 discovery = (discovery_t *) hashbin_get_first(cachelog);
74 while (discovery != NULL ) {
75 node = discovery;
76
77 /* Be sure to stay one item ahead */
78 discovery = (discovery_t *) hashbin_get_next(cachelog);
79
80 if ((node->data.saddr == new->data.saddr) &&
81 ((node->data.daddr == new->data.daddr) ||
82 (strcmp(node->data.info, new->data.info) == 0)))
83 {
84 /* This discovery is a previous discovery
85 * from the same device, so just remove it
86 */
87 hashbin_remove_this(cachelog, (irda_queue_t *) node);
88 /* Check if hints bits are unchanged */
89 if(u16ho(node->data.hints) == u16ho(new->data.hints))
90 /* Set time of first discovery for this node */
91 new->firststamp = node->firststamp;
92 kfree(node);
93 }
94 }
95
96 /* Insert the new and updated version */
97 hashbin_insert(cachelog, (irda_queue_t *) new, new->data.daddr, NULL);
98
99 spin_unlock_irqrestore(&cachelog->hb_spinlock, flags);
100}
101
102/*
103 * Function irlmp_add_discovery_log (cachelog, log)
104 *
105 * Merge a disovery log into the cachelog.
106 *
107 */
108void irlmp_add_discovery_log(hashbin_t *cachelog, hashbin_t *log)
109{
110 discovery_t *discovery;
111
112 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
113
114 /*
115 * If log is missing this means that IrLAP was unable to perform the
116 * discovery, so restart discovery again with just the half timeout
117 * of the normal one.
118 */
119 /* Well... It means that there was nobody out there - Jean II */
120 if (log == NULL) {
121 /* irlmp_start_discovery_timer(irlmp, 150); */
122 return;
123 }
124
125 /*
126 * Locking : we are the only owner of this discovery log, so
127 * no need to lock it.
128 * We just need to lock the global log in irlmp_add_discovery().
129 */
130 discovery = (discovery_t *) hashbin_remove_first(log);
131 while (discovery != NULL) {
132 irlmp_add_discovery(cachelog, discovery);
133
134 discovery = (discovery_t *) hashbin_remove_first(log);
135 }
136
137 /* Delete the now empty log */
138 hashbin_delete(log, (FREE_FUNC) kfree);
139}
140
141/*
142 * Function irlmp_expire_discoveries (log, saddr, force)
143 *
144 * Go through all discoveries and expire all that has stayed too long
145 *
146 * Note : this assume that IrLAP won't change its saddr, which
147 * currently is a valid assumption...
148 */
149void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force)
150{
151 discovery_t * discovery;
152 discovery_t * curr;
153 unsigned long flags;
154 discinfo_t * buffer = NULL;
155 int n; /* Size of the full log */
156 int i = 0; /* How many we expired */
157
158 IRDA_ASSERT(log != NULL, return;);
159 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
160
161 spin_lock_irqsave(&log->hb_spinlock, flags);
162
163 discovery = (discovery_t *) hashbin_get_first(log);
164 while (discovery != NULL) {
165 /* Be sure to be one item ahead */
166 curr = discovery;
167 discovery = (discovery_t *) hashbin_get_next(log);
168
169 /* Test if it's time to expire this discovery */
170 if ((curr->data.saddr == saddr) &&
171 (force ||
172 ((jiffies - curr->timestamp) > DISCOVERY_EXPIRE_TIMEOUT)))
173 {
174 /* Create buffer as needed.
175 * As this function get called a lot and most time
176 * we don't have anything to put in the log (we are
177 * quite picky), we can save a lot of overhead
178 * by not calling kmalloc. Jean II */
179 if(buffer == NULL) {
180 /* Create the client specific buffer */
181 n = HASHBIN_GET_SIZE(log);
182 buffer = kmalloc(n * sizeof(struct irda_device_info), GFP_ATOMIC);
183 if (buffer == NULL) {
184 spin_unlock_irqrestore(&log->hb_spinlock, flags);
185 return;
186 }
187
188 }
189
190 /* Copy discovery information */
191 memcpy(&(buffer[i]), &(curr->data),
192 sizeof(discinfo_t));
193 i++;
194
195 /* Remove it from the log */
196 curr = hashbin_remove_this(log, (irda_queue_t *) curr);
197 if (curr)
198 kfree(curr);
199 }
200 }
201
202 /* Drop the spinlock before calling the higher layers, as
203 * we can't guarantee they won't call us back and create a
204 * deadlock. We will work on our own private data, so we
205 * don't care to be interupted. - Jean II */
206 spin_unlock_irqrestore(&log->hb_spinlock, flags);
207
208 if(buffer == NULL)
209 return;
210
211 /* Tell IrLMP and registered clients about it */
212 irlmp_discovery_expiry(buffer, i);
213
214 /* Free up our buffer */
215 kfree(buffer);
216}
217
218#if 0
219/*
220 * Function irlmp_dump_discoveries (log)
221 *
222 * Print out all discoveries in log
223 *
224 */
225void irlmp_dump_discoveries(hashbin_t *log)
226{
227 discovery_t *discovery;
228
229 IRDA_ASSERT(log != NULL, return;);
230
231 discovery = (discovery_t *) hashbin_get_first(log);
232 while (discovery != NULL) {
233 IRDA_DEBUG(0, "Discovery:\n");
234 IRDA_DEBUG(0, " daddr=%08x\n", discovery->data.daddr);
235 IRDA_DEBUG(0, " saddr=%08x\n", discovery->data.saddr);
236 IRDA_DEBUG(0, " nickname=%s\n", discovery->data.info);
237
238 discovery = (discovery_t *) hashbin_get_next(log);
239 }
240}
241#endif
242
243/*
244 * Function irlmp_copy_discoveries (log, pn, mask)
245 *
246 * Copy all discoveries in a buffer
247 *
248 * This function implement a safe way for lmp clients to access the
249 * discovery log. The basic problem is that we don't want the log
250 * to change (add/remove) while the client is reading it. If the
251 * lmp client manipulate directly the hashbin, he is sure to get
252 * into troubles...
253 * The idea is that we copy all the current discovery log in a buffer
254 * which is specific to the client and pass this copy to him. As we
255 * do this operation with the spinlock grabbed, we are safe...
256 * Note : we don't want those clients to grab the spinlock, because
257 * we have no control on how long they will hold it...
258 * Note : we choose to copy the log in "struct irda_device_info" to
259 * save space...
260 * Note : the client must kfree himself() the log...
261 * Jean II
262 */
263struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn,
264 __u16 mask, int old_entries)
265{
266 discovery_t * discovery;
267 unsigned long flags;
268 discinfo_t * buffer = NULL;
269 int j_timeout = (sysctl_discovery_timeout * HZ);
270 int n; /* Size of the full log */
271 int i = 0; /* How many we picked */
272
273 IRDA_ASSERT(pn != NULL, return NULL;);
274 IRDA_ASSERT(log != NULL, return NULL;);
275
276 /* Save spin lock */
277 spin_lock_irqsave(&log->hb_spinlock, flags);
278
279 discovery = (discovery_t *) hashbin_get_first(log);
280 while (discovery != NULL) {
281 /* Mask out the ones we don't want :
282 * We want to match the discovery mask, and to get only
283 * the most recent one (unless we want old ones) */
284 if ((u16ho(discovery->data.hints) & mask) &&
285 ((old_entries) ||
286 ((jiffies - discovery->firststamp) < j_timeout)) ) {
287 /* Create buffer as needed.
288 * As this function get called a lot and most time
289 * we don't have anything to put in the log (we are
290 * quite picky), we can save a lot of overhead
291 * by not calling kmalloc. Jean II */
292 if(buffer == NULL) {
293 /* Create the client specific buffer */
294 n = HASHBIN_GET_SIZE(log);
295 buffer = kmalloc(n * sizeof(struct irda_device_info), GFP_ATOMIC);
296 if (buffer == NULL) {
297 spin_unlock_irqrestore(&log->hb_spinlock, flags);
298 return NULL;
299 }
300
301 }
302
303 /* Copy discovery information */
304 memcpy(&(buffer[i]), &(discovery->data),
305 sizeof(discinfo_t));
306 i++;
307 }
308 discovery = (discovery_t *) hashbin_get_next(log);
309 }
310
311 spin_unlock_irqrestore(&log->hb_spinlock, flags);
312
313 /* Get the actual number of device in the buffer and return */
314 *pn = i;
315 return(buffer);
316}
317
318#ifdef CONFIG_PROC_FS
319static inline discovery_t *discovery_seq_idx(loff_t pos)
320
321{
322 discovery_t *discovery;
323
324 for (discovery = (discovery_t *) hashbin_get_first(irlmp->cachelog);
325 discovery != NULL;
326 discovery = (discovery_t *) hashbin_get_next(irlmp->cachelog)) {
327 if (pos-- == 0)
328 break;
329 }
330
331 return discovery;
332}
333
334static void *discovery_seq_start(struct seq_file *seq, loff_t *pos)
335{
336 spin_lock_irq(&irlmp->cachelog->hb_spinlock);
337 return *pos ? discovery_seq_idx(*pos - 1) : SEQ_START_TOKEN;
338}
339
340static void *discovery_seq_next(struct seq_file *seq, void *v, loff_t *pos)
341{
342 ++*pos;
343 return (v == SEQ_START_TOKEN)
344 ? (void *) hashbin_get_first(irlmp->cachelog)
345 : (void *) hashbin_get_next(irlmp->cachelog);
346}
347
348static void discovery_seq_stop(struct seq_file *seq, void *v)
349{
350 spin_unlock_irq(&irlmp->cachelog->hb_spinlock);
351}
352
353static int discovery_seq_show(struct seq_file *seq, void *v)
354{
355 if (v == SEQ_START_TOKEN)
356 seq_puts(seq, "IrLMP: Discovery log:\n\n");
357 else {
358 const discovery_t *discovery = v;
359
360 seq_printf(seq, "nickname: %s, hint: 0x%02x%02x",
361 discovery->data.info,
362 discovery->data.hints[0],
363 discovery->data.hints[1]);
364#if 0
365 if ( discovery->data.hints[0] & HINT_PNP)
366 seq_puts(seq, "PnP Compatible ");
367 if ( discovery->data.hints[0] & HINT_PDA)
368 seq_puts(seq, "PDA/Palmtop ");
369 if ( discovery->data.hints[0] & HINT_COMPUTER)
370 seq_puts(seq, "Computer ");
371 if ( discovery->data.hints[0] & HINT_PRINTER)
372 seq_puts(seq, "Printer ");
373 if ( discovery->data.hints[0] & HINT_MODEM)
374 seq_puts(seq, "Modem ");
375 if ( discovery->data.hints[0] & HINT_FAX)
376 seq_puts(seq, "Fax ");
377 if ( discovery->data.hints[0] & HINT_LAN)
378 seq_puts(seq, "LAN Access ");
379
380 if ( discovery->data.hints[1] & HINT_TELEPHONY)
381 seq_puts(seq, "Telephony ");
382 if ( discovery->data.hints[1] & HINT_FILE_SERVER)
383 seq_puts(seq, "File Server ");
384 if ( discovery->data.hints[1] & HINT_COMM)
385 seq_puts(seq, "IrCOMM ");
386 if ( discovery->data.hints[1] & HINT_OBEX)
387 seq_puts(seq, "IrOBEX ");
388#endif
389 seq_printf(seq,", saddr: 0x%08x, daddr: 0x%08x\n\n",
390 discovery->data.saddr,
391 discovery->data.daddr);
392
393 seq_putc(seq, '\n');
394 }
395 return 0;
396}
397
398static struct seq_operations discovery_seq_ops = {
399 .start = discovery_seq_start,
400 .next = discovery_seq_next,
401 .stop = discovery_seq_stop,
402 .show = discovery_seq_show,
403};
404
405static int discovery_seq_open(struct inode *inode, struct file *file)
406{
407 IRDA_ASSERT(irlmp != NULL, return -EINVAL;);
408
409 return seq_open(file, &discovery_seq_ops);
410}
411
412struct file_operations discovery_seq_fops = {
413 .owner = THIS_MODULE,
414 .open = discovery_seq_open,
415 .read = seq_read,
416 .llseek = seq_lseek,
417 .release = seq_release,
418};
419#endif
diff --git a/net/irda/ircomm/Kconfig b/net/irda/ircomm/Kconfig
new file mode 100644
index 00000000000..2d4c6b4a78d
--- /dev/null
+++ b/net/irda/ircomm/Kconfig
@@ -0,0 +1,12 @@
1config IRCOMM
2 tristate "IrCOMM protocol"
3 depends on IRDA
4 help
5 Say Y here if you want to build support for the IrCOMM protocol.
6 To compile it as modules, choose M here: the modules will be
7 called ircomm and ircomm_tty.
8 IrCOMM implements serial port emulation, and makes it possible to
9 use all existing applications that understands TTY's with an
10 infrared link. Thus you should be able to use application like PPP,
11 minicom and others.
12
diff --git a/net/irda/ircomm/Makefile b/net/irda/ircomm/Makefile
new file mode 100644
index 00000000000..48689458c08
--- /dev/null
+++ b/net/irda/ircomm/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for the Linux IrDA IrCOMM protocol layer.
3#
4
5obj-$(CONFIG_IRCOMM) += ircomm.o ircomm-tty.o
6
7ircomm-objs := ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o
8ircomm-tty-objs := ircomm_tty.o ircomm_tty_attach.o ircomm_tty_ioctl.o ircomm_param.o
diff --git a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c
new file mode 100644
index 00000000000..28688197885
--- /dev/null
+++ b/net/irda/ircomm/ircomm_core.c
@@ -0,0 +1,587 @@
1/*********************************************************************
2 *
3 * Filename: ircomm_core.c
4 * Version: 1.0
5 * Description: IrCOMM service interface
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Jun 6 20:37:34 1999
9 * Modified at: Tue Dec 21 13:26:41 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1999 Dag Brattli, All Rights Reserved.
13 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 * MA 02111-1307 USA
29 *
30 ********************************************************************/
31
32#include <linux/config.h>
33#include <linux/module.h>
34#include <linux/sched.h>
35#include <linux/proc_fs.h>
36#include <linux/seq_file.h>
37#include <linux/init.h>
38
39#include <net/irda/irda.h>
40#include <net/irda/irmod.h>
41#include <net/irda/irlmp.h>
42#include <net/irda/iriap.h>
43#include <net/irda/irttp.h>
44#include <net/irda/irias_object.h>
45
46#include <net/irda/ircomm_event.h>
47#include <net/irda/ircomm_lmp.h>
48#include <net/irda/ircomm_ttp.h>
49#include <net/irda/ircomm_param.h>
50#include <net/irda/ircomm_core.h>
51
52static int __ircomm_close(struct ircomm_cb *self);
53static void ircomm_control_indication(struct ircomm_cb *self,
54 struct sk_buff *skb, int clen);
55
56#ifdef CONFIG_PROC_FS
57extern struct proc_dir_entry *proc_irda;
58static int ircomm_seq_open(struct inode *, struct file *);
59
60static struct file_operations ircomm_proc_fops = {
61 .owner = THIS_MODULE,
62 .open = ircomm_seq_open,
63 .read = seq_read,
64 .llseek = seq_lseek,
65 .release = seq_release,
66};
67#endif /* CONFIG_PROC_FS */
68
69hashbin_t *ircomm = NULL;
70
71static int __init ircomm_init(void)
72{
73 ircomm = hashbin_new(HB_LOCK);
74 if (ircomm == NULL) {
75 IRDA_ERROR("%s(), can't allocate hashbin!\n", __FUNCTION__);
76 return -ENOMEM;
77 }
78
79#ifdef CONFIG_PROC_FS
80 { struct proc_dir_entry *ent;
81 ent = create_proc_entry("ircomm", 0, proc_irda);
82 if (ent)
83 ent->proc_fops = &ircomm_proc_fops;
84 }
85#endif /* CONFIG_PROC_FS */
86
87 IRDA_MESSAGE("IrCOMM protocol (Dag Brattli)\n");
88
89 return 0;
90}
91
92static void __exit ircomm_cleanup(void)
93{
94 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
95
96 hashbin_delete(ircomm, (FREE_FUNC) __ircomm_close);
97
98#ifdef CONFIG_PROC_FS
99 remove_proc_entry("ircomm", proc_irda);
100#endif /* CONFIG_PROC_FS */
101}
102
103/*
104 * Function ircomm_open (client_notify)
105 *
106 * Start a new IrCOMM instance
107 *
108 */
109struct ircomm_cb *ircomm_open(notify_t *notify, __u8 service_type, int line)
110{
111 struct ircomm_cb *self = NULL;
112 int ret;
113
114 IRDA_DEBUG(2, "%s(), service_type=0x%02x\n", __FUNCTION__ ,
115 service_type);
116
117 IRDA_ASSERT(ircomm != NULL, return NULL;);
118
119 self = kmalloc(sizeof(struct ircomm_cb), GFP_ATOMIC);
120 if (self == NULL)
121 return NULL;
122
123 memset(self, 0, sizeof(struct ircomm_cb));
124
125 self->notify = *notify;
126 self->magic = IRCOMM_MAGIC;
127
128 /* Check if we should use IrLMP or IrTTP */
129 if (service_type & IRCOMM_3_WIRE_RAW) {
130 self->flow_status = FLOW_START;
131 ret = ircomm_open_lsap(self);
132 } else
133 ret = ircomm_open_tsap(self);
134
135 if (ret < 0) {
136 kfree(self);
137 return NULL;
138 }
139
140 self->service_type = service_type;
141 self->line = line;
142
143 hashbin_insert(ircomm, (irda_queue_t *) self, line, NULL);
144
145 ircomm_next_state(self, IRCOMM_IDLE);
146
147 return self;
148}
149
150EXPORT_SYMBOL(ircomm_open);
151
152/*
153 * Function ircomm_close_instance (self)
154 *
155 * Remove IrCOMM instance
156 *
157 */
158static int __ircomm_close(struct ircomm_cb *self)
159{
160 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
161
162 /* Disconnect link if any */
163 ircomm_do_event(self, IRCOMM_DISCONNECT_REQUEST, NULL, NULL);
164
165 /* Remove TSAP */
166 if (self->tsap) {
167 irttp_close_tsap(self->tsap);
168 self->tsap = NULL;
169 }
170
171 /* Remove LSAP */
172 if (self->lsap) {
173 irlmp_close_lsap(self->lsap);
174 self->lsap = NULL;
175 }
176 self->magic = 0;
177
178 kfree(self);
179
180 return 0;
181}
182
183/*
184 * Function ircomm_close (self)
185 *
186 * Closes and removes the specified IrCOMM instance
187 *
188 */
189int ircomm_close(struct ircomm_cb *self)
190{
191 struct ircomm_cb *entry;
192
193 IRDA_ASSERT(self != NULL, return -EIO;);
194 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return -EIO;);
195
196 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
197
198 entry = hashbin_remove(ircomm, self->line, NULL);
199
200 IRDA_ASSERT(entry == self, return -1;);
201
202 return __ircomm_close(self);
203}
204
205EXPORT_SYMBOL(ircomm_close);
206
207/*
208 * Function ircomm_connect_request (self, service_type)
209 *
210 * Impl. of this function is differ from one of the reference. This
211 * function does discovery as well as sending connect request
212 *
213 */
214int ircomm_connect_request(struct ircomm_cb *self, __u8 dlsap_sel,
215 __u32 saddr, __u32 daddr, struct sk_buff *skb,
216 __u8 service_type)
217{
218 struct ircomm_info info;
219 int ret;
220
221 IRDA_DEBUG(2 , "%s()\n", __FUNCTION__ );
222
223 IRDA_ASSERT(self != NULL, return -1;);
224 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
225
226 self->service_type= service_type;
227
228 info.dlsap_sel = dlsap_sel;
229 info.saddr = saddr;
230 info.daddr = daddr;
231
232 ret = ircomm_do_event(self, IRCOMM_CONNECT_REQUEST, skb, &info);
233
234 return ret;
235}
236
237EXPORT_SYMBOL(ircomm_connect_request);
238
239/*
240 * Function ircomm_connect_indication (self, qos, skb)
241 *
242 * Notify user layer about the incoming connection
243 *
244 */
245void ircomm_connect_indication(struct ircomm_cb *self, struct sk_buff *skb,
246 struct ircomm_info *info)
247{
248 int clen = 0;
249
250 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
251
252 /* Check if the packet contains data on the control channel */
253 if (skb->len > 0)
254 clen = skb->data[0];
255
256 /*
257 * If there are any data hiding in the control channel, we must
258 * deliver it first. The side effect is that the control channel
259 * will be removed from the skb
260 */
261 if (self->notify.connect_indication)
262 self->notify.connect_indication(self->notify.instance, self,
263 info->qos, info->max_data_size,
264 info->max_header_size, skb);
265 else {
266 IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ );
267 }
268}
269
270/*
271 * Function ircomm_connect_response (self, userdata, max_sdu_size)
272 *
273 * User accepts connection
274 *
275 */
276int ircomm_connect_response(struct ircomm_cb *self, struct sk_buff *userdata)
277{
278 int ret;
279
280 IRDA_ASSERT(self != NULL, return -1;);
281 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
282
283 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
284
285 ret = ircomm_do_event(self, IRCOMM_CONNECT_RESPONSE, userdata, NULL);
286
287 return ret;
288}
289
290EXPORT_SYMBOL(ircomm_connect_response);
291
292/*
293 * Function connect_confirm (self, skb)
294 *
295 * Notify user layer that the link is now connected
296 *
297 */
298void ircomm_connect_confirm(struct ircomm_cb *self, struct sk_buff *skb,
299 struct ircomm_info *info)
300{
301 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
302
303 if (self->notify.connect_confirm )
304 self->notify.connect_confirm(self->notify.instance,
305 self, info->qos,
306 info->max_data_size,
307 info->max_header_size, skb);
308 else {
309 IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ );
310 }
311}
312
313/*
314 * Function ircomm_data_request (self, userdata)
315 *
316 * Send IrCOMM data to peer device
317 *
318 */
319int ircomm_data_request(struct ircomm_cb *self, struct sk_buff *skb)
320{
321 int ret;
322
323 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
324
325 IRDA_ASSERT(self != NULL, return -EFAULT;);
326 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return -EFAULT;);
327 IRDA_ASSERT(skb != NULL, return -EFAULT;);
328
329 ret = ircomm_do_event(self, IRCOMM_DATA_REQUEST, skb, NULL);
330
331 return ret;
332}
333
334EXPORT_SYMBOL(ircomm_data_request);
335
336/*
337 * Function ircomm_data_indication (self, skb)
338 *
339 * Data arrived, so deliver it to user
340 *
341 */
342void ircomm_data_indication(struct ircomm_cb *self, struct sk_buff *skb)
343{
344 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
345
346 IRDA_ASSERT(skb->len > 0, return;);
347
348 if (self->notify.data_indication)
349 self->notify.data_indication(self->notify.instance, self, skb);
350 else {
351 IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ );
352 }
353}
354
355/*
356 * Function ircomm_process_data (self, skb)
357 *
358 * Data arrived which may contain control channel data
359 *
360 */
361void ircomm_process_data(struct ircomm_cb *self, struct sk_buff *skb)
362{
363 int clen;
364
365 IRDA_ASSERT(skb->len > 0, return;);
366
367 clen = skb->data[0];
368
369 /*
370 * If there are any data hiding in the control channel, we must
371 * deliver it first. The side effect is that the control channel
372 * will be removed from the skb
373 */
374 if (clen > 0)
375 ircomm_control_indication(self, skb, clen);
376
377 /* Remove control channel from data channel */
378 skb_pull(skb, clen+1);
379
380 if (skb->len)
381 ircomm_data_indication(self, skb);
382 else {
383 IRDA_DEBUG(4, "%s(), data was control info only!\n",
384 __FUNCTION__ );
385 }
386}
387
388/*
389 * Function ircomm_control_request (self, params)
390 *
391 * Send control data to peer device
392 *
393 */
394int ircomm_control_request(struct ircomm_cb *self, struct sk_buff *skb)
395{
396 int ret;
397
398 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
399
400 IRDA_ASSERT(self != NULL, return -EFAULT;);
401 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return -EFAULT;);
402 IRDA_ASSERT(skb != NULL, return -EFAULT;);
403
404 ret = ircomm_do_event(self, IRCOMM_CONTROL_REQUEST, skb, NULL);
405
406 return ret;
407}
408
409EXPORT_SYMBOL(ircomm_control_request);
410
411/*
412 * Function ircomm_control_indication (self, skb)
413 *
414 * Data has arrived on the control channel
415 *
416 */
417static void ircomm_control_indication(struct ircomm_cb *self,
418 struct sk_buff *skb, int clen)
419{
420 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
421
422 /* Use udata for delivering data on the control channel */
423 if (self->notify.udata_indication) {
424 struct sk_buff *ctrl_skb;
425
426 /* We don't own the skb, so clone it */
427 ctrl_skb = skb_clone(skb, GFP_ATOMIC);
428 if (!ctrl_skb)
429 return;
430
431 /* Remove data channel from control channel */
432 skb_trim(ctrl_skb, clen+1);
433
434 self->notify.udata_indication(self->notify.instance, self,
435 ctrl_skb);
436
437 /* Drop reference count -
438 * see ircomm_tty_control_indication(). */
439 dev_kfree_skb(ctrl_skb);
440 } else {
441 IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ );
442 }
443}
444
445/*
446 * Function ircomm_disconnect_request (self, userdata, priority)
447 *
448 * User layer wants to disconnect the IrCOMM connection
449 *
450 */
451int ircomm_disconnect_request(struct ircomm_cb *self, struct sk_buff *userdata)
452{
453 struct ircomm_info info;
454 int ret;
455
456 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
457
458 IRDA_ASSERT(self != NULL, return -1;);
459 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
460
461 ret = ircomm_do_event(self, IRCOMM_DISCONNECT_REQUEST, userdata,
462 &info);
463 return ret;
464}
465
466EXPORT_SYMBOL(ircomm_disconnect_request);
467
468/*
469 * Function disconnect_indication (self, skb)
470 *
471 * Tell user that the link has been disconnected
472 *
473 */
474void ircomm_disconnect_indication(struct ircomm_cb *self, struct sk_buff *skb,
475 struct ircomm_info *info)
476{
477 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
478
479 IRDA_ASSERT(info != NULL, return;);
480
481 if (self->notify.disconnect_indication) {
482 self->notify.disconnect_indication(self->notify.instance, self,
483 info->reason, skb);
484 } else {
485 IRDA_DEBUG(0, "%s(), missing handler\n", __FUNCTION__ );
486 }
487}
488
489/*
490 * Function ircomm_flow_request (self, flow)
491 *
492 *
493 *
494 */
495void ircomm_flow_request(struct ircomm_cb *self, LOCAL_FLOW flow)
496{
497 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
498
499 IRDA_ASSERT(self != NULL, return;);
500 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return;);
501
502 if (self->service_type == IRCOMM_3_WIRE_RAW)
503 return;
504
505 irttp_flow_request(self->tsap, flow);
506}
507
508EXPORT_SYMBOL(ircomm_flow_request);
509
510#ifdef CONFIG_PROC_FS
511static void *ircomm_seq_start(struct seq_file *seq, loff_t *pos)
512{
513 struct ircomm_cb *self;
514 loff_t off = 0;
515
516 spin_lock_irq(&ircomm->hb_spinlock);
517
518 for (self = (struct ircomm_cb *) hashbin_get_first(ircomm);
519 self != NULL;
520 self = (struct ircomm_cb *) hashbin_get_next(ircomm)) {
521 if (off++ == *pos)
522 break;
523
524 }
525 return self;
526}
527
528static void *ircomm_seq_next(struct seq_file *seq, void *v, loff_t *pos)
529{
530 ++*pos;
531
532 return (void *) hashbin_get_next(ircomm);
533}
534
535static void ircomm_seq_stop(struct seq_file *seq, void *v)
536{
537 spin_unlock_irq(&ircomm->hb_spinlock);
538}
539
540static int ircomm_seq_show(struct seq_file *seq, void *v)
541{
542 const struct ircomm_cb *self = v;
543
544 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return -EINVAL; );
545
546 if(self->line < 0x10)
547 seq_printf(seq, "ircomm%d", self->line);
548 else
549 seq_printf(seq, "irlpt%d", self->line - 0x10);
550
551 seq_printf(seq,
552 " state: %s, slsap_sel: %#02x, dlsap_sel: %#02x, mode:",
553 ircomm_state[ self->state],
554 self->slsap_sel, self->dlsap_sel);
555
556 if(self->service_type & IRCOMM_3_WIRE_RAW)
557 seq_printf(seq, " 3-wire-raw");
558 if(self->service_type & IRCOMM_3_WIRE)
559 seq_printf(seq, " 3-wire");
560 if(self->service_type & IRCOMM_9_WIRE)
561 seq_printf(seq, " 9-wire");
562 if(self->service_type & IRCOMM_CENTRONICS)
563 seq_printf(seq, " Centronics");
564 seq_putc(seq, '\n');
565
566 return 0;
567}
568
569static struct seq_operations ircomm_seq_ops = {
570 .start = ircomm_seq_start,
571 .next = ircomm_seq_next,
572 .stop = ircomm_seq_stop,
573 .show = ircomm_seq_show,
574};
575
576static int ircomm_seq_open(struct inode *inode, struct file *file)
577{
578 return seq_open(file, &ircomm_seq_ops);
579}
580#endif /* CONFIG_PROC_FS */
581
582MODULE_AUTHOR("Dag Brattli <dag@brattli.net>");
583MODULE_DESCRIPTION("IrCOMM protocol");
584MODULE_LICENSE("GPL");
585
586module_init(ircomm_init);
587module_exit(ircomm_cleanup);
diff --git a/net/irda/ircomm/ircomm_event.c b/net/irda/ircomm/ircomm_event.c
new file mode 100644
index 00000000000..01f4e801a1b
--- /dev/null
+++ b/net/irda/ircomm/ircomm_event.c
@@ -0,0 +1,251 @@
1/*********************************************************************
2 *
3 * Filename: ircomm_event.c
4 * Version: 1.0
5 * Description: IrCOMM layer state machine
6 * Status: Stable
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Jun 6 20:33:11 1999
9 * Modified at: Sun Dec 12 13:44:32 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1999 Dag Brattli, All Rights Reserved.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 * MA 02111-1307 USA
28 *
29 ********************************************************************/
30
31#include <linux/sched.h>
32#include <linux/proc_fs.h>
33#include <linux/init.h>
34
35#include <net/irda/irda.h>
36#include <net/irda/irlmp.h>
37#include <net/irda/iriap.h>
38#include <net/irda/irttp.h>
39#include <net/irda/irias_object.h>
40
41#include <net/irda/ircomm_core.h>
42#include <net/irda/ircomm_event.h>
43
44static int ircomm_state_idle(struct ircomm_cb *self, IRCOMM_EVENT event,
45 struct sk_buff *skb, struct ircomm_info *info);
46static int ircomm_state_waiti(struct ircomm_cb *self, IRCOMM_EVENT event,
47 struct sk_buff *skb, struct ircomm_info *info);
48static int ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event,
49 struct sk_buff *skb, struct ircomm_info *info);
50static int ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event,
51 struct sk_buff *skb, struct ircomm_info *info);
52
53char *ircomm_state[] = {
54 "IRCOMM_IDLE",
55 "IRCOMM_WAITI",
56 "IRCOMM_WAITR",
57 "IRCOMM_CONN",
58};
59
60#ifdef CONFIG_IRDA_DEBUG
61static char *ircomm_event[] = {
62 "IRCOMM_CONNECT_REQUEST",
63 "IRCOMM_CONNECT_RESPONSE",
64 "IRCOMM_TTP_CONNECT_INDICATION",
65 "IRCOMM_LMP_CONNECT_INDICATION",
66 "IRCOMM_TTP_CONNECT_CONFIRM",
67 "IRCOMM_LMP_CONNECT_CONFIRM",
68
69 "IRCOMM_LMP_DISCONNECT_INDICATION",
70 "IRCOMM_TTP_DISCONNECT_INDICATION",
71 "IRCOMM_DISCONNECT_REQUEST",
72
73 "IRCOMM_TTP_DATA_INDICATION",
74 "IRCOMM_LMP_DATA_INDICATION",
75 "IRCOMM_DATA_REQUEST",
76 "IRCOMM_CONTROL_REQUEST",
77 "IRCOMM_CONTROL_INDICATION",
78};
79#endif /* CONFIG_IRDA_DEBUG */
80
81static int (*state[])(struct ircomm_cb *self, IRCOMM_EVENT event,
82 struct sk_buff *skb, struct ircomm_info *info) =
83{
84 ircomm_state_idle,
85 ircomm_state_waiti,
86 ircomm_state_waitr,
87 ircomm_state_conn,
88};
89
90/*
91 * Function ircomm_state_idle (self, event, skb)
92 *
93 * IrCOMM is currently idle
94 *
95 */
96static int ircomm_state_idle(struct ircomm_cb *self, IRCOMM_EVENT event,
97 struct sk_buff *skb, struct ircomm_info *info)
98{
99 int ret = 0;
100
101 switch (event) {
102 case IRCOMM_CONNECT_REQUEST:
103 ircomm_next_state(self, IRCOMM_WAITI);
104 ret = self->issue.connect_request(self, skb, info);
105 break;
106 case IRCOMM_TTP_CONNECT_INDICATION:
107 case IRCOMM_LMP_CONNECT_INDICATION:
108 ircomm_next_state(self, IRCOMM_WAITR);
109 ircomm_connect_indication(self, skb, info);
110 break;
111 default:
112 IRDA_DEBUG(4, "%s(), unknown event: %s\n", __FUNCTION__ ,
113 ircomm_event[event]);
114 ret = -EINVAL;
115 }
116 return ret;
117}
118
119/*
120 * Function ircomm_state_waiti (self, event, skb)
121 *
122 * The IrCOMM user has requested an IrCOMM connection to the remote
123 * device and is awaiting confirmation
124 */
125static int ircomm_state_waiti(struct ircomm_cb *self, IRCOMM_EVENT event,
126 struct sk_buff *skb, struct ircomm_info *info)
127{
128 int ret = 0;
129
130 switch (event) {
131 case IRCOMM_TTP_CONNECT_CONFIRM:
132 case IRCOMM_LMP_CONNECT_CONFIRM:
133 ircomm_next_state(self, IRCOMM_CONN);
134 ircomm_connect_confirm(self, skb, info);
135 break;
136 case IRCOMM_TTP_DISCONNECT_INDICATION:
137 case IRCOMM_LMP_DISCONNECT_INDICATION:
138 ircomm_next_state(self, IRCOMM_IDLE);
139 ircomm_disconnect_indication(self, skb, info);
140 break;
141 default:
142 IRDA_DEBUG(0, "%s(), unknown event: %s\n", __FUNCTION__ ,
143 ircomm_event[event]);
144 ret = -EINVAL;
145 }
146 return ret;
147}
148
149/*
150 * Function ircomm_state_waitr (self, event, skb)
151 *
152 * IrCOMM has received an incoming connection request and is awaiting
153 * response from the user
154 */
155static int ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event,
156 struct sk_buff *skb, struct ircomm_info *info)
157{
158 int ret = 0;
159
160 switch (event) {
161 case IRCOMM_CONNECT_RESPONSE:
162 ircomm_next_state(self, IRCOMM_CONN);
163 ret = self->issue.connect_response(self, skb);
164 break;
165 case IRCOMM_DISCONNECT_REQUEST:
166 ircomm_next_state(self, IRCOMM_IDLE);
167 ret = self->issue.disconnect_request(self, skb, info);
168 break;
169 case IRCOMM_TTP_DISCONNECT_INDICATION:
170 case IRCOMM_LMP_DISCONNECT_INDICATION:
171 ircomm_next_state(self, IRCOMM_IDLE);
172 ircomm_disconnect_indication(self, skb, info);
173 break;
174 default:
175 IRDA_DEBUG(0, "%s(), unknown event = %s\n", __FUNCTION__ ,
176 ircomm_event[event]);
177 ret = -EINVAL;
178 }
179 return ret;
180}
181
182/*
183 * Function ircomm_state_conn (self, event, skb)
184 *
185 * IrCOMM is connected to the peer IrCOMM device
186 *
187 */
188static int ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event,
189 struct sk_buff *skb, struct ircomm_info *info)
190{
191 int ret = 0;
192
193 switch (event) {
194 case IRCOMM_DATA_REQUEST:
195 ret = self->issue.data_request(self, skb, 0);
196 break;
197 case IRCOMM_TTP_DATA_INDICATION:
198 ircomm_process_data(self, skb);
199 break;
200 case IRCOMM_LMP_DATA_INDICATION:
201 ircomm_data_indication(self, skb);
202 break;
203 case IRCOMM_CONTROL_REQUEST:
204 /* Just send a separate frame for now */
205 ret = self->issue.data_request(self, skb, skb->len);
206 break;
207 case IRCOMM_TTP_DISCONNECT_INDICATION:
208 case IRCOMM_LMP_DISCONNECT_INDICATION:
209 ircomm_next_state(self, IRCOMM_IDLE);
210 ircomm_disconnect_indication(self, skb, info);
211 break;
212 case IRCOMM_DISCONNECT_REQUEST:
213 ircomm_next_state(self, IRCOMM_IDLE);
214 ret = self->issue.disconnect_request(self, skb, info);
215 break;
216 default:
217 IRDA_DEBUG(0, "%s(), unknown event = %s\n", __FUNCTION__ ,
218 ircomm_event[event]);
219 ret = -EINVAL;
220 }
221 return ret;
222}
223
224/*
225 * Function ircomm_do_event (self, event, skb)
226 *
227 * Process event
228 *
229 */
230int ircomm_do_event(struct ircomm_cb *self, IRCOMM_EVENT event,
231 struct sk_buff *skb, struct ircomm_info *info)
232{
233 IRDA_DEBUG(4, "%s: state=%s, event=%s\n", __FUNCTION__ ,
234 ircomm_state[self->state], ircomm_event[event]);
235
236 return (*state[self->state])(self, event, skb, info);
237}
238
239/*
240 * Function ircomm_next_state (self, state)
241 *
242 * Switch state
243 *
244 */
245void ircomm_next_state(struct ircomm_cb *self, IRCOMM_STATE state)
246{
247 self->state = state;
248
249 IRDA_DEBUG(4, "%s: next state=%s, service type=%d\n", __FUNCTION__ ,
250 ircomm_state[self->state], self->service_type);
251}
diff --git a/net/irda/ircomm/ircomm_lmp.c b/net/irda/ircomm/ircomm_lmp.c
new file mode 100644
index 00000000000..d9097207aed
--- /dev/null
+++ b/net/irda/ircomm/ircomm_lmp.c
@@ -0,0 +1,372 @@
1/*********************************************************************
2 *
3 * Filename: ircomm_lmp.c
4 * Version: 1.0
5 * Description: Interface between IrCOMM and IrLMP
6 * Status: Stable
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Jun 6 20:48:27 1999
9 * Modified at: Sun Dec 12 13:44:17 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 * Sources: Previous IrLPT work by Thomas Davis
12 *
13 * Copyright (c) 1999 Dag Brattli, All Rights Reserved.
14 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 * MA 02111-1307 USA
30 *
31 ********************************************************************/
32
33#include <linux/sched.h>
34#include <linux/init.h>
35
36#include <net/irda/irda.h>
37#include <net/irda/irlmp.h>
38#include <net/irda/iriap.h>
39#include <net/irda/irda_device.h> /* struct irda_skb_cb */
40
41#include <net/irda/ircomm_event.h>
42#include <net/irda/ircomm_lmp.h>
43
44
45/*
46 * Function ircomm_lmp_connect_request (self, userdata)
47 *
48 *
49 *
50 */
51static int ircomm_lmp_connect_request(struct ircomm_cb *self,
52 struct sk_buff *userdata,
53 struct ircomm_info *info)
54{
55 int ret = 0;
56
57 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
58
59 /* Don't forget to refcount it - should be NULL anyway */
60 if(userdata)
61 skb_get(userdata);
62
63 ret = irlmp_connect_request(self->lsap, info->dlsap_sel,
64 info->saddr, info->daddr, NULL, userdata);
65 return ret;
66}
67
68/*
69 * Function ircomm_lmp_connect_response (self, skb)
70 *
71 *
72 *
73 */
74static int ircomm_lmp_connect_response(struct ircomm_cb *self,
75 struct sk_buff *userdata)
76{
77 struct sk_buff *tx_skb;
78 int ret;
79
80 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
81
82 /* Any userdata supplied? */
83 if (userdata == NULL) {
84 tx_skb = dev_alloc_skb(64);
85 if (!tx_skb)
86 return -ENOMEM;
87
88 /* Reserve space for MUX and LAP header */
89 skb_reserve(tx_skb, LMP_MAX_HEADER);
90 } else {
91 /*
92 * Check that the client has reserved enough space for
93 * headers
94 */
95 IRDA_ASSERT(skb_headroom(userdata) >= LMP_MAX_HEADER,
96 return -1;);
97
98 /* Don't forget to refcount it - should be NULL anyway */
99 skb_get(userdata);
100 tx_skb = userdata;
101 }
102
103 ret = irlmp_connect_response(self->lsap, tx_skb);
104
105 return 0;
106}
107
108static int ircomm_lmp_disconnect_request(struct ircomm_cb *self,
109 struct sk_buff *userdata,
110 struct ircomm_info *info)
111{
112 struct sk_buff *tx_skb;
113 int ret;
114
115 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
116
117 if (!userdata) {
118 tx_skb = dev_alloc_skb(64);
119 if (!tx_skb)
120 return -ENOMEM;
121
122 /* Reserve space for MUX and LAP header */
123 skb_reserve(tx_skb, LMP_MAX_HEADER);
124 userdata = tx_skb;
125 } else {
126 /* Don't forget to refcount it - should be NULL anyway */
127 skb_get(userdata);
128 }
129
130 ret = irlmp_disconnect_request(self->lsap, userdata);
131
132 return ret;
133}
134
135/*
136 * Function ircomm_lmp_flow_control (skb)
137 *
138 * This function is called when a data frame we have sent to IrLAP has
139 * been deallocated. We do this to make sure we don't flood IrLAP with
140 * frames, since we are not using the IrTTP flow control mechanism
141 */
142static void ircomm_lmp_flow_control(struct sk_buff *skb)
143{
144 struct irda_skb_cb *cb;
145 struct ircomm_cb *self;
146 int line;
147
148 IRDA_ASSERT(skb != NULL, return;);
149
150 cb = (struct irda_skb_cb *) skb->cb;
151
152 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
153
154 line = cb->line;
155
156 self = (struct ircomm_cb *) hashbin_lock_find(ircomm, line, NULL);
157 if (!self) {
158 IRDA_DEBUG(2, "%s(), didn't find myself\n", __FUNCTION__ );
159 return;
160 }
161
162 IRDA_ASSERT(self != NULL, return;);
163 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return;);
164
165 self->pkt_count--;
166
167 if ((self->pkt_count < 2) && (self->flow_status == FLOW_STOP)) {
168 IRDA_DEBUG(2, "%s(), asking TTY to start again!\n", __FUNCTION__ );
169 self->flow_status = FLOW_START;
170 if (self->notify.flow_indication)
171 self->notify.flow_indication(self->notify.instance,
172 self, FLOW_START);
173 }
174}
175
176/*
177 * Function ircomm_lmp_data_request (self, userdata)
178 *
179 * Send data frame to peer device
180 *
181 */
182static int ircomm_lmp_data_request(struct ircomm_cb *self,
183 struct sk_buff *skb,
184 int not_used)
185{
186 struct irda_skb_cb *cb;
187 int ret;
188
189 IRDA_ASSERT(skb != NULL, return -1;);
190
191 cb = (struct irda_skb_cb *) skb->cb;
192
193 cb->line = self->line;
194
195 IRDA_DEBUG(4, "%s(), sending frame\n", __FUNCTION__ );
196
197 /* Don't forget to refcount it - see ircomm_tty_do_softint() */
198 skb_get(skb);
199
200 skb->destructor = ircomm_lmp_flow_control;
201
202 if ((self->pkt_count++ > 7) && (self->flow_status == FLOW_START)) {
203 IRDA_DEBUG(2, "%s(), asking TTY to slow down!\n", __FUNCTION__ );
204 self->flow_status = FLOW_STOP;
205 if (self->notify.flow_indication)
206 self->notify.flow_indication(self->notify.instance,
207 self, FLOW_STOP);
208 }
209 ret = irlmp_data_request(self->lsap, skb);
210 if (ret) {
211 IRDA_ERROR("%s(), failed\n", __FUNCTION__);
212 /* irlmp_data_request already free the packet */
213 }
214
215 return ret;
216}
217
218/*
219 * Function ircomm_lmp_data_indication (instance, sap, skb)
220 *
221 * Incoming data which we must deliver to the state machine, to check
222 * we are still connected.
223 */
224static int ircomm_lmp_data_indication(void *instance, void *sap,
225 struct sk_buff *skb)
226{
227 struct ircomm_cb *self = (struct ircomm_cb *) instance;
228
229 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
230
231 IRDA_ASSERT(self != NULL, return -1;);
232 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
233 IRDA_ASSERT(skb != NULL, return -1;);
234
235 ircomm_do_event(self, IRCOMM_LMP_DATA_INDICATION, skb, NULL);
236
237 /* Drop reference count - see ircomm_tty_data_indication(). */
238 dev_kfree_skb(skb);
239
240 return 0;
241}
242
243/*
244 * Function ircomm_lmp_connect_confirm (instance, sap, qos, max_sdu_size,
245 * max_header_size, skb)
246 *
247 * Connection has been confirmed by peer device
248 *
249 */
250static void ircomm_lmp_connect_confirm(void *instance, void *sap,
251 struct qos_info *qos,
252 __u32 max_seg_size,
253 __u8 max_header_size,
254 struct sk_buff *skb)
255{
256 struct ircomm_cb *self = (struct ircomm_cb *) instance;
257 struct ircomm_info info;
258
259 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
260
261 IRDA_ASSERT(self != NULL, return;);
262 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return;);
263 IRDA_ASSERT(skb != NULL, return;);
264 IRDA_ASSERT(qos != NULL, return;);
265
266 info.max_data_size = max_seg_size;
267 info.max_header_size = max_header_size;
268 info.qos = qos;
269
270 ircomm_do_event(self, IRCOMM_LMP_CONNECT_CONFIRM, skb, &info);
271
272 /* Drop reference count - see ircomm_tty_connect_confirm(). */
273 dev_kfree_skb(skb);
274}
275
276/*
277 * Function ircomm_lmp_connect_indication (instance, sap, qos, max_sdu_size,
278 * max_header_size, skb)
279 *
280 * Peer device wants to make a connection with us
281 *
282 */
283static void ircomm_lmp_connect_indication(void *instance, void *sap,
284 struct qos_info *qos,
285 __u32 max_seg_size,
286 __u8 max_header_size,
287 struct sk_buff *skb)
288{
289 struct ircomm_cb *self = (struct ircomm_cb *)instance;
290 struct ircomm_info info;
291
292 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
293
294 IRDA_ASSERT(self != NULL, return;);
295 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return;);
296 IRDA_ASSERT(skb != NULL, return;);
297 IRDA_ASSERT(qos != NULL, return;);
298
299 info.max_data_size = max_seg_size;
300 info.max_header_size = max_header_size;
301 info.qos = qos;
302
303 ircomm_do_event(self, IRCOMM_LMP_CONNECT_INDICATION, skb, &info);
304
305 /* Drop reference count - see ircomm_tty_connect_indication(). */
306 dev_kfree_skb(skb);
307}
308
309/*
310 * Function ircomm_lmp_disconnect_indication (instance, sap, reason, skb)
311 *
312 * Peer device has closed the connection, or the link went down for some
313 * other reason
314 */
315static void ircomm_lmp_disconnect_indication(void *instance, void *sap,
316 LM_REASON reason,
317 struct sk_buff *skb)
318{
319 struct ircomm_cb *self = (struct ircomm_cb *) instance;
320 struct ircomm_info info;
321
322 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
323
324 IRDA_ASSERT(self != NULL, return;);
325 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return;);
326
327 info.reason = reason;
328
329 ircomm_do_event(self, IRCOMM_LMP_DISCONNECT_INDICATION, skb, &info);
330
331 /* Drop reference count - see ircomm_tty_disconnect_indication(). */
332 if(skb)
333 dev_kfree_skb(skb);
334}
335/*
336 * Function ircomm_open_lsap (self)
337 *
338 * Open LSAP. This function will only be used when using "raw" services
339 *
340 */
341int ircomm_open_lsap(struct ircomm_cb *self)
342{
343 notify_t notify;
344
345 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
346
347 /* Register callbacks */
348 irda_notify_init(&notify);
349 notify.data_indication = ircomm_lmp_data_indication;
350 notify.connect_confirm = ircomm_lmp_connect_confirm;
351 notify.connect_indication = ircomm_lmp_connect_indication;
352 notify.disconnect_indication = ircomm_lmp_disconnect_indication;
353 notify.instance = self;
354 strlcpy(notify.name, "IrCOMM", sizeof(notify.name));
355
356 self->lsap = irlmp_open_lsap(LSAP_ANY, &notify, 0);
357 if (!self->lsap) {
358 IRDA_DEBUG(0,"%sfailed to allocate tsap\n", __FUNCTION__ );
359 return -1;
360 }
361 self->slsap_sel = self->lsap->slsap_sel;
362
363 /*
364 * Initialize the call-table for issuing commands
365 */
366 self->issue.data_request = ircomm_lmp_data_request;
367 self->issue.connect_request = ircomm_lmp_connect_request;
368 self->issue.connect_response = ircomm_lmp_connect_response;
369 self->issue.disconnect_request = ircomm_lmp_disconnect_request;
370
371 return 0;
372}
diff --git a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c
new file mode 100644
index 00000000000..6009bab0509
--- /dev/null
+++ b/net/irda/ircomm/ircomm_param.c
@@ -0,0 +1,511 @@
1/*********************************************************************
2 *
3 * Filename: ircomm_param.c
4 * Version: 1.0
5 * Description: Parameter handling for the IrCOMM protocol
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Mon Jun 7 10:25:11 1999
9 * Modified at: Sun Jan 30 14:32:03 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 * MA 02111-1307 USA
28 *
29 ********************************************************************/
30
31#include <linux/sched.h>
32#include <linux/workqueue.h>
33#include <linux/interrupt.h>
34
35#include <net/irda/irda.h>
36#include <net/irda/parameters.h>
37
38#include <net/irda/ircomm_core.h>
39#include <net/irda/ircomm_tty_attach.h>
40#include <net/irda/ircomm_tty.h>
41
42#include <net/irda/ircomm_param.h>
43
44static int ircomm_param_service_type(void *instance, irda_param_t *param,
45 int get);
46static int ircomm_param_port_type(void *instance, irda_param_t *param,
47 int get);
48static int ircomm_param_port_name(void *instance, irda_param_t *param,
49 int get);
50static int ircomm_param_service_type(void *instance, irda_param_t *param,
51 int get);
52static int ircomm_param_data_rate(void *instance, irda_param_t *param,
53 int get);
54static int ircomm_param_data_format(void *instance, irda_param_t *param,
55 int get);
56static int ircomm_param_flow_control(void *instance, irda_param_t *param,
57 int get);
58static int ircomm_param_xon_xoff(void *instance, irda_param_t *param, int get);
59static int ircomm_param_enq_ack(void *instance, irda_param_t *param, int get);
60static int ircomm_param_line_status(void *instance, irda_param_t *param,
61 int get);
62static int ircomm_param_dte(void *instance, irda_param_t *param, int get);
63static int ircomm_param_dce(void *instance, irda_param_t *param, int get);
64static int ircomm_param_poll(void *instance, irda_param_t *param, int get);
65
66static pi_minor_info_t pi_minor_call_table_common[] = {
67 { ircomm_param_service_type, PV_INT_8_BITS },
68 { ircomm_param_port_type, PV_INT_8_BITS },
69 { ircomm_param_port_name, PV_STRING }
70};
71static pi_minor_info_t pi_minor_call_table_non_raw[] = {
72 { ircomm_param_data_rate, PV_INT_32_BITS | PV_BIG_ENDIAN },
73 { ircomm_param_data_format, PV_INT_8_BITS },
74 { ircomm_param_flow_control, PV_INT_8_BITS },
75 { ircomm_param_xon_xoff, PV_INT_16_BITS },
76 { ircomm_param_enq_ack, PV_INT_16_BITS },
77 { ircomm_param_line_status, PV_INT_8_BITS }
78};
79static pi_minor_info_t pi_minor_call_table_9_wire[] = {
80 { ircomm_param_dte, PV_INT_8_BITS },
81 { ircomm_param_dce, PV_INT_8_BITS },
82 { ircomm_param_poll, PV_NO_VALUE },
83};
84
85static pi_major_info_t pi_major_call_table[] = {
86 { pi_minor_call_table_common, 3 },
87 { pi_minor_call_table_non_raw, 6 },
88 { pi_minor_call_table_9_wire, 3 }
89/* { pi_minor_call_table_centronics } */
90};
91
92pi_param_info_t ircomm_param_info = { pi_major_call_table, 3, 0x0f, 4 };
93
94/*
95 * Function ircomm_param_request (self, pi, flush)
96 *
97 * Queue a parameter for the control channel
98 *
99 */
100int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush)
101{
102 struct tty_struct *tty;
103 unsigned long flags;
104 struct sk_buff *skb;
105 int count;
106
107 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
108
109 IRDA_ASSERT(self != NULL, return -1;);
110 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
111
112 tty = self->tty;
113 if (!tty)
114 return 0;
115
116 /* Make sure we don't send parameters for raw mode */
117 if (self->service_type == IRCOMM_3_WIRE_RAW)
118 return 0;
119
120 spin_lock_irqsave(&self->spinlock, flags);
121
122 skb = self->ctrl_skb;
123 if (!skb) {
124 skb = dev_alloc_skb(256);
125 if (!skb) {
126 spin_unlock_irqrestore(&self->spinlock, flags);
127 return -ENOMEM;
128 }
129
130 skb_reserve(skb, self->max_header_size);
131 self->ctrl_skb = skb;
132 }
133 /*
134 * Inserting is a little bit tricky since we don't know how much
135 * room we will need. But this should hopefully work OK
136 */
137 count = irda_param_insert(self, pi, skb->tail, skb_tailroom(skb),
138 &ircomm_param_info);
139 if (count < 0) {
140 IRDA_WARNING("%s(), no room for parameter!\n", __FUNCTION__);
141 spin_unlock_irqrestore(&self->spinlock, flags);
142 return -1;
143 }
144 skb_put(skb, count);
145
146 spin_unlock_irqrestore(&self->spinlock, flags);
147
148 IRDA_DEBUG(2, "%s(), skb->len=%d\n", __FUNCTION__ , skb->len);
149
150 if (flush) {
151 /* ircomm_tty_do_softint will take care of the rest */
152 schedule_work(&self->tqueue);
153 }
154
155 return count;
156}
157
158/*
159 * Function ircomm_param_service_type (self, buf, len)
160 *
161 * Handle service type, this function will both be called after the LM-IAS
162 * query and then the remote device sends its initial parameters
163 *
164 */
165static int ircomm_param_service_type(void *instance, irda_param_t *param,
166 int get)
167{
168 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
169 __u8 service_type = (__u8) param->pv.i;
170
171 IRDA_ASSERT(self != NULL, return -1;);
172 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
173
174 if (get) {
175 param->pv.i = self->settings.service_type;
176 return 0;
177 }
178
179 /* Find all common service types */
180 service_type &= self->service_type;
181 if (!service_type) {
182 IRDA_DEBUG(2,
183 "%s(), No common service type to use!\n", __FUNCTION__ );
184 return -1;
185 }
186 IRDA_DEBUG(0, "%s(), services in common=%02x\n", __FUNCTION__ ,
187 service_type);
188
189 /*
190 * Now choose a preferred service type of those available
191 */
192 if (service_type & IRCOMM_CENTRONICS)
193 self->settings.service_type = IRCOMM_CENTRONICS;
194 else if (service_type & IRCOMM_9_WIRE)
195 self->settings.service_type = IRCOMM_9_WIRE;
196 else if (service_type & IRCOMM_3_WIRE)
197 self->settings.service_type = IRCOMM_3_WIRE;
198 else if (service_type & IRCOMM_3_WIRE_RAW)
199 self->settings.service_type = IRCOMM_3_WIRE_RAW;
200
201 IRDA_DEBUG(0, "%s(), resulting service type=0x%02x\n", __FUNCTION__ ,
202 self->settings.service_type);
203
204 /*
205 * Now the line is ready for some communication. Check if we are a
206 * server, and send over some initial parameters.
207 * Client do it in ircomm_tty_state_setup().
208 * Note : we may get called from ircomm_tty_getvalue_confirm(),
209 * therefore before we even have open any socket. And self->client
210 * is initialised to TRUE only later. So, we check if the link is
211 * really initialised. - Jean II
212 */
213 if ((self->max_header_size != IRCOMM_TTY_HDR_UNINITIALISED) &&
214 (!self->client) &&
215 (self->settings.service_type != IRCOMM_3_WIRE_RAW))
216 {
217 /* Init connection */
218 ircomm_tty_send_initial_parameters(self);
219 ircomm_tty_link_established(self);
220 }
221
222 return 0;
223}
224
225/*
226 * Function ircomm_param_port_type (self, param)
227 *
228 * The port type parameter tells if the devices are serial or parallel.
229 * Since we only advertise serial service, this parameter should only
230 * be equal to IRCOMM_SERIAL.
231 */
232static int ircomm_param_port_type(void *instance, irda_param_t *param, int get)
233{
234 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
235
236 IRDA_ASSERT(self != NULL, return -1;);
237 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
238
239 if (get)
240 param->pv.i = IRCOMM_SERIAL;
241 else {
242 self->settings.port_type = (__u8) param->pv.i;
243
244 IRDA_DEBUG(0, "%s(), port type=%d\n", __FUNCTION__ ,
245 self->settings.port_type);
246 }
247 return 0;
248}
249
250/*
251 * Function ircomm_param_port_name (self, param)
252 *
253 * Exchange port name
254 *
255 */
256static int ircomm_param_port_name(void *instance, irda_param_t *param, int get)
257{
258 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
259
260 IRDA_ASSERT(self != NULL, return -1;);
261 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
262
263 if (get) {
264 IRDA_DEBUG(0, "%s(), not imp!\n", __FUNCTION__ );
265 } else {
266 IRDA_DEBUG(0, "%s(), port-name=%s\n", __FUNCTION__ , param->pv.c);
267 strncpy(self->settings.port_name, param->pv.c, 32);
268 }
269
270 return 0;
271}
272
273/*
274 * Function ircomm_param_data_rate (self, param)
275 *
276 * Exchange data rate to be used in this settings
277 *
278 */
279static int ircomm_param_data_rate(void *instance, irda_param_t *param, int get)
280{
281 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
282
283 IRDA_ASSERT(self != NULL, return -1;);
284 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
285
286 if (get)
287 param->pv.i = self->settings.data_rate;
288 else
289 self->settings.data_rate = param->pv.i;
290
291 IRDA_DEBUG(2, "%s(), data rate = %d\n", __FUNCTION__ , param->pv.i);
292
293 return 0;
294}
295
296/*
297 * Function ircomm_param_data_format (self, param)
298 *
299 * Exchange data format to be used in this settings
300 *
301 */
302static int ircomm_param_data_format(void *instance, irda_param_t *param,
303 int get)
304{
305 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
306
307 IRDA_ASSERT(self != NULL, return -1;);
308 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
309
310 if (get)
311 param->pv.i = self->settings.data_format;
312 else
313 self->settings.data_format = (__u8) param->pv.i;
314
315 return 0;
316}
317
318/*
319 * Function ircomm_param_flow_control (self, param)
320 *
321 * Exchange flow control settings to be used in this settings
322 *
323 */
324static int ircomm_param_flow_control(void *instance, irda_param_t *param,
325 int get)
326{
327 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
328
329 IRDA_ASSERT(self != NULL, return -1;);
330 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
331
332 if (get)
333 param->pv.i = self->settings.flow_control;
334 else
335 self->settings.flow_control = (__u8) param->pv.i;
336
337 IRDA_DEBUG(1, "%s(), flow control = 0x%02x\n", __FUNCTION__ , (__u8) param->pv.i);
338
339 return 0;
340}
341
342/*
343 * Function ircomm_param_xon_xoff (self, param)
344 *
345 * Exchange XON/XOFF characters
346 *
347 */
348static int ircomm_param_xon_xoff(void *instance, irda_param_t *param, int get)
349{
350 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
351
352 IRDA_ASSERT(self != NULL, return -1;);
353 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
354
355 if (get) {
356 param->pv.i = self->settings.xonxoff[0];
357 param->pv.i |= self->settings.xonxoff[1] << 8;
358 } else {
359 self->settings.xonxoff[0] = (__u16) param->pv.i & 0xff;
360 self->settings.xonxoff[1] = (__u16) param->pv.i >> 8;
361 }
362
363 IRDA_DEBUG(0, "%s(), XON/XOFF = 0x%02x,0x%02x\n", __FUNCTION__ ,
364 param->pv.i & 0xff, param->pv.i >> 8);
365
366 return 0;
367}
368
369/*
370 * Function ircomm_param_enq_ack (self, param)
371 *
372 * Exchange ENQ/ACK characters
373 *
374 */
375static int ircomm_param_enq_ack(void *instance, irda_param_t *param, int get)
376{
377 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
378
379 IRDA_ASSERT(self != NULL, return -1;);
380 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
381
382 if (get) {
383 param->pv.i = self->settings.enqack[0];
384 param->pv.i |= self->settings.enqack[1] << 8;
385 } else {
386 self->settings.enqack[0] = (__u16) param->pv.i & 0xff;
387 self->settings.enqack[1] = (__u16) param->pv.i >> 8;
388 }
389
390 IRDA_DEBUG(0, "%s(), ENQ/ACK = 0x%02x,0x%02x\n", __FUNCTION__ ,
391 param->pv.i & 0xff, param->pv.i >> 8);
392
393 return 0;
394}
395
396/*
397 * Function ircomm_param_line_status (self, param)
398 *
399 *
400 *
401 */
402static int ircomm_param_line_status(void *instance, irda_param_t *param,
403 int get)
404{
405 IRDA_DEBUG(2, "%s(), not impl.\n", __FUNCTION__ );
406
407 return 0;
408}
409
410/*
411 * Function ircomm_param_dte (instance, param)
412 *
413 * If we get here, there must be some sort of null-modem connection, and
414 * we are probably working in server mode as well.
415 */
416static int ircomm_param_dte(void *instance, irda_param_t *param, int get)
417{
418 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
419 __u8 dte;
420
421 IRDA_ASSERT(self != NULL, return -1;);
422 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
423
424 if (get)
425 param->pv.i = self->settings.dte;
426 else {
427 dte = (__u8) param->pv.i;
428
429 self->settings.dce = 0;
430
431 if (dte & IRCOMM_DELTA_DTR)
432 self->settings.dce |= (IRCOMM_DELTA_DSR|
433 IRCOMM_DELTA_RI |
434 IRCOMM_DELTA_CD);
435 if (dte & IRCOMM_DTR)
436 self->settings.dce |= (IRCOMM_DSR|
437 IRCOMM_RI |
438 IRCOMM_CD);
439
440 if (dte & IRCOMM_DELTA_RTS)
441 self->settings.dce |= IRCOMM_DELTA_CTS;
442 if (dte & IRCOMM_RTS)
443 self->settings.dce |= IRCOMM_CTS;
444
445 /* Take appropriate actions */
446 ircomm_tty_check_modem_status(self);
447
448 /* Null modem cable emulator */
449 self->settings.null_modem = TRUE;
450 }
451
452 return 0;
453}
454
455/*
456 * Function ircomm_param_dce (instance, param)
457 *
458 *
459 *
460 */
461static int ircomm_param_dce(void *instance, irda_param_t *param, int get)
462{
463 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
464 __u8 dce;
465
466 IRDA_DEBUG(1, "%s(), dce = 0x%02x\n", __FUNCTION__ , (__u8) param->pv.i);
467
468 dce = (__u8) param->pv.i;
469
470 IRDA_ASSERT(self != NULL, return -1;);
471 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
472
473 self->settings.dce = dce;
474
475 /* Check if any of the settings have changed */
476 if (dce & 0x0f) {
477 if (dce & IRCOMM_DELTA_CTS) {
478 IRDA_DEBUG(2, "%s(), CTS \n", __FUNCTION__ );
479 }
480 }
481
482 ircomm_tty_check_modem_status(self);
483
484 return 0;
485}
486
487/*
488 * Function ircomm_param_poll (instance, param)
489 *
490 * Called when the peer device is polling for the line settings
491 *
492 */
493static int ircomm_param_poll(void *instance, irda_param_t *param, int get)
494{
495 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
496
497 IRDA_ASSERT(self != NULL, return -1;);
498 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
499
500 /* Poll parameters are always of lenght 0 (just a signal) */
501 if (!get) {
502 /* Respond with DTE line settings */
503 ircomm_param_request(self, IRCOMM_DTE, TRUE);
504 }
505 return 0;
506}
507
508
509
510
511
diff --git a/net/irda/ircomm/ircomm_ttp.c b/net/irda/ircomm/ircomm_ttp.c
new file mode 100644
index 00000000000..d98bf3570d2
--- /dev/null
+++ b/net/irda/ircomm/ircomm_ttp.c
@@ -0,0 +1,369 @@
1/*********************************************************************
2 *
3 * Filename: ircomm_ttp.c
4 * Version: 1.0
5 * Description: Interface between IrCOMM and IrTTP
6 * Status: Stable
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Jun 6 20:48:27 1999
9 * Modified at: Mon Dec 13 11:35:13 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1999 Dag Brattli, All Rights Reserved.
13 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 * MA 02111-1307 USA
29 *
30 ********************************************************************/
31
32#include <linux/sched.h>
33#include <linux/init.h>
34
35#include <net/irda/irda.h>
36#include <net/irda/irlmp.h>
37#include <net/irda/iriap.h>
38#include <net/irda/irttp.h>
39
40#include <net/irda/ircomm_event.h>
41#include <net/irda/ircomm_ttp.h>
42
43static int ircomm_ttp_data_indication(void *instance, void *sap,
44 struct sk_buff *skb);
45static void ircomm_ttp_connect_confirm(void *instance, void *sap,
46 struct qos_info *qos,
47 __u32 max_sdu_size,
48 __u8 max_header_size,
49 struct sk_buff *skb);
50static void ircomm_ttp_connect_indication(void *instance, void *sap,
51 struct qos_info *qos,
52 __u32 max_sdu_size,
53 __u8 max_header_size,
54 struct sk_buff *skb);
55static void ircomm_ttp_flow_indication(void *instance, void *sap,
56 LOCAL_FLOW cmd);
57static void ircomm_ttp_disconnect_indication(void *instance, void *sap,
58 LM_REASON reason,
59 struct sk_buff *skb);
60static int ircomm_ttp_data_request(struct ircomm_cb *self,
61 struct sk_buff *skb,
62 int clen);
63static int ircomm_ttp_connect_request(struct ircomm_cb *self,
64 struct sk_buff *userdata,
65 struct ircomm_info *info);
66static int ircomm_ttp_connect_response(struct ircomm_cb *self,
67 struct sk_buff *userdata);
68static int ircomm_ttp_disconnect_request(struct ircomm_cb *self,
69 struct sk_buff *userdata,
70 struct ircomm_info *info);
71
72/*
73 * Function ircomm_open_tsap (self)
74 *
75 *
76 *
77 */
78int ircomm_open_tsap(struct ircomm_cb *self)
79{
80 notify_t notify;
81
82 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
83
84 /* Register callbacks */
85 irda_notify_init(&notify);
86 notify.data_indication = ircomm_ttp_data_indication;
87 notify.connect_confirm = ircomm_ttp_connect_confirm;
88 notify.connect_indication = ircomm_ttp_connect_indication;
89 notify.flow_indication = ircomm_ttp_flow_indication;
90 notify.disconnect_indication = ircomm_ttp_disconnect_indication;
91 notify.instance = self;
92 strlcpy(notify.name, "IrCOMM", sizeof(notify.name));
93
94 self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT,
95 &notify);
96 if (!self->tsap) {
97 IRDA_DEBUG(0, "%sfailed to allocate tsap\n", __FUNCTION__ );
98 return -1;
99 }
100 self->slsap_sel = self->tsap->stsap_sel;
101
102 /*
103 * Initialize the call-table for issuing commands
104 */
105 self->issue.data_request = ircomm_ttp_data_request;
106 self->issue.connect_request = ircomm_ttp_connect_request;
107 self->issue.connect_response = ircomm_ttp_connect_response;
108 self->issue.disconnect_request = ircomm_ttp_disconnect_request;
109
110 return 0;
111}
112
113/*
114 * Function ircomm_ttp_connect_request (self, userdata)
115 *
116 *
117 *
118 */
119static int ircomm_ttp_connect_request(struct ircomm_cb *self,
120 struct sk_buff *userdata,
121 struct ircomm_info *info)
122{
123 int ret = 0;
124
125 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
126
127 /* Don't forget to refcount it - should be NULL anyway */
128 if(userdata)
129 skb_get(userdata);
130
131 ret = irttp_connect_request(self->tsap, info->dlsap_sel,
132 info->saddr, info->daddr, NULL,
133 TTP_SAR_DISABLE, userdata);
134
135 return ret;
136}
137
138/*
139 * Function ircomm_ttp_connect_response (self, skb)
140 *
141 *
142 *
143 */
144static int ircomm_ttp_connect_response(struct ircomm_cb *self,
145 struct sk_buff *userdata)
146{
147 int ret;
148
149 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
150
151 /* Don't forget to refcount it - should be NULL anyway */
152 if(userdata)
153 skb_get(userdata);
154
155 ret = irttp_connect_response(self->tsap, TTP_SAR_DISABLE, userdata);
156
157 return ret;
158}
159
160/*
161 * Function ircomm_ttp_data_request (self, userdata)
162 *
163 * Send IrCOMM data to IrTTP layer. Currently we do not try to combine
164 * control data with pure data, so they will be sent as separate frames.
165 * Should not be a big problem though, since control frames are rare. But
166 * some of them are sent after connection establishment, so this can
167 * increase the latency a bit.
168 */
169static int ircomm_ttp_data_request(struct ircomm_cb *self,
170 struct sk_buff *skb,
171 int clen)
172{
173 int ret;
174
175 IRDA_ASSERT(skb != NULL, return -1;);
176
177 IRDA_DEBUG(2, "%s(), clen=%d\n", __FUNCTION__ , clen);
178
179 /*
180 * Insert clen field, currently we either send data only, or control
181 * only frames, to make things easier and avoid queueing
182 */
183 IRDA_ASSERT(skb_headroom(skb) >= IRCOMM_HEADER_SIZE, return -1;);
184
185 /* Don't forget to refcount it - see ircomm_tty_do_softint() */
186 skb_get(skb);
187
188 skb_push(skb, IRCOMM_HEADER_SIZE);
189
190 skb->data[0] = clen;
191
192 ret = irttp_data_request(self->tsap, skb);
193 if (ret) {
194 IRDA_ERROR("%s(), failed\n", __FUNCTION__);
195 /* irttp_data_request already free the packet */
196 }
197
198 return ret;
199}
200
201/*
202 * Function ircomm_ttp_data_indication (instance, sap, skb)
203 *
204 * Incoming data
205 *
206 */
207static int ircomm_ttp_data_indication(void *instance, void *sap,
208 struct sk_buff *skb)
209{
210 struct ircomm_cb *self = (struct ircomm_cb *) instance;
211
212 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
213
214 IRDA_ASSERT(self != NULL, return -1;);
215 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
216 IRDA_ASSERT(skb != NULL, return -1;);
217
218 ircomm_do_event(self, IRCOMM_TTP_DATA_INDICATION, skb, NULL);
219
220 /* Drop reference count - see ircomm_tty_data_indication(). */
221 dev_kfree_skb(skb);
222
223 return 0;
224}
225
226static void ircomm_ttp_connect_confirm(void *instance, void *sap,
227 struct qos_info *qos,
228 __u32 max_sdu_size,
229 __u8 max_header_size,
230 struct sk_buff *skb)
231{
232 struct ircomm_cb *self = (struct ircomm_cb *) instance;
233 struct ircomm_info info;
234
235 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
236
237 IRDA_ASSERT(self != NULL, return;);
238 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return;);
239 IRDA_ASSERT(skb != NULL, return;);
240 IRDA_ASSERT(qos != NULL, goto out;);
241
242 if (max_sdu_size != TTP_SAR_DISABLE) {
243 IRDA_ERROR("%s(), SAR not allowed for IrCOMM!\n",
244 __FUNCTION__);
245 goto out;
246 }
247
248 info.max_data_size = irttp_get_max_seg_size(self->tsap)
249 - IRCOMM_HEADER_SIZE;
250 info.max_header_size = max_header_size + IRCOMM_HEADER_SIZE;
251 info.qos = qos;
252
253 ircomm_do_event(self, IRCOMM_TTP_CONNECT_CONFIRM, skb, &info);
254
255out:
256 /* Drop reference count - see ircomm_tty_connect_confirm(). */
257 dev_kfree_skb(skb);
258}
259
260/*
261 * Function ircomm_ttp_connect_indication (instance, sap, qos, max_sdu_size,
262 * max_header_size, skb)
263 *
264 *
265 *
266 */
267static void ircomm_ttp_connect_indication(void *instance, void *sap,
268 struct qos_info *qos,
269 __u32 max_sdu_size,
270 __u8 max_header_size,
271 struct sk_buff *skb)
272{
273 struct ircomm_cb *self = (struct ircomm_cb *)instance;
274 struct ircomm_info info;
275
276 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
277
278 IRDA_ASSERT(self != NULL, return;);
279 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return;);
280 IRDA_ASSERT(skb != NULL, return;);
281 IRDA_ASSERT(qos != NULL, goto out;);
282
283 if (max_sdu_size != TTP_SAR_DISABLE) {
284 IRDA_ERROR("%s(), SAR not allowed for IrCOMM!\n",
285 __FUNCTION__);
286 goto out;
287 }
288
289 info.max_data_size = irttp_get_max_seg_size(self->tsap)
290 - IRCOMM_HEADER_SIZE;
291 info.max_header_size = max_header_size + IRCOMM_HEADER_SIZE;
292 info.qos = qos;
293
294 ircomm_do_event(self, IRCOMM_TTP_CONNECT_INDICATION, skb, &info);
295
296out:
297 /* Drop reference count - see ircomm_tty_connect_indication(). */
298 dev_kfree_skb(skb);
299}
300
301/*
302 * Function ircomm_ttp_disconnect_request (self, userdata, info)
303 *
304 *
305 *
306 */
307static int ircomm_ttp_disconnect_request(struct ircomm_cb *self,
308 struct sk_buff *userdata,
309 struct ircomm_info *info)
310{
311 int ret;
312
313 /* Don't forget to refcount it - should be NULL anyway */
314 if(userdata)
315 skb_get(userdata);
316
317 ret = irttp_disconnect_request(self->tsap, userdata, P_NORMAL);
318
319 return ret;
320}
321
322/*
323 * Function ircomm_ttp_disconnect_indication (instance, sap, reason, skb)
324 *
325 *
326 *
327 */
328static void ircomm_ttp_disconnect_indication(void *instance, void *sap,
329 LM_REASON reason,
330 struct sk_buff *skb)
331{
332 struct ircomm_cb *self = (struct ircomm_cb *) instance;
333 struct ircomm_info info;
334
335 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
336
337 IRDA_ASSERT(self != NULL, return;);
338 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return;);
339
340 info.reason = reason;
341
342 ircomm_do_event(self, IRCOMM_TTP_DISCONNECT_INDICATION, skb, &info);
343
344 /* Drop reference count - see ircomm_tty_disconnect_indication(). */
345 if(skb)
346 dev_kfree_skb(skb);
347}
348
349/*
350 * Function ircomm_ttp_flow_indication (instance, sap, cmd)
351 *
352 * Layer below is telling us to start or stop the flow of data
353 *
354 */
355static void ircomm_ttp_flow_indication(void *instance, void *sap,
356 LOCAL_FLOW cmd)
357{
358 struct ircomm_cb *self = (struct ircomm_cb *) instance;
359
360 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
361
362 IRDA_ASSERT(self != NULL, return;);
363 IRDA_ASSERT(self->magic == IRCOMM_MAGIC, return;);
364
365 if (self->notify.flow_indication)
366 self->notify.flow_indication(self->notify.instance, self, cmd);
367}
368
369
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
new file mode 100644
index 00000000000..5d1e61168eb
--- /dev/null
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -0,0 +1,1405 @@
1/*********************************************************************
2 *
3 * Filename: ircomm_tty.c
4 * Version: 1.0
5 * Description: IrCOMM serial TTY driver
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Jun 6 21:00:56 1999
9 * Modified at: Wed Feb 23 00:09:02 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 * Sources: serial.c and previous IrCOMM work by Takahide Higuchi
12 *
13 * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
14 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 * MA 02111-1307 USA
30 *
31 ********************************************************************/
32
33#include <linux/config.h>
34#include <linux/init.h>
35#include <linux/module.h>
36#include <linux/fs.h>
37#include <linux/sched.h>
38#include <linux/termios.h>
39#include <linux/tty.h>
40#include <linux/interrupt.h>
41#include <linux/device.h> /* for MODULE_ALIAS_CHARDEV_MAJOR */
42
43#include <asm/uaccess.h>
44
45#include <net/irda/irda.h>
46#include <net/irda/irmod.h>
47
48#include <net/irda/ircomm_core.h>
49#include <net/irda/ircomm_param.h>
50#include <net/irda/ircomm_tty_attach.h>
51#include <net/irda/ircomm_tty.h>
52
53static int ircomm_tty_open(struct tty_struct *tty, struct file *filp);
54static void ircomm_tty_close(struct tty_struct * tty, struct file *filp);
55static int ircomm_tty_write(struct tty_struct * tty,
56 const unsigned char *buf, int count);
57static int ircomm_tty_write_room(struct tty_struct *tty);
58static void ircomm_tty_throttle(struct tty_struct *tty);
59static void ircomm_tty_unthrottle(struct tty_struct *tty);
60static int ircomm_tty_chars_in_buffer(struct tty_struct *tty);
61static void ircomm_tty_flush_buffer(struct tty_struct *tty);
62static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch);
63static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout);
64static void ircomm_tty_hangup(struct tty_struct *tty);
65static void ircomm_tty_do_softint(void *private_);
66static void ircomm_tty_shutdown(struct ircomm_tty_cb *self);
67static void ircomm_tty_stop(struct tty_struct *tty);
68
69static int ircomm_tty_data_indication(void *instance, void *sap,
70 struct sk_buff *skb);
71static int ircomm_tty_control_indication(void *instance, void *sap,
72 struct sk_buff *skb);
73static void ircomm_tty_flow_indication(void *instance, void *sap,
74 LOCAL_FLOW cmd);
75#ifdef CONFIG_PROC_FS
76static int ircomm_tty_read_proc(char *buf, char **start, off_t offset, int len,
77 int *eof, void *unused);
78#endif /* CONFIG_PROC_FS */
79static struct tty_driver *driver;
80
81hashbin_t *ircomm_tty = NULL;
82
83static struct tty_operations ops = {
84 .open = ircomm_tty_open,
85 .close = ircomm_tty_close,
86 .write = ircomm_tty_write,
87 .write_room = ircomm_tty_write_room,
88 .chars_in_buffer = ircomm_tty_chars_in_buffer,
89 .flush_buffer = ircomm_tty_flush_buffer,
90 .ioctl = ircomm_tty_ioctl, /* ircomm_tty_ioctl.c */
91 .tiocmget = ircomm_tty_tiocmget, /* ircomm_tty_ioctl.c */
92 .tiocmset = ircomm_tty_tiocmset, /* ircomm_tty_ioctl.c */
93 .throttle = ircomm_tty_throttle,
94 .unthrottle = ircomm_tty_unthrottle,
95 .send_xchar = ircomm_tty_send_xchar,
96 .set_termios = ircomm_tty_set_termios,
97 .stop = ircomm_tty_stop,
98 .start = ircomm_tty_start,
99 .hangup = ircomm_tty_hangup,
100 .wait_until_sent = ircomm_tty_wait_until_sent,
101#ifdef CONFIG_PROC_FS
102 .read_proc = ircomm_tty_read_proc,
103#endif /* CONFIG_PROC_FS */
104};
105
106/*
107 * Function ircomm_tty_init()
108 *
109 * Init IrCOMM TTY layer/driver
110 *
111 */
112static int __init ircomm_tty_init(void)
113{
114 driver = alloc_tty_driver(IRCOMM_TTY_PORTS);
115 if (!driver)
116 return -ENOMEM;
117 ircomm_tty = hashbin_new(HB_LOCK);
118 if (ircomm_tty == NULL) {
119 IRDA_ERROR("%s(), can't allocate hashbin!\n", __FUNCTION__);
120 put_tty_driver(driver);
121 return -ENOMEM;
122 }
123
124 driver->owner = THIS_MODULE;
125 driver->driver_name = "ircomm";
126 driver->name = "ircomm";
127 driver->devfs_name = "ircomm";
128 driver->major = IRCOMM_TTY_MAJOR;
129 driver->minor_start = IRCOMM_TTY_MINOR;
130 driver->type = TTY_DRIVER_TYPE_SERIAL;
131 driver->subtype = SERIAL_TYPE_NORMAL;
132 driver->init_termios = tty_std_termios;
133 driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
134 driver->flags = TTY_DRIVER_REAL_RAW;
135 tty_set_operations(driver, &ops);
136 if (tty_register_driver(driver)) {
137 IRDA_ERROR("%s(): Couldn't register serial driver\n",
138 __FUNCTION__);
139 put_tty_driver(driver);
140 return -1;
141 }
142 return 0;
143}
144
145static void __exit __ircomm_tty_cleanup(struct ircomm_tty_cb *self)
146{
147 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
148
149 IRDA_ASSERT(self != NULL, return;);
150 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
151
152 ircomm_tty_shutdown(self);
153
154 self->magic = 0;
155 kfree(self);
156}
157
158/*
159 * Function ircomm_tty_cleanup ()
160 *
161 * Remove IrCOMM TTY layer/driver
162 *
163 */
164static void __exit ircomm_tty_cleanup(void)
165{
166 int ret;
167
168 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
169
170 ret = tty_unregister_driver(driver);
171 if (ret) {
172 IRDA_ERROR("%s(), failed to unregister driver\n",
173 __FUNCTION__);
174 return;
175 }
176
177 hashbin_delete(ircomm_tty, (FREE_FUNC) __ircomm_tty_cleanup);
178 put_tty_driver(driver);
179}
180
181/*
182 * Function ircomm_startup (self)
183 *
184 *
185 *
186 */
187static int ircomm_tty_startup(struct ircomm_tty_cb *self)
188{
189 notify_t notify;
190 int ret = -ENODEV;
191
192 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
193
194 IRDA_ASSERT(self != NULL, return -1;);
195 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
196
197 /* Check if already open */
198 if (test_and_set_bit(ASYNC_B_INITIALIZED, &self->flags)) {
199 IRDA_DEBUG(2, "%s(), already open so break out!\n", __FUNCTION__ );
200 return 0;
201 }
202
203 /* Register with IrCOMM */
204 irda_notify_init(&notify);
205 /* These callbacks we must handle ourselves */
206 notify.data_indication = ircomm_tty_data_indication;
207 notify.udata_indication = ircomm_tty_control_indication;
208 notify.flow_indication = ircomm_tty_flow_indication;
209
210 /* Use the ircomm_tty interface for these ones */
211 notify.disconnect_indication = ircomm_tty_disconnect_indication;
212 notify.connect_confirm = ircomm_tty_connect_confirm;
213 notify.connect_indication = ircomm_tty_connect_indication;
214 strlcpy(notify.name, "ircomm_tty", sizeof(notify.name));
215 notify.instance = self;
216
217 if (!self->ircomm) {
218 self->ircomm = ircomm_open(&notify, self->service_type,
219 self->line);
220 }
221 if (!self->ircomm)
222 goto err;
223
224 self->slsap_sel = self->ircomm->slsap_sel;
225
226 /* Connect IrCOMM link with remote device */
227 ret = ircomm_tty_attach_cable(self);
228 if (ret < 0) {
229 IRDA_ERROR("%s(), error attaching cable!\n", __FUNCTION__);
230 goto err;
231 }
232
233 return 0;
234err:
235 clear_bit(ASYNC_B_INITIALIZED, &self->flags);
236 return ret;
237}
238
239/*
240 * Function ircomm_block_til_ready (self, filp)
241 *
242 *
243 *
244 */
245static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
246 struct file *filp)
247{
248 DECLARE_WAITQUEUE(wait, current);
249 int retval;
250 int do_clocal = 0, extra_count = 0;
251 unsigned long flags;
252 struct tty_struct *tty;
253
254 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
255
256 tty = self->tty;
257
258 /*
259 * If non-blocking mode is set, or the port is not enabled,
260 * then make the check up front and then exit.
261 */
262 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
263 /* nonblock mode is set or port is not enabled */
264 self->flags |= ASYNC_NORMAL_ACTIVE;
265 IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __FUNCTION__ );
266 return 0;
267 }
268
269 if (tty->termios->c_cflag & CLOCAL) {
270 IRDA_DEBUG(1, "%s(), doing CLOCAL!\n", __FUNCTION__ );
271 do_clocal = 1;
272 }
273
274 /* Wait for carrier detect and the line to become
275 * free (i.e., not in use by the callout). While we are in
276 * this loop, self->open_count is dropped by one, so that
277 * mgsl_close() knows when to free things. We restore it upon
278 * exit, either normal or abnormal.
279 */
280
281 retval = 0;
282 add_wait_queue(&self->open_wait, &wait);
283
284 IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n",
285 __FILE__,__LINE__, tty->driver->name, self->open_count );
286
287 /* As far as I can see, we protect open_count - Jean II */
288 spin_lock_irqsave(&self->spinlock, flags);
289 if (!tty_hung_up_p(filp)) {
290 extra_count = 1;
291 self->open_count--;
292 }
293 spin_unlock_irqrestore(&self->spinlock, flags);
294 self->blocked_open++;
295
296 while (1) {
297 if (tty->termios->c_cflag & CBAUD) {
298 /* Here, we use to lock those two guys, but
299 * as ircomm_param_request() does it itself,
300 * I don't see the point (and I see the deadlock).
301 * Jean II */
302 self->settings.dte |= IRCOMM_RTS + IRCOMM_DTR;
303
304 ircomm_param_request(self, IRCOMM_DTE, TRUE);
305 }
306
307 current->state = TASK_INTERRUPTIBLE;
308
309 if (tty_hung_up_p(filp) ||
310 !test_bit(ASYNC_B_INITIALIZED, &self->flags)) {
311 retval = (self->flags & ASYNC_HUP_NOTIFY) ?
312 -EAGAIN : -ERESTARTSYS;
313 break;
314 }
315
316 /*
317 * Check if link is ready now. Even if CLOCAL is
318 * specified, we cannot return before the IrCOMM link is
319 * ready
320 */
321 if (!test_bit(ASYNC_B_CLOSING, &self->flags) &&
322 (do_clocal || (self->settings.dce & IRCOMM_CD)) &&
323 self->state == IRCOMM_TTY_READY)
324 {
325 break;
326 }
327
328 if (signal_pending(current)) {
329 retval = -ERESTARTSYS;
330 break;
331 }
332
333 IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n",
334 __FILE__,__LINE__, tty->driver->name, self->open_count );
335
336 schedule();
337 }
338
339 __set_current_state(TASK_RUNNING);
340 remove_wait_queue(&self->open_wait, &wait);
341
342 if (extra_count) {
343 /* ++ is not atomic, so this should be protected - Jean II */
344 spin_lock_irqsave(&self->spinlock, flags);
345 self->open_count++;
346 spin_unlock_irqrestore(&self->spinlock, flags);
347 }
348 self->blocked_open--;
349
350 IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n",
351 __FILE__,__LINE__, tty->driver->name, self->open_count);
352
353 if (!retval)
354 self->flags |= ASYNC_NORMAL_ACTIVE;
355
356 return retval;
357}
358
359/*
360 * Function ircomm_tty_open (tty, filp)
361 *
362 * This routine is called when a particular tty device is opened. This
363 * routine is mandatory; if this routine is not filled in, the attempted
364 * open will fail with ENODEV.
365 */
366static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
367{
368 struct ircomm_tty_cb *self;
369 unsigned int line;
370 unsigned long flags;
371 int ret;
372
373 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
374
375 line = tty->index;
376 if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
377 return -ENODEV;
378 }
379
380 /* Check if instance already exists */
381 self = hashbin_lock_find(ircomm_tty, line, NULL);
382 if (!self) {
383 /* No, so make new instance */
384 self = kmalloc(sizeof(struct ircomm_tty_cb), GFP_KERNEL);
385 if (self == NULL) {
386 IRDA_ERROR("%s(), kmalloc failed!\n", __FUNCTION__);
387 return -ENOMEM;
388 }
389 memset(self, 0, sizeof(struct ircomm_tty_cb));
390
391 self->magic = IRCOMM_TTY_MAGIC;
392 self->flow = FLOW_STOP;
393
394 self->line = line;
395 INIT_WORK(&self->tqueue, ircomm_tty_do_softint, self);
396 self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED;
397 self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED;
398 self->close_delay = 5*HZ/10;
399 self->closing_wait = 30*HZ;
400
401 /* Init some important stuff */
402 init_timer(&self->watchdog_timer);
403 init_waitqueue_head(&self->open_wait);
404 init_waitqueue_head(&self->close_wait);
405 spin_lock_init(&self->spinlock);
406
407 /*
408 * Force TTY into raw mode by default which is usually what
409 * we want for IrCOMM and IrLPT. This way applications will
410 * not have to twiddle with printcap etc.
411 */
412 tty->termios->c_iflag = 0;
413 tty->termios->c_oflag = 0;
414
415 /* Insert into hash */
416 hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL);
417 }
418 /* ++ is not atomic, so this should be protected - Jean II */
419 spin_lock_irqsave(&self->spinlock, flags);
420 self->open_count++;
421
422 tty->driver_data = self;
423 self->tty = tty;
424 spin_unlock_irqrestore(&self->spinlock, flags);
425
426 IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __FUNCTION__ , tty->driver->name,
427 self->line, self->open_count);
428
429 /* Not really used by us, but lets do it anyway */
430 self->tty->low_latency = (self->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
431
432 /*
433 * If the port is the middle of closing, bail out now
434 */
435 if (tty_hung_up_p(filp) ||
436 test_bit(ASYNC_B_CLOSING, &self->flags)) {
437
438 /* Hm, why are we blocking on ASYNC_CLOSING if we
439 * do return -EAGAIN/-ERESTARTSYS below anyway?
440 * IMHO it's either not needed in the first place
441 * or for some reason we need to make sure the async
442 * closing has been finished - if so, wouldn't we
443 * probably better sleep uninterruptible?
444 */
445
446 if (wait_event_interruptible(self->close_wait, !test_bit(ASYNC_B_CLOSING, &self->flags))) {
447 IRDA_WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n",
448 __FUNCTION__);
449 return -ERESTARTSYS;
450 }
451
452#ifdef SERIAL_DO_RESTART
453 return ((self->flags & ASYNC_HUP_NOTIFY) ?
454 -EAGAIN : -ERESTARTSYS);
455#else
456 return -EAGAIN;
457#endif
458 }
459
460 /* Check if this is a "normal" ircomm device, or an irlpt device */
461 if (line < 0x10) {
462 self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE;
463 self->settings.service_type = IRCOMM_9_WIRE; /* 9 wire as default */
464 /* Jan Kiszka -> add DSR/RI -> Conform to IrCOMM spec */
465 self->settings.dce = IRCOMM_CTS | IRCOMM_CD | IRCOMM_DSR | IRCOMM_RI; /* Default line settings */
466 IRDA_DEBUG(2, "%s(), IrCOMM device\n", __FUNCTION__ );
467 } else {
468 IRDA_DEBUG(2, "%s(), IrLPT device\n", __FUNCTION__ );
469 self->service_type = IRCOMM_3_WIRE_RAW;
470 self->settings.service_type = IRCOMM_3_WIRE_RAW; /* Default */
471 }
472
473 ret = ircomm_tty_startup(self);
474 if (ret)
475 return ret;
476
477 ret = ircomm_tty_block_til_ready(self, filp);
478 if (ret) {
479 IRDA_DEBUG(2,
480 "%s(), returning after block_til_ready with %d\n", __FUNCTION__ ,
481 ret);
482
483 return ret;
484 }
485 return 0;
486}
487
488/*
489 * Function ircomm_tty_close (tty, filp)
490 *
491 * This routine is called when a particular tty device is closed.
492 *
493 */
494static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
495{
496 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
497 unsigned long flags;
498
499 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
500
501 if (!tty)
502 return;
503
504 IRDA_ASSERT(self != NULL, return;);
505 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
506
507 spin_lock_irqsave(&self->spinlock, flags);
508
509 if (tty_hung_up_p(filp)) {
510 spin_unlock_irqrestore(&self->spinlock, flags);
511
512 IRDA_DEBUG(0, "%s(), returning 1\n", __FUNCTION__ );
513 return;
514 }
515
516 if ((tty->count == 1) && (self->open_count != 1)) {
517 /*
518 * Uh, oh. tty->count is 1, which means that the tty
519 * structure will be freed. state->count should always
520 * be one in these conditions. If it's greater than
521 * one, we've got real problems, since it means the
522 * serial port won't be shutdown.
523 */
524 IRDA_DEBUG(0, "%s(), bad serial port count; "
525 "tty->count is 1, state->count is %d\n", __FUNCTION__ ,
526 self->open_count);
527 self->open_count = 1;
528 }
529
530 if (--self->open_count < 0) {
531 IRDA_ERROR("%s(), bad serial port count for ttys%d: %d\n",
532 __FUNCTION__, self->line, self->open_count);
533 self->open_count = 0;
534 }
535 if (self->open_count) {
536 spin_unlock_irqrestore(&self->spinlock, flags);
537
538 IRDA_DEBUG(0, "%s(), open count > 0\n", __FUNCTION__ );
539 return;
540 }
541
542 /* Hum... Should be test_and_set_bit ??? - Jean II */
543 set_bit(ASYNC_B_CLOSING, &self->flags);
544
545 /* We need to unlock here (we were unlocking at the end of this
546 * function), because tty_wait_until_sent() may schedule.
547 * I don't know if the rest should be protected somehow,
548 * so someone should check. - Jean II */
549 spin_unlock_irqrestore(&self->spinlock, flags);
550
551 /*
552 * Now we wait for the transmit buffer to clear; and we notify
553 * the line discipline to only process XON/XOFF characters.
554 */
555 tty->closing = 1;
556 if (self->closing_wait != ASYNC_CLOSING_WAIT_NONE)
557 tty_wait_until_sent(tty, self->closing_wait);
558
559 ircomm_tty_shutdown(self);
560
561 if (tty->driver->flush_buffer)
562 tty->driver->flush_buffer(tty);
563 if (tty->ldisc.flush_buffer)
564 tty->ldisc.flush_buffer(tty);
565
566 tty->closing = 0;
567 self->tty = NULL;
568
569 if (self->blocked_open) {
570 if (self->close_delay) {
571 current->state = TASK_INTERRUPTIBLE;
572 schedule_timeout(self->close_delay);
573 }
574 wake_up_interruptible(&self->open_wait);
575 }
576
577 self->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
578 wake_up_interruptible(&self->close_wait);
579}
580
581/*
582 * Function ircomm_tty_flush_buffer (tty)
583 *
584 *
585 *
586 */
587static void ircomm_tty_flush_buffer(struct tty_struct *tty)
588{
589 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
590
591 IRDA_ASSERT(self != NULL, return;);
592 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
593
594 /*
595 * Let do_softint() do this to avoid race condition with
596 * do_softint() ;-)
597 */
598 schedule_work(&self->tqueue);
599}
600
601/*
602 * Function ircomm_tty_do_softint (private_)
603 *
604 * We use this routine to give the write wakeup to the user at at a
605 * safe time (as fast as possible after write have completed). This
606 * can be compared to the Tx interrupt.
607 */
608static void ircomm_tty_do_softint(void *private_)
609{
610 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) private_;
611 struct tty_struct *tty;
612 unsigned long flags;
613 struct sk_buff *skb, *ctrl_skb;
614
615 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
616
617 if (!self || self->magic != IRCOMM_TTY_MAGIC)
618 return;
619
620 tty = self->tty;
621 if (!tty)
622 return;
623
624 /* Unlink control buffer */
625 spin_lock_irqsave(&self->spinlock, flags);
626
627 ctrl_skb = self->ctrl_skb;
628 self->ctrl_skb = NULL;
629
630 spin_unlock_irqrestore(&self->spinlock, flags);
631
632 /* Flush control buffer if any */
633 if(ctrl_skb) {
634 if(self->flow == FLOW_START)
635 ircomm_control_request(self->ircomm, ctrl_skb);
636 /* Drop reference count - see ircomm_ttp_data_request(). */
637 dev_kfree_skb(ctrl_skb);
638 }
639
640 if (tty->hw_stopped)
641 return;
642
643 /* Unlink transmit buffer */
644 spin_lock_irqsave(&self->spinlock, flags);
645
646 skb = self->tx_skb;
647 self->tx_skb = NULL;
648
649 spin_unlock_irqrestore(&self->spinlock, flags);
650
651 /* Flush transmit buffer if any */
652 if (skb) {
653 ircomm_tty_do_event(self, IRCOMM_TTY_DATA_REQUEST, skb, NULL);
654 /* Drop reference count - see ircomm_ttp_data_request(). */
655 dev_kfree_skb(skb);
656 }
657
658 /* Check if user (still) wants to be waken up */
659 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
660 tty->ldisc.write_wakeup)
661 {
662 (tty->ldisc.write_wakeup)(tty);
663 }
664 wake_up_interruptible(&tty->write_wait);
665}
666
667/*
668 * Function ircomm_tty_write (tty, buf, count)
669 *
670 * This routine is called by the kernel to write a series of characters
671 * to the tty device. The characters may come from user space or kernel
672 * space. This routine will return the number of characters actually
673 * accepted for writing. This routine is mandatory.
674 */
675static int ircomm_tty_write(struct tty_struct *tty,
676 const unsigned char *buf, int count)
677{
678 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
679 unsigned long flags;
680 struct sk_buff *skb;
681 int tailroom = 0;
682 int len = 0;
683 int size;
684
685 IRDA_DEBUG(2, "%s(), count=%d, hw_stopped=%d\n", __FUNCTION__ , count,
686 tty->hw_stopped);
687
688 IRDA_ASSERT(self != NULL, return -1;);
689 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
690
691 /* We may receive packets from the TTY even before we have finished
692 * our setup. Not cool.
693 * The problem is that we don't know the final header and data size
694 * to create the proper skb, so any skb we would create would have
695 * bogus header and data size, so need care.
696 * We use a bogus header size to safely detect this condition.
697 * Another problem is that hw_stopped was set to 0 way before it
698 * should be, so we would drop this skb. It should now be fixed.
699 * One option is to not accept data until we are properly setup.
700 * But, I suspect that when it happens, the ppp line discipline
701 * just "drops" the data, which might screw up connect scripts.
702 * The second option is to create a "safe skb", with large header
703 * and small size (see ircomm_tty_open() for values).
704 * We just need to make sure that when the real values get filled,
705 * we don't mess up the original "safe skb" (see tx_data_size).
706 * Jean II */
707 if (self->max_header_size == IRCOMM_TTY_HDR_UNINITIALISED) {
708 IRDA_DEBUG(1, "%s() : not initialised\n", __FUNCTION__);
709#ifdef IRCOMM_NO_TX_BEFORE_INIT
710 /* We didn't consume anything, TTY will retry */
711 return 0;
712#endif
713 }
714
715 if (count < 1)
716 return 0;
717
718 /* Protect our manipulation of self->tx_skb and related */
719 spin_lock_irqsave(&self->spinlock, flags);
720
721 /* Fetch current transmit buffer */
722 skb = self->tx_skb;
723
724 /*
725 * Send out all the data we get, possibly as multiple fragmented
726 * frames, but this will only happen if the data is larger than the
727 * max data size. The normal case however is just the opposite, and
728 * this function may be called multiple times, and will then actually
729 * defragment the data and send it out as one packet as soon as
730 * possible, but at a safer point in time
731 */
732 while (count) {
733 size = count;
734
735 /* Adjust data size to the max data size */
736 if (size > self->max_data_size)
737 size = self->max_data_size;
738
739 /*
740 * Do we already have a buffer ready for transmit, or do
741 * we need to allocate a new frame
742 */
743 if (skb) {
744 /*
745 * Any room for more data at the end of the current
746 * transmit buffer? Cannot use skb_tailroom, since
747 * dev_alloc_skb gives us a larger skb than we
748 * requested
749 * Note : use tx_data_size, because max_data_size
750 * may have changed and we don't want to overwrite
751 * the skb. - Jean II
752 */
753 if ((tailroom = (self->tx_data_size - skb->len)) > 0) {
754 /* Adjust data to tailroom */
755 if (size > tailroom)
756 size = tailroom;
757 } else {
758 /*
759 * Current transmit frame is full, so break
760 * out, so we can send it as soon as possible
761 */
762 break;
763 }
764 } else {
765 /* Prepare a full sized frame */
766 skb = dev_alloc_skb(self->max_data_size+
767 self->max_header_size);
768 if (!skb) {
769 spin_unlock_irqrestore(&self->spinlock, flags);
770 return -ENOBUFS;
771 }
772 skb_reserve(skb, self->max_header_size);
773 self->tx_skb = skb;
774 /* Remember skb size because max_data_size may
775 * change later on - Jean II */
776 self->tx_data_size = self->max_data_size;
777 }
778
779 /* Copy data */
780 memcpy(skb_put(skb,size), buf + len, size);
781
782 count -= size;
783 len += size;
784 }
785
786 spin_unlock_irqrestore(&self->spinlock, flags);
787
788 /*
789 * Schedule a new thread which will transmit the frame as soon
790 * as possible, but at a safe point in time. We do this so the
791 * "user" can give us data multiple times, as PPP does (because of
792 * its 256 byte tx buffer). We will then defragment and send out
793 * all this data as one single packet.
794 */
795 schedule_work(&self->tqueue);
796
797 return len;
798}
799
800/*
801 * Function ircomm_tty_write_room (tty)
802 *
803 * This routine returns the numbers of characters the tty driver will
804 * accept for queuing to be written. This number is subject to change as
805 * output buffers get emptied, or if the output flow control is acted.
806 */
807static int ircomm_tty_write_room(struct tty_struct *tty)
808{
809 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
810 unsigned long flags;
811 int ret;
812
813 IRDA_ASSERT(self != NULL, return -1;);
814 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
815
816#ifdef IRCOMM_NO_TX_BEFORE_INIT
817 /* max_header_size tells us if the channel is initialised or not. */
818 if (self->max_header_size == IRCOMM_TTY_HDR_UNINITIALISED)
819 /* Don't bother us yet */
820 return 0;
821#endif
822
823 /* Check if we are allowed to transmit any data.
824 * hw_stopped is the regular flow control.
825 * Jean II */
826 if (tty->hw_stopped)
827 ret = 0;
828 else {
829 spin_lock_irqsave(&self->spinlock, flags);
830 if (self->tx_skb)
831 ret = self->tx_data_size - self->tx_skb->len;
832 else
833 ret = self->max_data_size;
834 spin_unlock_irqrestore(&self->spinlock, flags);
835 }
836 IRDA_DEBUG(2, "%s(), ret=%d\n", __FUNCTION__ , ret);
837
838 return ret;
839}
840
841/*
842 * Function ircomm_tty_wait_until_sent (tty, timeout)
843 *
844 * This routine waits until the device has written out all of the
845 * characters in its transmitter FIFO.
846 */
847static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
848{
849 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
850 unsigned long orig_jiffies, poll_time;
851 unsigned long flags;
852
853 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
854
855 IRDA_ASSERT(self != NULL, return;);
856 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
857
858 orig_jiffies = jiffies;
859
860 /* Set poll time to 200 ms */
861 poll_time = IRDA_MIN(timeout, msecs_to_jiffies(200));
862
863 spin_lock_irqsave(&self->spinlock, flags);
864 while (self->tx_skb && self->tx_skb->len) {
865 spin_unlock_irqrestore(&self->spinlock, flags);
866 current->state = TASK_INTERRUPTIBLE;
867 schedule_timeout(poll_time);
868 spin_lock_irqsave(&self->spinlock, flags);
869 if (signal_pending(current))
870 break;
871 if (timeout && time_after(jiffies, orig_jiffies + timeout))
872 break;
873 }
874 spin_unlock_irqrestore(&self->spinlock, flags);
875 current->state = TASK_RUNNING;
876}
877
878/*
879 * Function ircomm_tty_throttle (tty)
880 *
881 * This routine notifies the tty driver that input buffers for the line
882 * discipline are close to full, and it should somehow signal that no
883 * more characters should be sent to the tty.
884 */
885static void ircomm_tty_throttle(struct tty_struct *tty)
886{
887 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
888
889 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
890
891 IRDA_ASSERT(self != NULL, return;);
892 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
893
894 /* Software flow control? */
895 if (I_IXOFF(tty))
896 ircomm_tty_send_xchar(tty, STOP_CHAR(tty));
897
898 /* Hardware flow control? */
899 if (tty->termios->c_cflag & CRTSCTS) {
900 self->settings.dte &= ~IRCOMM_RTS;
901 self->settings.dte |= IRCOMM_DELTA_RTS;
902
903 ircomm_param_request(self, IRCOMM_DTE, TRUE);
904 }
905
906 ircomm_flow_request(self->ircomm, FLOW_STOP);
907}
908
909/*
910 * Function ircomm_tty_unthrottle (tty)
911 *
912 * This routine notifies the tty drivers that it should signals that
913 * characters can now be sent to the tty without fear of overrunning the
914 * input buffers of the line disciplines.
915 */
916static void ircomm_tty_unthrottle(struct tty_struct *tty)
917{
918 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
919
920 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
921
922 IRDA_ASSERT(self != NULL, return;);
923 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
924
925 /* Using software flow control? */
926 if (I_IXOFF(tty)) {
927 ircomm_tty_send_xchar(tty, START_CHAR(tty));
928 }
929
930 /* Using hardware flow control? */
931 if (tty->termios->c_cflag & CRTSCTS) {
932 self->settings.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS);
933
934 ircomm_param_request(self, IRCOMM_DTE, TRUE);
935 IRDA_DEBUG(1, "%s(), FLOW_START\n", __FUNCTION__ );
936 }
937 ircomm_flow_request(self->ircomm, FLOW_START);
938}
939
940/*
941 * Function ircomm_tty_chars_in_buffer (tty)
942 *
943 * Indicates if there are any data in the buffer
944 *
945 */
946static int ircomm_tty_chars_in_buffer(struct tty_struct *tty)
947{
948 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
949 unsigned long flags;
950 int len = 0;
951
952 IRDA_ASSERT(self != NULL, return -1;);
953 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
954
955 spin_lock_irqsave(&self->spinlock, flags);
956
957 if (self->tx_skb)
958 len = self->tx_skb->len;
959
960 spin_unlock_irqrestore(&self->spinlock, flags);
961
962 return len;
963}
964
965static void ircomm_tty_shutdown(struct ircomm_tty_cb *self)
966{
967 unsigned long flags;
968
969 IRDA_ASSERT(self != NULL, return;);
970 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
971
972 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
973
974 if (!test_and_clear_bit(ASYNC_B_INITIALIZED, &self->flags))
975 return;
976
977 ircomm_tty_detach_cable(self);
978
979 spin_lock_irqsave(&self->spinlock, flags);
980
981 del_timer(&self->watchdog_timer);
982
983 /* Free parameter buffer */
984 if (self->ctrl_skb) {
985 dev_kfree_skb(self->ctrl_skb);
986 self->ctrl_skb = NULL;
987 }
988
989 /* Free transmit buffer */
990 if (self->tx_skb) {
991 dev_kfree_skb(self->tx_skb);
992 self->tx_skb = NULL;
993 }
994
995 if (self->ircomm) {
996 ircomm_close(self->ircomm);
997 self->ircomm = NULL;
998 }
999
1000 spin_unlock_irqrestore(&self->spinlock, flags);
1001}
1002
1003/*
1004 * Function ircomm_tty_hangup (tty)
1005 *
1006 * This routine notifies the tty driver that it should hangup the tty
1007 * device.
1008 *
1009 */
1010static void ircomm_tty_hangup(struct tty_struct *tty)
1011{
1012 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
1013 unsigned long flags;
1014
1015 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
1016
1017 IRDA_ASSERT(self != NULL, return;);
1018 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
1019
1020 if (!tty)
1021 return;
1022
1023 /* ircomm_tty_flush_buffer(tty); */
1024 ircomm_tty_shutdown(self);
1025
1026 /* I guess we need to lock here - Jean II */
1027 spin_lock_irqsave(&self->spinlock, flags);
1028 self->flags &= ~ASYNC_NORMAL_ACTIVE;
1029 self->tty = NULL;
1030 self->open_count = 0;
1031 spin_unlock_irqrestore(&self->spinlock, flags);
1032
1033 wake_up_interruptible(&self->open_wait);
1034}
1035
1036/*
1037 * Function ircomm_tty_send_xchar (tty, ch)
1038 *
1039 * This routine is used to send a high-priority XON/XOFF character to
1040 * the device.
1041 */
1042static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch)
1043{
1044 IRDA_DEBUG(0, "%s(), not impl\n", __FUNCTION__ );
1045}
1046
1047/*
1048 * Function ircomm_tty_start (tty)
1049 *
1050 * This routine notifies the tty driver that it resume sending
1051 * characters to the tty device.
1052 */
1053void ircomm_tty_start(struct tty_struct *tty)
1054{
1055 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
1056
1057 ircomm_flow_request(self->ircomm, FLOW_START);
1058}
1059
1060/*
1061 * Function ircomm_tty_stop (tty)
1062 *
1063 * This routine notifies the tty driver that it should stop outputting
1064 * characters to the tty device.
1065 */
1066static void ircomm_tty_stop(struct tty_struct *tty)
1067{
1068 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
1069
1070 IRDA_ASSERT(self != NULL, return;);
1071 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
1072
1073 ircomm_flow_request(self->ircomm, FLOW_STOP);
1074}
1075
1076/*
1077 * Function ircomm_check_modem_status (self)
1078 *
1079 * Check for any changes in the DCE's line settings. This function should
1080 * be called whenever the dce parameter settings changes, to update the
1081 * flow control settings and other things
1082 */
1083void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
1084{
1085 struct tty_struct *tty;
1086 int status;
1087
1088 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
1089
1090 IRDA_ASSERT(self != NULL, return;);
1091 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
1092
1093 tty = self->tty;
1094
1095 status = self->settings.dce;
1096
1097 if (status & IRCOMM_DCE_DELTA_ANY) {
1098 /*wake_up_interruptible(&self->delta_msr_wait);*/
1099 }
1100 if ((self->flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) {
1101 IRDA_DEBUG(2,
1102 "%s(), ircomm%d CD now %s...\n", __FUNCTION__ , self->line,
1103 (status & IRCOMM_CD) ? "on" : "off");
1104
1105 if (status & IRCOMM_CD) {
1106 wake_up_interruptible(&self->open_wait);
1107 } else {
1108 IRDA_DEBUG(2,
1109 "%s(), Doing serial hangup..\n", __FUNCTION__ );
1110 if (tty)
1111 tty_hangup(tty);
1112
1113 /* Hangup will remote the tty, so better break out */
1114 return;
1115 }
1116 }
1117 if (self->flags & ASYNC_CTS_FLOW) {
1118 if (tty->hw_stopped) {
1119 if (status & IRCOMM_CTS) {
1120 IRDA_DEBUG(2,
1121 "%s(), CTS tx start...\n", __FUNCTION__ );
1122 tty->hw_stopped = 0;
1123
1124 /* Wake up processes blocked on open */
1125 wake_up_interruptible(&self->open_wait);
1126
1127 schedule_work(&self->tqueue);
1128 return;
1129 }
1130 } else {
1131 if (!(status & IRCOMM_CTS)) {
1132 IRDA_DEBUG(2,
1133 "%s(), CTS tx stop...\n", __FUNCTION__ );
1134 tty->hw_stopped = 1;
1135 }
1136 }
1137 }
1138}
1139
1140/*
1141 * Function ircomm_tty_data_indication (instance, sap, skb)
1142 *
1143 * Handle incoming data, and deliver it to the line discipline
1144 *
1145 */
1146static int ircomm_tty_data_indication(void *instance, void *sap,
1147 struct sk_buff *skb)
1148{
1149 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
1150
1151 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
1152
1153 IRDA_ASSERT(self != NULL, return -1;);
1154 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
1155 IRDA_ASSERT(skb != NULL, return -1;);
1156
1157 if (!self->tty) {
1158 IRDA_DEBUG(0, "%s(), no tty!\n", __FUNCTION__ );
1159 return 0;
1160 }
1161
1162 /*
1163 * If we receive data when hardware is stopped then something is wrong.
1164 * We try to poll the peers line settings to check if we are up todate.
1165 * Devices like WinCE can do this, and since they don't send any
1166 * params, we can just as well declare the hardware for running.
1167 */
1168 if (self->tty->hw_stopped && (self->flow == FLOW_START)) {
1169 IRDA_DEBUG(0, "%s(), polling for line settings!\n", __FUNCTION__ );
1170 ircomm_param_request(self, IRCOMM_POLL, TRUE);
1171
1172 /* We can just as well declare the hardware for running */
1173 ircomm_tty_send_initial_parameters(self);
1174 ircomm_tty_link_established(self);
1175 }
1176
1177 /*
1178 * Just give it over to the line discipline. There is no need to
1179 * involve the flip buffers, since we are not running in an interrupt
1180 * handler
1181 */
1182 self->tty->ldisc.receive_buf(self->tty, skb->data, NULL, skb->len);
1183
1184 /* No need to kfree_skb - see ircomm_ttp_data_indication() */
1185
1186 return 0;
1187}
1188
1189/*
1190 * Function ircomm_tty_control_indication (instance, sap, skb)
1191 *
1192 * Parse all incoming parameters (easy!)
1193 *
1194 */
1195static int ircomm_tty_control_indication(void *instance, void *sap,
1196 struct sk_buff *skb)
1197{
1198 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
1199 int clen;
1200
1201 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
1202
1203 IRDA_ASSERT(self != NULL, return -1;);
1204 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
1205 IRDA_ASSERT(skb != NULL, return -1;);
1206
1207 clen = skb->data[0];
1208
1209 irda_param_extract_all(self, skb->data+1, IRDA_MIN(skb->len-1, clen),
1210 &ircomm_param_info);
1211
1212 /* No need to kfree_skb - see ircomm_control_indication() */
1213
1214 return 0;
1215}
1216
1217/*
1218 * Function ircomm_tty_flow_indication (instance, sap, cmd)
1219 *
1220 * This function is called by IrTTP when it wants us to slow down the
1221 * transmission of data. We just mark the hardware as stopped, and wait
1222 * for IrTTP to notify us that things are OK again.
1223 */
1224static void ircomm_tty_flow_indication(void *instance, void *sap,
1225 LOCAL_FLOW cmd)
1226{
1227 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
1228 struct tty_struct *tty;
1229
1230 IRDA_ASSERT(self != NULL, return;);
1231 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
1232
1233 tty = self->tty;
1234
1235 switch (cmd) {
1236 case FLOW_START:
1237 IRDA_DEBUG(2, "%s(), hw start!\n", __FUNCTION__ );
1238 tty->hw_stopped = 0;
1239
1240 /* ircomm_tty_do_softint will take care of the rest */
1241 schedule_work(&self->tqueue);
1242 break;
1243 default: /* If we get here, something is very wrong, better stop */
1244 case FLOW_STOP:
1245 IRDA_DEBUG(2, "%s(), hw stopped!\n", __FUNCTION__ );
1246 tty->hw_stopped = 1;
1247 break;
1248 }
1249 self->flow = cmd;
1250}
1251
1252static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf)
1253{
1254 int ret=0;
1255
1256 ret += sprintf(buf+ret, "State: %s\n", ircomm_tty_state[self->state]);
1257
1258 ret += sprintf(buf+ret, "Service type: ");
1259 if (self->service_type & IRCOMM_9_WIRE)
1260 ret += sprintf(buf+ret, "9_WIRE");
1261 else if (self->service_type & IRCOMM_3_WIRE)
1262 ret += sprintf(buf+ret, "3_WIRE");
1263 else if (self->service_type & IRCOMM_3_WIRE_RAW)
1264 ret += sprintf(buf+ret, "3_WIRE_RAW");
1265 else
1266 ret += sprintf(buf+ret, "No common service type!\n");
1267 ret += sprintf(buf+ret, "\n");
1268
1269 ret += sprintf(buf+ret, "Port name: %s\n", self->settings.port_name);
1270
1271 ret += sprintf(buf+ret, "DTE status: ");
1272 if (self->settings.dte & IRCOMM_RTS)
1273 ret += sprintf(buf+ret, "RTS|");
1274 if (self->settings.dte & IRCOMM_DTR)
1275 ret += sprintf(buf+ret, "DTR|");
1276 if (self->settings.dte)
1277 ret--; /* remove the last | */
1278 ret += sprintf(buf+ret, "\n");
1279
1280 ret += sprintf(buf+ret, "DCE status: ");
1281 if (self->settings.dce & IRCOMM_CTS)
1282 ret += sprintf(buf+ret, "CTS|");
1283 if (self->settings.dce & IRCOMM_DSR)
1284 ret += sprintf(buf+ret, "DSR|");
1285 if (self->settings.dce & IRCOMM_CD)
1286 ret += sprintf(buf+ret, "CD|");
1287 if (self->settings.dce & IRCOMM_RI)
1288 ret += sprintf(buf+ret, "RI|");
1289 if (self->settings.dce)
1290 ret--; /* remove the last | */
1291 ret += sprintf(buf+ret, "\n");
1292
1293 ret += sprintf(buf+ret, "Configuration: ");
1294 if (!self->settings.null_modem)
1295 ret += sprintf(buf+ret, "DTE <-> DCE\n");
1296 else
1297 ret += sprintf(buf+ret,
1298 "DTE <-> DTE (null modem emulation)\n");
1299
1300 ret += sprintf(buf+ret, "Data rate: %d\n", self->settings.data_rate);
1301
1302 ret += sprintf(buf+ret, "Flow control: ");
1303 if (self->settings.flow_control & IRCOMM_XON_XOFF_IN)
1304 ret += sprintf(buf+ret, "XON_XOFF_IN|");
1305 if (self->settings.flow_control & IRCOMM_XON_XOFF_OUT)
1306 ret += sprintf(buf+ret, "XON_XOFF_OUT|");
1307 if (self->settings.flow_control & IRCOMM_RTS_CTS_IN)
1308 ret += sprintf(buf+ret, "RTS_CTS_IN|");
1309 if (self->settings.flow_control & IRCOMM_RTS_CTS_OUT)
1310 ret += sprintf(buf+ret, "RTS_CTS_OUT|");
1311 if (self->settings.flow_control & IRCOMM_DSR_DTR_IN)
1312 ret += sprintf(buf+ret, "DSR_DTR_IN|");
1313 if (self->settings.flow_control & IRCOMM_DSR_DTR_OUT)
1314 ret += sprintf(buf+ret, "DSR_DTR_OUT|");
1315 if (self->settings.flow_control & IRCOMM_ENQ_ACK_IN)
1316 ret += sprintf(buf+ret, "ENQ_ACK_IN|");
1317 if (self->settings.flow_control & IRCOMM_ENQ_ACK_OUT)
1318 ret += sprintf(buf+ret, "ENQ_ACK_OUT|");
1319 if (self->settings.flow_control)
1320 ret--; /* remove the last | */
1321 ret += sprintf(buf+ret, "\n");
1322
1323 ret += sprintf(buf+ret, "Flags: ");
1324 if (self->flags & ASYNC_CTS_FLOW)
1325 ret += sprintf(buf+ret, "ASYNC_CTS_FLOW|");
1326 if (self->flags & ASYNC_CHECK_CD)
1327 ret += sprintf(buf+ret, "ASYNC_CHECK_CD|");
1328 if (self->flags & ASYNC_INITIALIZED)
1329 ret += sprintf(buf+ret, "ASYNC_INITIALIZED|");
1330 if (self->flags & ASYNC_LOW_LATENCY)
1331 ret += sprintf(buf+ret, "ASYNC_LOW_LATENCY|");
1332 if (self->flags & ASYNC_CLOSING)
1333 ret += sprintf(buf+ret, "ASYNC_CLOSING|");
1334 if (self->flags & ASYNC_NORMAL_ACTIVE)
1335 ret += sprintf(buf+ret, "ASYNC_NORMAL_ACTIVE|");
1336 if (self->flags)
1337 ret--; /* remove the last | */
1338 ret += sprintf(buf+ret, "\n");
1339
1340 ret += sprintf(buf+ret, "Role: %s\n", self->client ?
1341 "client" : "server");
1342 ret += sprintf(buf+ret, "Open count: %d\n", self->open_count);
1343 ret += sprintf(buf+ret, "Max data size: %d\n", self->max_data_size);
1344 ret += sprintf(buf+ret, "Max header size: %d\n", self->max_header_size);
1345
1346 if (self->tty)
1347 ret += sprintf(buf+ret, "Hardware: %s\n",
1348 self->tty->hw_stopped ? "Stopped" : "Running");
1349
1350 ret += sprintf(buf+ret, "\n");
1351 return ret;
1352}
1353
1354
1355/*
1356 * Function ircomm_tty_read_proc (buf, start, offset, len, eof, unused)
1357 *
1358 *
1359 *
1360 */
1361#ifdef CONFIG_PROC_FS
1362static int ircomm_tty_read_proc(char *buf, char **start, off_t offset, int len,
1363 int *eof, void *unused)
1364{
1365 struct ircomm_tty_cb *self;
1366 int count = 0, l;
1367 off_t begin = 0;
1368 unsigned long flags;
1369
1370 spin_lock_irqsave(&ircomm_tty->hb_spinlock, flags);
1371
1372 self = (struct ircomm_tty_cb *) hashbin_get_first(ircomm_tty);
1373 while ((self != NULL) && (count < 4000)) {
1374 if (self->magic != IRCOMM_TTY_MAGIC)
1375 break;
1376
1377 l = ircomm_tty_line_info(self, buf + count);
1378 count += l;
1379 if (count+begin > offset+len)
1380 goto done;
1381 if (count+begin < offset) {
1382 begin += count;
1383 count = 0;
1384 }
1385
1386 self = (struct ircomm_tty_cb *) hashbin_get_next(ircomm_tty);
1387 }
1388 *eof = 1;
1389done:
1390 spin_unlock_irqrestore(&ircomm_tty->hb_spinlock, flags);
1391
1392 if (offset >= count+begin)
1393 return 0;
1394 *start = buf + (offset-begin);
1395 return ((len < begin+count-offset) ? len : begin+count-offset);
1396}
1397#endif /* CONFIG_PROC_FS */
1398
1399MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
1400MODULE_DESCRIPTION("IrCOMM serial TTY driver");
1401MODULE_LICENSE("GPL");
1402MODULE_ALIAS_CHARDEV_MAJOR(IRCOMM_TTY_MAJOR);
1403
1404module_init(ircomm_tty_init);
1405module_exit(ircomm_tty_cleanup);
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c
new file mode 100644
index 00000000000..99f5eddbb4b
--- /dev/null
+++ b/net/irda/ircomm/ircomm_tty_attach.c
@@ -0,0 +1,1006 @@
1/*********************************************************************
2 *
3 * Filename: ircomm_tty_attach.c
4 * Version:
5 * Description: Code for attaching the serial driver to IrCOMM
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sat Jun 5 17:42:00 1999
9 * Modified at: Tue Jan 4 14:20:49 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
13 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 * MA 02111-1307 USA
29 *
30 ********************************************************************/
31
32#include <linux/sched.h>
33#include <linux/init.h>
34
35#include <net/irda/irda.h>
36#include <net/irda/irlmp.h>
37#include <net/irda/iriap.h>
38#include <net/irda/irttp.h>
39#include <net/irda/irias_object.h>
40#include <net/irda/parameters.h>
41
42#include <net/irda/ircomm_core.h>
43#include <net/irda/ircomm_param.h>
44#include <net/irda/ircomm_event.h>
45
46#include <net/irda/ircomm_tty.h>
47#include <net/irda/ircomm_tty_attach.h>
48
49static void ircomm_tty_ias_register(struct ircomm_tty_cb *self);
50static void ircomm_tty_discovery_indication(discinfo_t *discovery,
51 DISCOVERY_MODE mode,
52 void *priv);
53static void ircomm_tty_getvalue_confirm(int result, __u16 obj_id,
54 struct ias_value *value, void *priv);
55static void ircomm_tty_start_watchdog_timer(struct ircomm_tty_cb *self,
56 int timeout);
57static void ircomm_tty_watchdog_timer_expired(void *data);
58
59static int ircomm_tty_state_idle(struct ircomm_tty_cb *self,
60 IRCOMM_TTY_EVENT event,
61 struct sk_buff *skb,
62 struct ircomm_tty_info *info);
63static int ircomm_tty_state_search(struct ircomm_tty_cb *self,
64 IRCOMM_TTY_EVENT event,
65 struct sk_buff *skb,
66 struct ircomm_tty_info *info);
67static int ircomm_tty_state_query_parameters(struct ircomm_tty_cb *self,
68 IRCOMM_TTY_EVENT event,
69 struct sk_buff *skb,
70 struct ircomm_tty_info *info);
71static int ircomm_tty_state_query_lsap_sel(struct ircomm_tty_cb *self,
72 IRCOMM_TTY_EVENT event,
73 struct sk_buff *skb,
74 struct ircomm_tty_info *info);
75static int ircomm_tty_state_setup(struct ircomm_tty_cb *self,
76 IRCOMM_TTY_EVENT event,
77 struct sk_buff *skb,
78 struct ircomm_tty_info *info);
79static int ircomm_tty_state_ready(struct ircomm_tty_cb *self,
80 IRCOMM_TTY_EVENT event,
81 struct sk_buff *skb,
82 struct ircomm_tty_info *info);
83
84char *ircomm_tty_state[] = {
85 "IRCOMM_TTY_IDLE",
86 "IRCOMM_TTY_SEARCH",
87 "IRCOMM_TTY_QUERY_PARAMETERS",
88 "IRCOMM_TTY_QUERY_LSAP_SEL",
89 "IRCOMM_TTY_SETUP",
90 "IRCOMM_TTY_READY",
91 "*** ERROR *** ",
92};
93
94#ifdef CONFIG_IRDA_DEBUG
95static char *ircomm_tty_event[] = {
96 "IRCOMM_TTY_ATTACH_CABLE",
97 "IRCOMM_TTY_DETACH_CABLE",
98 "IRCOMM_TTY_DATA_REQUEST",
99 "IRCOMM_TTY_DATA_INDICATION",
100 "IRCOMM_TTY_DISCOVERY_REQUEST",
101 "IRCOMM_TTY_DISCOVERY_INDICATION",
102 "IRCOMM_TTY_CONNECT_CONFIRM",
103 "IRCOMM_TTY_CONNECT_INDICATION",
104 "IRCOMM_TTY_DISCONNECT_REQUEST",
105 "IRCOMM_TTY_DISCONNECT_INDICATION",
106 "IRCOMM_TTY_WD_TIMER_EXPIRED",
107 "IRCOMM_TTY_GOT_PARAMETERS",
108 "IRCOMM_TTY_GOT_LSAPSEL",
109 "*** ERROR ****",
110};
111#endif /* CONFIG_IRDA_DEBUG */
112
113static int (*state[])(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event,
114 struct sk_buff *skb, struct ircomm_tty_info *info) =
115{
116 ircomm_tty_state_idle,
117 ircomm_tty_state_search,
118 ircomm_tty_state_query_parameters,
119 ircomm_tty_state_query_lsap_sel,
120 ircomm_tty_state_setup,
121 ircomm_tty_state_ready,
122};
123
124/*
125 * Function ircomm_tty_attach_cable (driver)
126 *
127 * Try to attach cable (IrCOMM link). This function will only return
128 * when the link has been connected, or if an error condition occurs.
129 * If success, the return value is the resulting service type.
130 */
131int ircomm_tty_attach_cable(struct ircomm_tty_cb *self)
132{
133 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
134
135 IRDA_ASSERT(self != NULL, return -1;);
136 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
137
138 /* Check if somebody has already connected to us */
139 if (ircomm_is_connected(self->ircomm)) {
140 IRDA_DEBUG(0, "%s(), already connected!\n", __FUNCTION__ );
141 return 0;
142 }
143
144 /* Make sure nobody tries to write before the link is up */
145 self->tty->hw_stopped = 1;
146
147 ircomm_tty_ias_register(self);
148
149 ircomm_tty_do_event(self, IRCOMM_TTY_ATTACH_CABLE, NULL, NULL);
150
151 return 0;
152}
153
154/*
155 * Function ircomm_detach_cable (driver)
156 *
157 * Detach cable, or cable has been detached by peer
158 *
159 */
160void ircomm_tty_detach_cable(struct ircomm_tty_cb *self)
161{
162 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
163
164 IRDA_ASSERT(self != NULL, return;);
165 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
166
167 del_timer(&self->watchdog_timer);
168
169 /* Remove discovery handler */
170 if (self->ckey) {
171 irlmp_unregister_client(self->ckey);
172 self->ckey = NULL;
173 }
174 /* Remove IrCOMM hint bits */
175 if (self->skey) {
176 irlmp_unregister_service(self->skey);
177 self->skey = NULL;
178 }
179
180 if (self->iriap) {
181 iriap_close(self->iriap);
182 self->iriap = NULL;
183 }
184
185 /* Remove LM-IAS object */
186 if (self->obj) {
187 irias_delete_object(self->obj);
188 self->obj = NULL;
189 }
190
191 ircomm_tty_do_event(self, IRCOMM_TTY_DETACH_CABLE, NULL, NULL);
192
193 /* Reset some values */
194 self->daddr = self->saddr = 0;
195 self->dlsap_sel = self->slsap_sel = 0;
196
197 memset(&self->settings, 0, sizeof(struct ircomm_params));
198}
199
200/*
201 * Function ircomm_tty_ias_register (self)
202 *
203 * Register with LM-IAS depending on which service type we are
204 *
205 */
206static void ircomm_tty_ias_register(struct ircomm_tty_cb *self)
207{
208 __u8 oct_seq[6];
209 __u16 hints;
210
211 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
212
213 IRDA_ASSERT(self != NULL, return;);
214 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
215
216 /* Compute hint bits based on service */
217 hints = irlmp_service_to_hint(S_COMM);
218 if (self->service_type & IRCOMM_3_WIRE_RAW)
219 hints |= irlmp_service_to_hint(S_PRINTER);
220
221 /* Advertise IrCOMM hint bit in discovery */
222 if (!self->skey)
223 self->skey = irlmp_register_service(hints);
224 /* Set up a discovery handler */
225 if (!self->ckey)
226 self->ckey = irlmp_register_client(hints,
227 ircomm_tty_discovery_indication,
228 NULL, (void *) self);
229
230 /* If already done, no need to do it again */
231 if (self->obj)
232 return;
233
234 if (self->service_type & IRCOMM_3_WIRE_RAW) {
235 /* Register IrLPT with LM-IAS */
236 self->obj = irias_new_object("IrLPT", IAS_IRLPT_ID);
237 irias_add_integer_attrib(self->obj, "IrDA:IrLMP:LsapSel",
238 self->slsap_sel, IAS_KERNEL_ATTR);
239 } else {
240 /* Register IrCOMM with LM-IAS */
241 self->obj = irias_new_object("IrDA:IrCOMM", IAS_IRCOMM_ID);
242 irias_add_integer_attrib(self->obj, "IrDA:TinyTP:LsapSel",
243 self->slsap_sel, IAS_KERNEL_ATTR);
244
245 /* Code the parameters into the buffer */
246 irda_param_pack(oct_seq, "bbbbbb",
247 IRCOMM_SERVICE_TYPE, 1, self->service_type,
248 IRCOMM_PORT_TYPE, 1, IRCOMM_SERIAL);
249
250 /* Register parameters with LM-IAS */
251 irias_add_octseq_attrib(self->obj, "Parameters", oct_seq, 6,
252 IAS_KERNEL_ATTR);
253 }
254 irias_insert_object(self->obj);
255}
256
257/*
258 * Function ircomm_tty_ias_unregister (self)
259 *
260 * Remove our IAS object and client hook while connected.
261 *
262 */
263static void ircomm_tty_ias_unregister(struct ircomm_tty_cb *self)
264{
265 /* Remove LM-IAS object now so it is not reused.
266 * IrCOMM deals very poorly with multiple incoming connections.
267 * It should looks a lot more like IrNET, and "dup" a server TSAP
268 * to the application TSAP (based on various rules).
269 * This is a cheap workaround allowing multiple clients to
270 * connect to us. It will not always work.
271 * Each IrCOMM socket has an IAS entry. Incoming connection will
272 * pick the first one found. So, when we are fully connected,
273 * we remove our IAS entries so that the next IAS entry is used.
274 * We do that for *both* client and server, because a server
275 * can also create client instances.
276 * Jean II */
277 if (self->obj) {
278 irias_delete_object(self->obj);
279 self->obj = NULL;
280 }
281
282#if 0
283 /* Remove discovery handler.
284 * While we are connected, we no longer need to receive
285 * discovery events. This would be the case if there is
286 * multiple IrLAP interfaces. Jean II */
287 if (self->ckey) {
288 irlmp_unregister_client(self->ckey);
289 self->ckey = NULL;
290 }
291#endif
292}
293
294/*
295 * Function ircomm_send_initial_parameters (self)
296 *
297 * Send initial parameters to the remote IrCOMM device. These parameters
298 * must be sent before any data.
299 */
300int ircomm_tty_send_initial_parameters(struct ircomm_tty_cb *self)
301{
302 IRDA_ASSERT(self != NULL, return -1;);
303 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
304
305 if (self->service_type & IRCOMM_3_WIRE_RAW)
306 return 0;
307
308 /*
309 * Set default values, but only if the application for some reason
310 * haven't set them already
311 */
312 IRDA_DEBUG(2, "%s(), data-rate = %d\n", __FUNCTION__ ,
313 self->settings.data_rate);
314 if (!self->settings.data_rate)
315 self->settings.data_rate = 9600;
316 IRDA_DEBUG(2, "%s(), data-format = %d\n", __FUNCTION__ ,
317 self->settings.data_format);
318 if (!self->settings.data_format)
319 self->settings.data_format = IRCOMM_WSIZE_8; /* 8N1 */
320
321 IRDA_DEBUG(2, "%s(), flow-control = %d\n", __FUNCTION__ ,
322 self->settings.flow_control);
323 /*self->settings.flow_control = IRCOMM_RTS_CTS_IN|IRCOMM_RTS_CTS_OUT;*/
324
325 /* Do not set delta values for the initial parameters */
326 self->settings.dte = IRCOMM_DTR | IRCOMM_RTS;
327
328 /* Only send service type parameter when we are the client */
329 if (self->client)
330 ircomm_param_request(self, IRCOMM_SERVICE_TYPE, FALSE);
331 ircomm_param_request(self, IRCOMM_DATA_RATE, FALSE);
332 ircomm_param_request(self, IRCOMM_DATA_FORMAT, FALSE);
333
334 /* For a 3 wire service, we just flush the last parameter and return */
335 if (self->settings.service_type == IRCOMM_3_WIRE) {
336 ircomm_param_request(self, IRCOMM_FLOW_CONTROL, TRUE);
337 return 0;
338 }
339
340 /* Only 9-wire service types continue here */
341 ircomm_param_request(self, IRCOMM_FLOW_CONTROL, FALSE);
342#if 0
343 ircomm_param_request(self, IRCOMM_XON_XOFF, FALSE);
344 ircomm_param_request(self, IRCOMM_ENQ_ACK, FALSE);
345#endif
346 /* Notify peer that we are ready to receive data */
347 ircomm_param_request(self, IRCOMM_DTE, TRUE);
348
349 return 0;
350}
351
352/*
353 * Function ircomm_tty_discovery_indication (discovery)
354 *
355 * Remote device is discovered, try query the remote IAS to see which
356 * device it is, and which services it has.
357 *
358 */
359static void ircomm_tty_discovery_indication(discinfo_t *discovery,
360 DISCOVERY_MODE mode,
361 void *priv)
362{
363 struct ircomm_tty_cb *self;
364 struct ircomm_tty_info info;
365
366 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
367
368 /* Important note :
369 * We need to drop all passive discoveries.
370 * The LSAP management of IrComm is deficient and doesn't deal
371 * with the case of two instance connecting to each other
372 * simultaneously (it will deadlock in LMP).
373 * The proper fix would be to use the same technique as in IrNET,
374 * to have one server socket and separate instances for the
375 * connecting/connected socket.
376 * The workaround is to drop passive discovery, which drastically
377 * reduce the probability of this happening.
378 * Jean II */
379 if(mode == DISCOVERY_PASSIVE)
380 return;
381
382 info.daddr = discovery->daddr;
383 info.saddr = discovery->saddr;
384
385 /* FIXME. We have a locking problem on the hashbin here.
386 * We probably need to use hashbin_find_next(), but we first
387 * need to ensure that "line" is unique. - Jean II */
388 self = (struct ircomm_tty_cb *) hashbin_get_first(ircomm_tty);
389 while (self != NULL) {
390 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
391
392 ircomm_tty_do_event(self, IRCOMM_TTY_DISCOVERY_INDICATION,
393 NULL, &info);
394
395 self = (struct ircomm_tty_cb *) hashbin_get_next(ircomm_tty);
396 }
397}
398
399/*
400 * Function ircomm_tty_disconnect_indication (instance, sap, reason, skb)
401 *
402 * Link disconnected
403 *
404 */
405void ircomm_tty_disconnect_indication(void *instance, void *sap,
406 LM_REASON reason,
407 struct sk_buff *skb)
408{
409 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
410
411 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
412
413 IRDA_ASSERT(self != NULL, return;);
414 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
415
416 if (!self->tty)
417 return;
418
419 /* This will stop control data transfers */
420 self->flow = FLOW_STOP;
421
422 /* Stop data transfers */
423 self->tty->hw_stopped = 1;
424
425 ircomm_tty_do_event(self, IRCOMM_TTY_DISCONNECT_INDICATION, NULL,
426 NULL);
427}
428
429/*
430 * Function ircomm_tty_getvalue_confirm (result, obj_id, value, priv)
431 *
432 * Got result from the IAS query we make
433 *
434 */
435static void ircomm_tty_getvalue_confirm(int result, __u16 obj_id,
436 struct ias_value *value,
437 void *priv)
438{
439 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) priv;
440
441 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
442
443 IRDA_ASSERT(self != NULL, return;);
444 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
445
446 /* We probably don't need to make any more queries */
447 iriap_close(self->iriap);
448 self->iriap = NULL;
449
450 /* Check if request succeeded */
451 if (result != IAS_SUCCESS) {
452 IRDA_DEBUG(4, "%s(), got NULL value!\n", __FUNCTION__ );
453 return;
454 }
455
456 switch (value->type) {
457 case IAS_OCT_SEQ:
458 IRDA_DEBUG(2, "%s(), got octet sequence\n", __FUNCTION__ );
459
460 irda_param_extract_all(self, value->t.oct_seq, value->len,
461 &ircomm_param_info);
462
463 ircomm_tty_do_event(self, IRCOMM_TTY_GOT_PARAMETERS, NULL,
464 NULL);
465 break;
466 case IAS_INTEGER:
467 /* Got LSAP selector */
468 IRDA_DEBUG(2, "%s(), got lsapsel = %d\n", __FUNCTION__ ,
469 value->t.integer);
470
471 if (value->t.integer == -1) {
472 IRDA_DEBUG(0, "%s(), invalid value!\n", __FUNCTION__ );
473 } else
474 self->dlsap_sel = value->t.integer;
475
476 ircomm_tty_do_event(self, IRCOMM_TTY_GOT_LSAPSEL, NULL, NULL);
477 break;
478 case IAS_MISSING:
479 IRDA_DEBUG(0, "%s(), got IAS_MISSING\n", __FUNCTION__ );
480 break;
481 default:
482 IRDA_DEBUG(0, "%s(), got unknown type!\n", __FUNCTION__ );
483 break;
484 }
485 irias_delete_value(value);
486}
487
488/*
489 * Function ircomm_tty_connect_confirm (instance, sap, qos, max_sdu_size, skb)
490 *
491 * Connection confirmed
492 *
493 */
494void ircomm_tty_connect_confirm(void *instance, void *sap,
495 struct qos_info *qos,
496 __u32 max_data_size,
497 __u8 max_header_size,
498 struct sk_buff *skb)
499{
500 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
501
502 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
503
504 IRDA_ASSERT(self != NULL, return;);
505 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
506
507 self->client = TRUE;
508 self->max_data_size = max_data_size;
509 self->max_header_size = max_header_size;
510 self->flow = FLOW_START;
511
512 ircomm_tty_do_event(self, IRCOMM_TTY_CONNECT_CONFIRM, NULL, NULL);
513
514 /* No need to kfree_skb - see ircomm_ttp_connect_confirm() */
515}
516
517/*
518 * Function ircomm_tty_connect_indication (instance, sap, qos, max_sdu_size,
519 * skb)
520 *
521 * we are discovered and being requested to connect by remote device !
522 *
523 */
524void ircomm_tty_connect_indication(void *instance, void *sap,
525 struct qos_info *qos,
526 __u32 max_data_size,
527 __u8 max_header_size,
528 struct sk_buff *skb)
529{
530 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
531 int clen;
532
533 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
534
535 IRDA_ASSERT(self != NULL, return;);
536 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
537
538 self->client = FALSE;
539 self->max_data_size = max_data_size;
540 self->max_header_size = max_header_size;
541 self->flow = FLOW_START;
542
543 clen = skb->data[0];
544 if (clen)
545 irda_param_extract_all(self, skb->data+1,
546 IRDA_MIN(skb->len, clen),
547 &ircomm_param_info);
548
549 ircomm_tty_do_event(self, IRCOMM_TTY_CONNECT_INDICATION, NULL, NULL);
550
551 /* No need to kfree_skb - see ircomm_ttp_connect_indication() */
552}
553
554/*
555 * Function ircomm_tty_link_established (self)
556 *
557 * Called when the IrCOMM link is established
558 *
559 */
560void ircomm_tty_link_established(struct ircomm_tty_cb *self)
561{
562 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
563
564 IRDA_ASSERT(self != NULL, return;);
565 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
566
567 if (!self->tty)
568 return;
569
570 del_timer(&self->watchdog_timer);
571
572 /*
573 * IrCOMM link is now up, and if we are not using hardware
574 * flow-control, then declare the hardware as running. Otherwise we
575 * will have to wait for the peer device (DCE) to raise the CTS
576 * line.
577 */
578 if ((self->flags & ASYNC_CTS_FLOW) && ((self->settings.dce & IRCOMM_CTS) == 0)) {
579 IRDA_DEBUG(0, "%s(), waiting for CTS ...\n", __FUNCTION__ );
580 return;
581 } else {
582 IRDA_DEBUG(1, "%s(), starting hardware!\n", __FUNCTION__ );
583
584 self->tty->hw_stopped = 0;
585
586 /* Wake up processes blocked on open */
587 wake_up_interruptible(&self->open_wait);
588 }
589
590 schedule_work(&self->tqueue);
591}
592
593/*
594 * Function ircomm_tty_start_watchdog_timer (self, timeout)
595 *
596 * Start the watchdog timer. This timer is used to make sure that any
597 * connection attempt is successful, and if not, we will retry after
598 * the timeout
599 */
600static void ircomm_tty_start_watchdog_timer(struct ircomm_tty_cb *self,
601 int timeout)
602{
603 IRDA_ASSERT(self != NULL, return;);
604 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
605
606 irda_start_timer(&self->watchdog_timer, timeout, (void *) self,
607 ircomm_tty_watchdog_timer_expired);
608}
609
610/*
611 * Function ircomm_tty_watchdog_timer_expired (data)
612 *
613 * Called when the connect procedure have taken to much time.
614 *
615 */
616static void ircomm_tty_watchdog_timer_expired(void *data)
617{
618 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) data;
619
620 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
621
622 IRDA_ASSERT(self != NULL, return;);
623 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
624
625 ircomm_tty_do_event(self, IRCOMM_TTY_WD_TIMER_EXPIRED, NULL, NULL);
626}
627
628
629/*
630 * Function ircomm_tty_do_event (self, event, skb)
631 *
632 * Process event
633 *
634 */
635int ircomm_tty_do_event(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event,
636 struct sk_buff *skb, struct ircomm_tty_info *info)
637{
638 IRDA_ASSERT(self != NULL, return -1;);
639 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
640
641 IRDA_DEBUG(2, "%s: state=%s, event=%s\n", __FUNCTION__ ,
642 ircomm_tty_state[self->state], ircomm_tty_event[event]);
643
644 return (*state[self->state])(self, event, skb, info);
645}
646
647/*
648 * Function ircomm_tty_next_state (self, state)
649 *
650 * Switch state
651 *
652 */
653static inline void ircomm_tty_next_state(struct ircomm_tty_cb *self, IRCOMM_TTY_STATE state)
654{
655 /*
656 IRDA_ASSERT(self != NULL, return;);
657 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
658
659 IRDA_DEBUG(2, "%s: next state=%s, service type=%d\n", __FUNCTION__ ,
660 ircomm_tty_state[self->state], self->service_type);
661 */
662 self->state = state;
663}
664
665/*
666 * Function ircomm_tty_state_idle (self, event, skb, info)
667 *
668 * Just hanging around
669 *
670 */
671static int ircomm_tty_state_idle(struct ircomm_tty_cb *self,
672 IRCOMM_TTY_EVENT event,
673 struct sk_buff *skb,
674 struct ircomm_tty_info *info)
675{
676 int ret = 0;
677
678 IRDA_DEBUG(2, "%s: state=%s, event=%s\n", __FUNCTION__ ,
679 ircomm_tty_state[self->state], ircomm_tty_event[event]);
680 switch (event) {
681 case IRCOMM_TTY_ATTACH_CABLE:
682 /* Try to discover any remote devices */
683 ircomm_tty_start_watchdog_timer(self, 3*HZ);
684 ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);
685
686 irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS);
687 break;
688 case IRCOMM_TTY_DISCOVERY_INDICATION:
689 self->daddr = info->daddr;
690 self->saddr = info->saddr;
691
692 if (self->iriap) {
693 IRDA_WARNING("%s(), busy with a previous query\n",
694 __FUNCTION__);
695 return -EBUSY;
696 }
697
698 self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
699 ircomm_tty_getvalue_confirm);
700
701 iriap_getvaluebyclass_request(self->iriap,
702 self->saddr, self->daddr,
703 "IrDA:IrCOMM", "Parameters");
704
705 ircomm_tty_start_watchdog_timer(self, 3*HZ);
706 ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_PARAMETERS);
707 break;
708 case IRCOMM_TTY_CONNECT_INDICATION:
709 del_timer(&self->watchdog_timer);
710
711 /* Accept connection */
712 ircomm_connect_response(self->ircomm, NULL);
713 ircomm_tty_next_state(self, IRCOMM_TTY_READY);
714 break;
715 case IRCOMM_TTY_WD_TIMER_EXPIRED:
716 /* Just stay idle */
717 break;
718 case IRCOMM_TTY_DETACH_CABLE:
719 ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
720 break;
721 default:
722 IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
723 ircomm_tty_event[event]);
724 ret = -EINVAL;
725 }
726 return ret;
727}
728
729/*
730 * Function ircomm_tty_state_search (self, event, skb, info)
731 *
732 * Trying to discover an IrCOMM device
733 *
734 */
735static int ircomm_tty_state_search(struct ircomm_tty_cb *self,
736 IRCOMM_TTY_EVENT event,
737 struct sk_buff *skb,
738 struct ircomm_tty_info *info)
739{
740 int ret = 0;
741
742 IRDA_DEBUG(2, "%s: state=%s, event=%s\n", __FUNCTION__ ,
743 ircomm_tty_state[self->state], ircomm_tty_event[event]);
744
745 switch (event) {
746 case IRCOMM_TTY_DISCOVERY_INDICATION:
747 self->daddr = info->daddr;
748 self->saddr = info->saddr;
749
750 if (self->iriap) {
751 IRDA_WARNING("%s(), busy with a previous query\n",
752 __FUNCTION__);
753 return -EBUSY;
754 }
755
756 self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
757 ircomm_tty_getvalue_confirm);
758
759 if (self->service_type == IRCOMM_3_WIRE_RAW) {
760 iriap_getvaluebyclass_request(self->iriap, self->saddr,
761 self->daddr, "IrLPT",
762 "IrDA:IrLMP:LsapSel");
763 ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_LSAP_SEL);
764 } else {
765 iriap_getvaluebyclass_request(self->iriap, self->saddr,
766 self->daddr,
767 "IrDA:IrCOMM",
768 "Parameters");
769
770 ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_PARAMETERS);
771 }
772 ircomm_tty_start_watchdog_timer(self, 3*HZ);
773 break;
774 case IRCOMM_TTY_CONNECT_INDICATION:
775 del_timer(&self->watchdog_timer);
776 ircomm_tty_ias_unregister(self);
777
778 /* Accept connection */
779 ircomm_connect_response(self->ircomm, NULL);
780 ircomm_tty_next_state(self, IRCOMM_TTY_READY);
781 break;
782 case IRCOMM_TTY_WD_TIMER_EXPIRED:
783#if 1
784 /* Give up */
785#else
786 /* Try to discover any remote devices */
787 ircomm_tty_start_watchdog_timer(self, 3*HZ);
788 irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS);
789#endif
790 break;
791 case IRCOMM_TTY_DETACH_CABLE:
792 ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
793 break;
794 default:
795 IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
796 ircomm_tty_event[event]);
797 ret = -EINVAL;
798 }
799 return ret;
800}
801
802/*
803 * Function ircomm_tty_state_query (self, event, skb, info)
804 *
805 * Querying the remote LM-IAS for IrCOMM parameters
806 *
807 */
808static int ircomm_tty_state_query_parameters(struct ircomm_tty_cb *self,
809 IRCOMM_TTY_EVENT event,
810 struct sk_buff *skb,
811 struct ircomm_tty_info *info)
812{
813 int ret = 0;
814
815 IRDA_DEBUG(2, "%s: state=%s, event=%s\n", __FUNCTION__ ,
816 ircomm_tty_state[self->state], ircomm_tty_event[event]);
817
818 switch (event) {
819 case IRCOMM_TTY_GOT_PARAMETERS:
820 if (self->iriap) {
821 IRDA_WARNING("%s(), busy with a previous query\n",
822 __FUNCTION__);
823 return -EBUSY;
824 }
825
826 self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
827 ircomm_tty_getvalue_confirm);
828
829 iriap_getvaluebyclass_request(self->iriap, self->saddr,
830 self->daddr, "IrDA:IrCOMM",
831 "IrDA:TinyTP:LsapSel");
832
833 ircomm_tty_start_watchdog_timer(self, 3*HZ);
834 ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_LSAP_SEL);
835 break;
836 case IRCOMM_TTY_WD_TIMER_EXPIRED:
837 /* Go back to search mode */
838 ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);
839 ircomm_tty_start_watchdog_timer(self, 3*HZ);
840 break;
841 case IRCOMM_TTY_CONNECT_INDICATION:
842 del_timer(&self->watchdog_timer);
843 ircomm_tty_ias_unregister(self);
844
845 /* Accept connection */
846 ircomm_connect_response(self->ircomm, NULL);
847 ircomm_tty_next_state(self, IRCOMM_TTY_READY);
848 break;
849 case IRCOMM_TTY_DETACH_CABLE:
850 ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
851 break;
852 default:
853 IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
854 ircomm_tty_event[event]);
855 ret = -EINVAL;
856 }
857 return ret;
858}
859
860/*
861 * Function ircomm_tty_state_query_lsap_sel (self, event, skb, info)
862 *
863 * Query remote LM-IAS for the LSAP selector which we can connect to
864 *
865 */
866static int ircomm_tty_state_query_lsap_sel(struct ircomm_tty_cb *self,
867 IRCOMM_TTY_EVENT event,
868 struct sk_buff *skb,
869 struct ircomm_tty_info *info)
870{
871 int ret = 0;
872
873 IRDA_DEBUG(2, "%s: state=%s, event=%s\n", __FUNCTION__ ,
874 ircomm_tty_state[self->state], ircomm_tty_event[event]);
875
876 switch (event) {
877 case IRCOMM_TTY_GOT_LSAPSEL:
878 /* Connect to remote device */
879 ret = ircomm_connect_request(self->ircomm, self->dlsap_sel,
880 self->saddr, self->daddr,
881 NULL, self->service_type);
882 ircomm_tty_start_watchdog_timer(self, 3*HZ);
883 ircomm_tty_next_state(self, IRCOMM_TTY_SETUP);
884 break;
885 case IRCOMM_TTY_WD_TIMER_EXPIRED:
886 /* Go back to search mode */
887 ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);
888 ircomm_tty_start_watchdog_timer(self, 3*HZ);
889 break;
890 case IRCOMM_TTY_CONNECT_INDICATION:
891 del_timer(&self->watchdog_timer);
892 ircomm_tty_ias_unregister(self);
893
894 /* Accept connection */
895 ircomm_connect_response(self->ircomm, NULL);
896 ircomm_tty_next_state(self, IRCOMM_TTY_READY);
897 break;
898 case IRCOMM_TTY_DETACH_CABLE:
899 ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
900 break;
901 default:
902 IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
903 ircomm_tty_event[event]);
904 ret = -EINVAL;
905 }
906 return ret;
907}
908
909/*
910 * Function ircomm_tty_state_setup (self, event, skb, info)
911 *
912 * Trying to connect
913 *
914 */
915static int ircomm_tty_state_setup(struct ircomm_tty_cb *self,
916 IRCOMM_TTY_EVENT event,
917 struct sk_buff *skb,
918 struct ircomm_tty_info *info)
919{
920 int ret = 0;
921
922 IRDA_DEBUG(2, "%s: state=%s, event=%s\n", __FUNCTION__ ,
923 ircomm_tty_state[self->state], ircomm_tty_event[event]);
924
925 switch (event) {
926 case IRCOMM_TTY_CONNECT_CONFIRM:
927 del_timer(&self->watchdog_timer);
928 ircomm_tty_ias_unregister(self);
929
930 /*
931 * Send initial parameters. This will also send out queued
932 * parameters waiting for the connection to come up
933 */
934 ircomm_tty_send_initial_parameters(self);
935 ircomm_tty_link_established(self);
936 ircomm_tty_next_state(self, IRCOMM_TTY_READY);
937 break;
938 case IRCOMM_TTY_CONNECT_INDICATION:
939 del_timer(&self->watchdog_timer);
940 ircomm_tty_ias_unregister(self);
941
942 /* Accept connection */
943 ircomm_connect_response(self->ircomm, NULL);
944 ircomm_tty_next_state(self, IRCOMM_TTY_READY);
945 break;
946 case IRCOMM_TTY_WD_TIMER_EXPIRED:
947 /* Go back to search mode */
948 ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);
949 ircomm_tty_start_watchdog_timer(self, 3*HZ);
950 break;
951 case IRCOMM_TTY_DETACH_CABLE:
952 /* ircomm_disconnect_request(self->ircomm, NULL); */
953 ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
954 break;
955 default:
956 IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
957 ircomm_tty_event[event]);
958 ret = -EINVAL;
959 }
960 return ret;
961}
962
963/*
964 * Function ircomm_tty_state_ready (self, event, skb, info)
965 *
966 * IrCOMM is now connected
967 *
968 */
969static int ircomm_tty_state_ready(struct ircomm_tty_cb *self,
970 IRCOMM_TTY_EVENT event,
971 struct sk_buff *skb,
972 struct ircomm_tty_info *info)
973{
974 int ret = 0;
975
976 switch (event) {
977 case IRCOMM_TTY_DATA_REQUEST:
978 ret = ircomm_data_request(self->ircomm, skb);
979 break;
980 case IRCOMM_TTY_DETACH_CABLE:
981 ircomm_disconnect_request(self->ircomm, NULL);
982 ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
983 break;
984 case IRCOMM_TTY_DISCONNECT_INDICATION:
985 ircomm_tty_ias_register(self);
986 ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);
987 ircomm_tty_start_watchdog_timer(self, 3*HZ);
988
989 if (self->flags & ASYNC_CHECK_CD) {
990 /* Drop carrier */
991 self->settings.dce = IRCOMM_DELTA_CD;
992 ircomm_tty_check_modem_status(self);
993 } else {
994 IRDA_DEBUG(0, "%s(), hanging up!\n", __FUNCTION__ );
995 if (self->tty)
996 tty_hangup(self->tty);
997 }
998 break;
999 default:
1000 IRDA_DEBUG(2, "%s(), unknown event: %s\n", __FUNCTION__ ,
1001 ircomm_tty_event[event]);
1002 ret = -EINVAL;
1003 }
1004 return ret;
1005}
1006
diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c
new file mode 100644
index 00000000000..197e3e7ed7e
--- /dev/null
+++ b/net/irda/ircomm/ircomm_tty_ioctl.c
@@ -0,0 +1,428 @@
1/*********************************************************************
2 *
3 * Filename: ircomm_tty_ioctl.c
4 * Version:
5 * Description:
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Thu Jun 10 14:39:09 1999
9 * Modified at: Wed Jan 5 14:45:43 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 * MA 02111-1307 USA
28 *
29 ********************************************************************/
30
31#include <linux/init.h>
32#include <linux/fs.h>
33#include <linux/sched.h>
34#include <linux/termios.h>
35#include <linux/tty.h>
36#include <linux/serial.h>
37
38#include <asm/uaccess.h>
39
40#include <net/irda/irda.h>
41#include <net/irda/irmod.h>
42
43#include <net/irda/ircomm_core.h>
44#include <net/irda/ircomm_param.h>
45#include <net/irda/ircomm_tty_attach.h>
46#include <net/irda/ircomm_tty.h>
47
48#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
49
50/*
51 * Function ircomm_tty_change_speed (driver)
52 *
53 * Change speed of the driver. If the remote device is a DCE, then this
54 * should make it change the speed of its serial port
55 */
56static void ircomm_tty_change_speed(struct ircomm_tty_cb *self)
57{
58 unsigned cflag, cval;
59 int baud;
60
61 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
62
63 if (!self->tty || !self->tty->termios || !self->ircomm)
64 return;
65
66 cflag = self->tty->termios->c_cflag;
67
68 /* byte size and parity */
69 switch (cflag & CSIZE) {
70 case CS5: cval = IRCOMM_WSIZE_5; break;
71 case CS6: cval = IRCOMM_WSIZE_6; break;
72 case CS7: cval = IRCOMM_WSIZE_7; break;
73 case CS8: cval = IRCOMM_WSIZE_8; break;
74 default: cval = IRCOMM_WSIZE_5; break;
75 }
76 if (cflag & CSTOPB)
77 cval |= IRCOMM_2_STOP_BIT;
78
79 if (cflag & PARENB)
80 cval |= IRCOMM_PARITY_ENABLE;
81 if (!(cflag & PARODD))
82 cval |= IRCOMM_PARITY_EVEN;
83
84 /* Determine divisor based on baud rate */
85 baud = tty_get_baud_rate(self->tty);
86 if (!baud)
87 baud = 9600; /* B0 transition handled in rs_set_termios */
88
89 self->settings.data_rate = baud;
90 ircomm_param_request(self, IRCOMM_DATA_RATE, FALSE);
91
92 /* CTS flow control flag and modem status interrupts */
93 if (cflag & CRTSCTS) {
94 self->flags |= ASYNC_CTS_FLOW;
95 self->settings.flow_control |= IRCOMM_RTS_CTS_IN;
96 /* This got me. Bummer. Jean II */
97 if (self->service_type == IRCOMM_3_WIRE_RAW)
98 IRDA_WARNING("%s(), enabling RTS/CTS on link that doesn't support it (3-wire-raw)\n", __FUNCTION__);
99 } else {
100 self->flags &= ~ASYNC_CTS_FLOW;
101 self->settings.flow_control &= ~IRCOMM_RTS_CTS_IN;
102 }
103 if (cflag & CLOCAL)
104 self->flags &= ~ASYNC_CHECK_CD;
105 else
106 self->flags |= ASYNC_CHECK_CD;
107#if 0
108 /*
109 * Set up parity check flag
110 */
111
112 if (I_INPCK(self->tty))
113 driver->read_status_mask |= LSR_FE | LSR_PE;
114 if (I_BRKINT(driver->tty) || I_PARMRK(driver->tty))
115 driver->read_status_mask |= LSR_BI;
116
117 /*
118 * Characters to ignore
119 */
120 driver->ignore_status_mask = 0;
121 if (I_IGNPAR(driver->tty))
122 driver->ignore_status_mask |= LSR_PE | LSR_FE;
123
124 if (I_IGNBRK(self->tty)) {
125 self->ignore_status_mask |= LSR_BI;
126 /*
127 * If we're ignore parity and break indicators, ignore
128 * overruns too. (For real raw support).
129 */
130 if (I_IGNPAR(self->tty))
131 self->ignore_status_mask |= LSR_OE;
132 }
133#endif
134 self->settings.data_format = cval;
135
136 ircomm_param_request(self, IRCOMM_DATA_FORMAT, FALSE);
137 ircomm_param_request(self, IRCOMM_FLOW_CONTROL, TRUE);
138}
139
140/*
141 * Function ircomm_tty_set_termios (tty, old_termios)
142 *
143 * This routine allows the tty driver to be notified when device's
144 * termios settings have changed. Note that a well-designed tty driver
145 * should be prepared to accept the case where old == NULL, and try to
146 * do something rational.
147 */
148void ircomm_tty_set_termios(struct tty_struct *tty,
149 struct termios *old_termios)
150{
151 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
152 unsigned int cflag = tty->termios->c_cflag;
153
154 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
155
156 if ((cflag == old_termios->c_cflag) &&
157 (RELEVANT_IFLAG(tty->termios->c_iflag) ==
158 RELEVANT_IFLAG(old_termios->c_iflag)))
159 {
160 return;
161 }
162
163 ircomm_tty_change_speed(self);
164
165 /* Handle transition to B0 status */
166 if ((old_termios->c_cflag & CBAUD) &&
167 !(cflag & CBAUD)) {
168 self->settings.dte &= ~(IRCOMM_DTR|IRCOMM_RTS);
169 ircomm_param_request(self, IRCOMM_DTE, TRUE);
170 }
171
172 /* Handle transition away from B0 status */
173 if (!(old_termios->c_cflag & CBAUD) &&
174 (cflag & CBAUD)) {
175 self->settings.dte |= IRCOMM_DTR;
176 if (!(tty->termios->c_cflag & CRTSCTS) ||
177 !test_bit(TTY_THROTTLED, &tty->flags)) {
178 self->settings.dte |= IRCOMM_RTS;
179 }
180 ircomm_param_request(self, IRCOMM_DTE, TRUE);
181 }
182
183 /* Handle turning off CRTSCTS */
184 if ((old_termios->c_cflag & CRTSCTS) &&
185 !(tty->termios->c_cflag & CRTSCTS))
186 {
187 tty->hw_stopped = 0;
188 ircomm_tty_start(tty);
189 }
190}
191
192/*
193 * Function ircomm_tty_tiocmget (tty, file)
194 *
195 *
196 *
197 */
198int ircomm_tty_tiocmget(struct tty_struct *tty, struct file *file)
199{
200 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
201 unsigned int result;
202
203 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
204
205 if (tty->flags & (1 << TTY_IO_ERROR))
206 return -EIO;
207
208 result = ((self->settings.dte & IRCOMM_RTS) ? TIOCM_RTS : 0)
209 | ((self->settings.dte & IRCOMM_DTR) ? TIOCM_DTR : 0)
210 | ((self->settings.dce & IRCOMM_CD) ? TIOCM_CAR : 0)
211 | ((self->settings.dce & IRCOMM_RI) ? TIOCM_RNG : 0)
212 | ((self->settings.dce & IRCOMM_DSR) ? TIOCM_DSR : 0)
213 | ((self->settings.dce & IRCOMM_CTS) ? TIOCM_CTS : 0);
214 return result;
215}
216
217/*
218 * Function ircomm_tty_tiocmset (tty, file, set, clear)
219 *
220 *
221 *
222 */
223int ircomm_tty_tiocmset(struct tty_struct *tty, struct file *file,
224 unsigned int set, unsigned int clear)
225{
226 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
227
228 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
229
230 if (tty->flags & (1 << TTY_IO_ERROR))
231 return -EIO;
232
233 IRDA_ASSERT(self != NULL, return -1;);
234 IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
235
236 if (set & TIOCM_RTS)
237 self->settings.dte |= IRCOMM_RTS;
238 if (set & TIOCM_DTR)
239 self->settings.dte |= IRCOMM_DTR;
240
241 if (clear & TIOCM_RTS)
242 self->settings.dte &= ~IRCOMM_RTS;
243 if (clear & TIOCM_DTR)
244 self->settings.dte &= ~IRCOMM_DTR;
245
246 if ((set|clear) & TIOCM_RTS)
247 self->settings.dte |= IRCOMM_DELTA_RTS;
248 if ((set|clear) & TIOCM_DTR)
249 self->settings.dte |= IRCOMM_DELTA_DTR;
250
251 ircomm_param_request(self, IRCOMM_DTE, TRUE);
252
253 return 0;
254}
255
256/*
257 * Function get_serial_info (driver, retinfo)
258 *
259 *
260 *
261 */
262static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self,
263 struct serial_struct __user *retinfo)
264{
265 struct serial_struct info;
266
267 if (!retinfo)
268 return -EFAULT;
269
270 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
271
272 memset(&info, 0, sizeof(info));
273 info.line = self->line;
274 info.flags = self->flags;
275 info.baud_base = self->settings.data_rate;
276 info.close_delay = self->close_delay;
277 info.closing_wait = self->closing_wait;
278
279 /* For compatibility */
280 info.type = PORT_16550A;
281 info.port = 0;
282 info.irq = 0;
283 info.xmit_fifo_size = 0;
284 info.hub6 = 0;
285 info.custom_divisor = 0;
286
287 if (copy_to_user(retinfo, &info, sizeof(*retinfo)))
288 return -EFAULT;
289
290 return 0;
291}
292
293/*
294 * Function set_serial_info (driver, new_info)
295 *
296 *
297 *
298 */
299static int ircomm_tty_set_serial_info(struct ircomm_tty_cb *self,
300 struct serial_struct __user *new_info)
301{
302#if 0
303 struct serial_struct new_serial;
304 struct ircomm_tty_cb old_state, *state;
305
306 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
307
308 if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
309 return -EFAULT;
310
311
312 state = self
313 old_state = *self;
314
315 if (!capable(CAP_SYS_ADMIN)) {
316 if ((new_serial.baud_base != state->settings.data_rate) ||
317 (new_serial.close_delay != state->close_delay) ||
318 ((new_serial.flags & ~ASYNC_USR_MASK) !=
319 (self->flags & ~ASYNC_USR_MASK)))
320 return -EPERM;
321 state->flags = ((state->flags & ~ASYNC_USR_MASK) |
322 (new_serial.flags & ASYNC_USR_MASK));
323 self->flags = ((self->flags & ~ASYNC_USR_MASK) |
324 (new_serial.flags & ASYNC_USR_MASK));
325 /* self->custom_divisor = new_serial.custom_divisor; */
326 goto check_and_exit;
327 }
328
329 /*
330 * OK, past this point, all the error checking has been done.
331 * At this point, we start making changes.....
332 */
333
334 if (self->settings.data_rate != new_serial.baud_base) {
335 self->settings.data_rate = new_serial.baud_base;
336 ircomm_param_request(self, IRCOMM_DATA_RATE, TRUE);
337 }
338
339 self->close_delay = new_serial.close_delay * HZ/100;
340 self->closing_wait = new_serial.closing_wait * HZ/100;
341 /* self->custom_divisor = new_serial.custom_divisor; */
342
343 self->flags = ((self->flags & ~ASYNC_FLAGS) |
344 (new_serial.flags & ASYNC_FLAGS));
345 self->tty->low_latency = (self->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
346
347 check_and_exit:
348
349 if (self->flags & ASYNC_INITIALIZED) {
350 if (((old_state.flags & ASYNC_SPD_MASK) !=
351 (self->flags & ASYNC_SPD_MASK)) ||
352 (old_driver.custom_divisor != driver->custom_divisor)) {
353 if ((driver->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
354 driver->tty->alt_speed = 57600;
355 if ((driver->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
356 driver->tty->alt_speed = 115200;
357 if ((driver->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
358 driver->tty->alt_speed = 230400;
359 if ((driver->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
360 driver->tty->alt_speed = 460800;
361 ircomm_tty_change_speed(driver);
362 }
363 }
364#endif
365 return 0;
366}
367
368/*
369 * Function ircomm_tty_ioctl (tty, file, cmd, arg)
370 *
371 *
372 *
373 */
374int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file,
375 unsigned int cmd, unsigned long arg)
376{
377 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
378 int ret = 0;
379
380 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
381
382 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
383 (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
384 (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
385 if (tty->flags & (1 << TTY_IO_ERROR))
386 return -EIO;
387 }
388
389 switch (cmd) {
390 case TIOCGSERIAL:
391 ret = ircomm_tty_get_serial_info(self, (struct serial_struct __user *) arg);
392 break;
393 case TIOCSSERIAL:
394 ret = ircomm_tty_set_serial_info(self, (struct serial_struct __user *) arg);
395 break;
396 case TIOCMIWAIT:
397 IRDA_DEBUG(0, "(), TIOCMIWAIT, not impl!\n");
398 break;
399
400 case TIOCGICOUNT:
401 IRDA_DEBUG(0, "%s(), TIOCGICOUNT not impl!\n", __FUNCTION__ );
402#if 0
403 save_flags(flags); cli();
404 cnow = driver->icount;
405 restore_flags(flags);
406 p_cuser = (struct serial_icounter_struct __user *) arg;
407 if (put_user(cnow.cts, &p_cuser->cts) ||
408 put_user(cnow.dsr, &p_cuser->dsr) ||
409 put_user(cnow.rng, &p_cuser->rng) ||
410 put_user(cnow.dcd, &p_cuser->dcd) ||
411 put_user(cnow.rx, &p_cuser->rx) ||
412 put_user(cnow.tx, &p_cuser->tx) ||
413 put_user(cnow.frame, &p_cuser->frame) ||
414 put_user(cnow.overrun, &p_cuser->overrun) ||
415 put_user(cnow.parity, &p_cuser->parity) ||
416 put_user(cnow.brk, &p_cuser->brk) ||
417 put_user(cnow.buf_overrun, &p_cuser->buf_overrun))
418 return -EFAULT;
419#endif
420 return 0;
421 default:
422 ret = -ENOIOCTLCMD; /* ioctls which we must ignore */
423 }
424 return ret;
425}
426
427
428
diff --git a/net/irda/irda_device.c b/net/irda/irda_device.c
new file mode 100644
index 00000000000..fda299e300c
--- /dev/null
+++ b/net/irda/irda_device.c
@@ -0,0 +1,489 @@
1/*********************************************************************
2 *
3 * Filename: irda_device.c
4 * Version: 0.9
5 * Description: Utility functions used by the device drivers
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sat Oct 9 09:22:27 1999
9 * Modified at: Sun Jan 23 17:41:24 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
13 * Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 * MA 02111-1307 USA
29 *
30 ********************************************************************/
31
32#include <linux/config.h>
33#include <linux/string.h>
34#include <linux/proc_fs.h>
35#include <linux/skbuff.h>
36#include <linux/if.h>
37#include <linux/if_ether.h>
38#include <linux/if_arp.h>
39#include <linux/netdevice.h>
40#include <linux/init.h>
41#include <linux/tty.h>
42#include <linux/kmod.h>
43#include <linux/spinlock.h>
44
45#include <asm/ioctls.h>
46#include <asm/uaccess.h>
47#include <asm/dma.h>
48#include <asm/io.h>
49
50#include <net/irda/irda_device.h>
51#include <net/irda/irlap.h>
52#include <net/irda/timer.h>
53#include <net/irda/wrapper.h>
54
55static void __irda_task_delete(struct irda_task *task);
56
57static hashbin_t *dongles = NULL;
58static hashbin_t *tasks = NULL;
59
60#ifdef CONFIG_IRDA_DEBUG
61static const char *task_state[] = {
62 "IRDA_TASK_INIT",
63 "IRDA_TASK_DONE",
64 "IRDA_TASK_WAIT",
65 "IRDA_TASK_WAIT1",
66 "IRDA_TASK_WAIT2",
67 "IRDA_TASK_WAIT3",
68 "IRDA_TASK_CHILD_INIT",
69 "IRDA_TASK_CHILD_WAIT",
70 "IRDA_TASK_CHILD_DONE",
71};
72#endif /* CONFIG_IRDA_DEBUG */
73
74static void irda_task_timer_expired(void *data);
75
76int __init irda_device_init( void)
77{
78 dongles = hashbin_new(HB_NOLOCK);
79 if (dongles == NULL) {
80 IRDA_WARNING("IrDA: Can't allocate dongles hashbin!\n");
81 return -ENOMEM;
82 }
83 spin_lock_init(&dongles->hb_spinlock);
84
85 tasks = hashbin_new(HB_LOCK);
86 if (tasks == NULL) {
87 IRDA_WARNING("IrDA: Can't allocate tasks hashbin!\n");
88 hashbin_delete(dongles, NULL);
89 return -ENOMEM;
90 }
91
92 /* We no longer initialise the driver ourselves here, we let
93 * the system do it for us... - Jean II */
94
95 return 0;
96}
97
98static void __exit leftover_dongle(void *arg)
99{
100 struct dongle_reg *reg = arg;
101 IRDA_WARNING("IrDA: Dongle type %x not unregistered\n",
102 reg->type);
103}
104
105void __exit irda_device_cleanup(void)
106{
107 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
108
109 hashbin_delete(tasks, (FREE_FUNC) __irda_task_delete);
110
111 hashbin_delete(dongles, leftover_dongle);
112}
113
114/*
115 * Function irda_device_set_media_busy (self, status)
116 *
117 * Called when we have detected that another station is transmitting
118 * in contention mode.
119 */
120void irda_device_set_media_busy(struct net_device *dev, int status)
121{
122 struct irlap_cb *self;
123
124 IRDA_DEBUG(4, "%s(%s)\n", __FUNCTION__, status ? "TRUE" : "FALSE");
125
126 self = (struct irlap_cb *) dev->atalk_ptr;
127
128 IRDA_ASSERT(self != NULL, return;);
129 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
130
131 if (status) {
132 self->media_busy = TRUE;
133 if (status == SMALL)
134 irlap_start_mbusy_timer(self, SMALLBUSY_TIMEOUT);
135 else
136 irlap_start_mbusy_timer(self, MEDIABUSY_TIMEOUT);
137 IRDA_DEBUG( 4, "Media busy!\n");
138 } else {
139 self->media_busy = FALSE;
140 irlap_stop_mbusy_timer(self);
141 }
142}
143EXPORT_SYMBOL(irda_device_set_media_busy);
144
145
146/*
147 * Function irda_device_is_receiving (dev)
148 *
149 * Check if the device driver is currently receiving data
150 *
151 */
152int irda_device_is_receiving(struct net_device *dev)
153{
154 struct if_irda_req req;
155 int ret;
156
157 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
158
159 if (!dev->do_ioctl) {
160 IRDA_ERROR("%s: do_ioctl not impl. by device driver\n",
161 __FUNCTION__);
162 return -1;
163 }
164
165 ret = dev->do_ioctl(dev, (struct ifreq *) &req, SIOCGRECEIVING);
166 if (ret < 0)
167 return ret;
168
169 return req.ifr_receiving;
170}
171
172void irda_task_next_state(struct irda_task *task, IRDA_TASK_STATE state)
173{
174 IRDA_DEBUG(2, "%s(), state = %s\n", __FUNCTION__, task_state[state]);
175
176 task->state = state;
177}
178EXPORT_SYMBOL(irda_task_next_state);
179
180static void __irda_task_delete(struct irda_task *task)
181{
182 del_timer(&task->timer);
183
184 kfree(task);
185}
186
187void irda_task_delete(struct irda_task *task)
188{
189 /* Unregister task */
190 hashbin_remove(tasks, (long) task, NULL);
191
192 __irda_task_delete(task);
193}
194EXPORT_SYMBOL(irda_task_delete);
195
196/*
197 * Function irda_task_kick (task)
198 *
199 * Tries to execute a task possible multiple times until the task is either
200 * finished, or askes for a timeout. When a task is finished, we do post
201 * processing, and notify the parent task, that is waiting for this task
202 * to complete.
203 */
204static int irda_task_kick(struct irda_task *task)
205{
206 int finished = TRUE;
207 int count = 0;
208 int timeout;
209
210 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
211
212 IRDA_ASSERT(task != NULL, return -1;);
213 IRDA_ASSERT(task->magic == IRDA_TASK_MAGIC, return -1;);
214
215 /* Execute task until it's finished, or askes for a timeout */
216 do {
217 timeout = task->function(task);
218 if (count++ > 100) {
219 IRDA_ERROR("%s: error in task handler!\n",
220 __FUNCTION__);
221 irda_task_delete(task);
222 return TRUE;
223 }
224 } while ((timeout == 0) && (task->state != IRDA_TASK_DONE));
225
226 if (timeout < 0) {
227 IRDA_ERROR("%s: Error executing task!\n", __FUNCTION__);
228 irda_task_delete(task);
229 return TRUE;
230 }
231
232 /* Check if we are finished */
233 if (task->state == IRDA_TASK_DONE) {
234 del_timer(&task->timer);
235
236 /* Do post processing */
237 if (task->finished)
238 task->finished(task);
239
240 /* Notify parent */
241 if (task->parent) {
242 /* Check if parent is waiting for us to complete */
243 if (task->parent->state == IRDA_TASK_CHILD_WAIT) {
244 task->parent->state = IRDA_TASK_CHILD_DONE;
245
246 /* Stop timer now that we are here */
247 del_timer(&task->parent->timer);
248
249 /* Kick parent task */
250 irda_task_kick(task->parent);
251 }
252 }
253 irda_task_delete(task);
254 } else if (timeout > 0) {
255 irda_start_timer(&task->timer, timeout, (void *) task,
256 irda_task_timer_expired);
257 finished = FALSE;
258 } else {
259 IRDA_DEBUG(0, "%s(), not finished, and no timeout!\n",
260 __FUNCTION__);
261 finished = FALSE;
262 }
263
264 return finished;
265}
266
267/*
268 * Function irda_task_execute (instance, function, finished)
269 *
270 * This function registers and tries to execute tasks that may take some
271 * time to complete. We do it this hairy way since we may have been
272 * called from interrupt context, so it's not possible to use
273 * schedule_timeout()
274 * Two important notes :
275 * o Make sure you irda_task_delete(task); in case you delete the
276 * calling instance.
277 * o No real need to lock when calling this function, but you may
278 * want to lock within the task handler.
279 * Jean II
280 */
281struct irda_task *irda_task_execute(void *instance,
282 IRDA_TASK_CALLBACK function,
283 IRDA_TASK_CALLBACK finished,
284 struct irda_task *parent, void *param)
285{
286 struct irda_task *task;
287
288 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
289
290 task = kmalloc(sizeof(struct irda_task), GFP_ATOMIC);
291 if (!task)
292 return NULL;
293
294 task->state = IRDA_TASK_INIT;
295 task->instance = instance;
296 task->function = function;
297 task->finished = finished;
298 task->parent = parent;
299 task->param = param;
300 task->magic = IRDA_TASK_MAGIC;
301
302 init_timer(&task->timer);
303
304 /* Register task */
305 hashbin_insert(tasks, (irda_queue_t *) task, (long) task, NULL);
306
307 /* No time to waste, so lets get going! */
308 return irda_task_kick(task) ? NULL : task;
309}
310EXPORT_SYMBOL(irda_task_execute);
311
312/*
313 * Function irda_task_timer_expired (data)
314 *
315 * Task time has expired. We now try to execute task (again), and restart
316 * the timer if the task has not finished yet
317 */
318static void irda_task_timer_expired(void *data)
319{
320 struct irda_task *task;
321
322 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
323
324 task = (struct irda_task *) data;
325
326 irda_task_kick(task);
327}
328
329/*
330 * Function irda_device_setup (dev)
331 *
332 * This function should be used by low level device drivers in a similar way
333 * as ether_setup() is used by normal network device drivers
334 */
335static void irda_device_setup(struct net_device *dev)
336{
337 dev->hard_header_len = 0;
338 dev->addr_len = 0;
339
340 dev->type = ARPHRD_IRDA;
341 dev->tx_queue_len = 8; /* Window size + 1 s-frame */
342
343 memset(dev->broadcast, 0xff, 4);
344
345 dev->mtu = 2048;
346 dev->flags = IFF_NOARP;
347}
348
349/*
350 * Funciton alloc_irdadev
351 * Allocates and sets up an IRDA device in a manner similar to
352 * alloc_etherdev.
353 */
354struct net_device *alloc_irdadev(int sizeof_priv)
355{
356 return alloc_netdev(sizeof_priv, "irda%d", irda_device_setup);
357}
358EXPORT_SYMBOL(alloc_irdadev);
359
360/*
361 * Function irda_device_init_dongle (self, type, qos)
362 *
363 * Initialize attached dongle.
364 *
365 * Important : request_module require us to call this function with
366 * a process context and irq enabled. - Jean II
367 */
368dongle_t *irda_device_dongle_init(struct net_device *dev, int type)
369{
370 struct dongle_reg *reg;
371 dongle_t *dongle = NULL;
372
373 might_sleep();
374
375 spin_lock(&dongles->hb_spinlock);
376 reg = hashbin_find(dongles, type, NULL);
377
378#ifdef CONFIG_KMOD
379 /* Try to load the module needed */
380 if (!reg && capable(CAP_SYS_MODULE)) {
381 spin_unlock(&dongles->hb_spinlock);
382
383 request_module("irda-dongle-%d", type);
384
385 spin_lock(&dongles->hb_spinlock);
386 reg = hashbin_find(dongles, type, NULL);
387 }
388#endif
389
390 if (!reg || !try_module_get(reg->owner) ) {
391 IRDA_ERROR("IrDA: Unable to find requested dongle type %x\n",
392 type);
393 goto out;
394 }
395
396 /* Allocate dongle info for this instance */
397 dongle = kmalloc(sizeof(dongle_t), GFP_KERNEL);
398 if (!dongle)
399 goto out;
400
401 memset(dongle, 0, sizeof(dongle_t));
402
403 /* Bind the registration info to this particular instance */
404 dongle->issue = reg;
405 dongle->dev = dev;
406
407 out:
408 spin_unlock(&dongles->hb_spinlock);
409 return dongle;
410}
411EXPORT_SYMBOL(irda_device_dongle_init);
412
413/*
414 * Function irda_device_dongle_cleanup (dongle)
415 */
416int irda_device_dongle_cleanup(dongle_t *dongle)
417{
418 IRDA_ASSERT(dongle != NULL, return -1;);
419
420 dongle->issue->close(dongle);
421 module_put(dongle->issue->owner);
422 kfree(dongle);
423
424 return 0;
425}
426EXPORT_SYMBOL(irda_device_dongle_cleanup);
427
428/*
429 * Function irda_device_register_dongle (dongle)
430 */
431int irda_device_register_dongle(struct dongle_reg *new)
432{
433 spin_lock(&dongles->hb_spinlock);
434 /* Check if this dongle has been registered before */
435 if (hashbin_find(dongles, new->type, NULL)) {
436 IRDA_MESSAGE("%s: Dongle type %x already registered\n",
437 __FUNCTION__, new->type);
438 } else {
439 /* Insert IrDA dongle into hashbin */
440 hashbin_insert(dongles, (irda_queue_t *) new, new->type, NULL);
441 }
442 spin_unlock(&dongles->hb_spinlock);
443
444 return 0;
445}
446EXPORT_SYMBOL(irda_device_register_dongle);
447
448/*
449 * Function irda_device_unregister_dongle (dongle)
450 *
451 * Unregister dongle, and remove dongle from list of registered dongles
452 *
453 */
454void irda_device_unregister_dongle(struct dongle_reg *dongle)
455{
456 struct dongle *node;
457
458 spin_lock(&dongles->hb_spinlock);
459 node = hashbin_remove(dongles, dongle->type, NULL);
460 if (!node)
461 IRDA_ERROR("%s: dongle not found!\n", __FUNCTION__);
462 spin_unlock(&dongles->hb_spinlock);
463}
464EXPORT_SYMBOL(irda_device_unregister_dongle);
465
466#ifdef CONFIG_ISA
467/*
468 * Function setup_dma (idev, buffer, count, mode)
469 *
470 * Setup the DMA channel. Commonly used by ISA FIR drivers
471 *
472 */
473void irda_setup_dma(int channel, dma_addr_t buffer, int count, int mode)
474{
475 unsigned long flags;
476
477 flags = claim_dma_lock();
478
479 disable_dma(channel);
480 clear_dma_ff(channel);
481 set_dma_mode(channel, mode);
482 set_dma_addr(channel, buffer);
483 set_dma_count(channel, count);
484 enable_dma(channel);
485
486 release_dma_lock(flags);
487}
488EXPORT_SYMBOL(irda_setup_dma);
489#endif
diff --git a/net/irda/iriap.c b/net/irda/iriap.c
new file mode 100644
index 00000000000..b8bb78af8b8
--- /dev/null
+++ b/net/irda/iriap.c
@@ -0,0 +1,1089 @@
1/*********************************************************************
2 *
3 * Filename: iriap.c
4 * Version: 0.8
5 * Description: Information Access Protocol (IAP)
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Thu Aug 21 00:02:07 1997
9 * Modified at: Sat Dec 25 16:42:42 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
13 * All Rights Reserved.
14 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
20 *
21 * Neither Dag Brattli nor University of Tromsø admit liability nor
22 * provide warranty for any of this software. This material is
23 * provided "AS-IS" and at no charge.
24 *
25 ********************************************************************/
26
27#include <linux/config.h>
28#include <linux/module.h>
29#include <linux/types.h>
30#include <linux/skbuff.h>
31#include <linux/string.h>
32#include <linux/init.h>
33#include <linux/seq_file.h>
34
35#include <asm/byteorder.h>
36#include <asm/unaligned.h>
37
38#include <net/irda/irda.h>
39#include <net/irda/irttp.h>
40#include <net/irda/irlmp.h>
41#include <net/irda/irias_object.h>
42#include <net/irda/iriap_event.h>
43#include <net/irda/iriap.h>
44
45#ifdef CONFIG_IRDA_DEBUG
46/* FIXME: This one should go in irlmp.c */
47static const char *ias_charset_types[] = {
48 "CS_ASCII",
49 "CS_ISO_8859_1",
50 "CS_ISO_8859_2",
51 "CS_ISO_8859_3",
52 "CS_ISO_8859_4",
53 "CS_ISO_8859_5",
54 "CS_ISO_8859_6",
55 "CS_ISO_8859_7",
56 "CS_ISO_8859_8",
57 "CS_ISO_8859_9",
58 "CS_UNICODE"
59};
60#endif /* CONFIG_IRDA_DEBUG */
61
62static hashbin_t *iriap = NULL;
63static void *service_handle;
64
65static void __iriap_close(struct iriap_cb *self);
66static int iriap_register_lsap(struct iriap_cb *self, __u8 slsap_sel, int mode);
67static void iriap_disconnect_indication(void *instance, void *sap,
68 LM_REASON reason, struct sk_buff *skb);
69static void iriap_connect_indication(void *instance, void *sap,
70 struct qos_info *qos, __u32 max_sdu_size,
71 __u8 max_header_size,
72 struct sk_buff *skb);
73static void iriap_connect_confirm(void *instance, void *sap,
74 struct qos_info *qos,
75 __u32 max_sdu_size, __u8 max_header_size,
76 struct sk_buff *skb);
77static int iriap_data_indication(void *instance, void *sap,
78 struct sk_buff *skb);
79
80static void iriap_watchdog_timer_expired(void *data);
81
82static inline void iriap_start_watchdog_timer(struct iriap_cb *self,
83 int timeout)
84{
85 irda_start_timer(&self->watchdog_timer, timeout, self,
86 iriap_watchdog_timer_expired);
87}
88
89/*
90 * Function iriap_init (void)
91 *
92 * Initializes the IrIAP layer, called by the module initialization code
93 * in irmod.c
94 */
95int __init iriap_init(void)
96{
97 struct ias_object *obj;
98 struct iriap_cb *server;
99 __u8 oct_seq[6];
100 __u16 hints;
101
102 /* Allocate master array */
103 iriap = hashbin_new(HB_LOCK);
104 if (!iriap)
105 return -ENOMEM;
106
107 /* Object repository - defined in irias_object.c */
108 irias_objects = hashbin_new(HB_LOCK);
109 if (!irias_objects) {
110 IRDA_WARNING("%s: Can't allocate irias_objects hashbin!\n",
111 __FUNCTION__);
112 hashbin_delete(iriap, NULL);
113 return -ENOMEM;
114 }
115
116 /*
117 * Register some default services for IrLMP
118 */
119 hints = irlmp_service_to_hint(S_COMPUTER);
120 service_handle = irlmp_register_service(hints);
121
122 /* Register the Device object with LM-IAS */
123 obj = irias_new_object("Device", IAS_DEVICE_ID);
124 irias_add_string_attrib(obj, "DeviceName", "Linux", IAS_KERNEL_ATTR);
125
126 oct_seq[0] = 0x01; /* Version 1 */
127 oct_seq[1] = 0x00; /* IAS support bits */
128 oct_seq[2] = 0x00; /* LM-MUX support bits */
129#ifdef CONFIG_IRDA_ULTRA
130 oct_seq[2] |= 0x04; /* Connectionless Data support */
131#endif
132 irias_add_octseq_attrib(obj, "IrLMPSupport", oct_seq, 3,
133 IAS_KERNEL_ATTR);
134 irias_insert_object(obj);
135
136 /*
137 * Register server support with IrLMP so we can accept incoming
138 * connections
139 */
140 server = iriap_open(LSAP_IAS, IAS_SERVER, NULL, NULL);
141 if (!server) {
142 IRDA_DEBUG(0, "%s(), unable to open server\n", __FUNCTION__);
143 return -1;
144 }
145 iriap_register_lsap(server, LSAP_IAS, IAS_SERVER);
146
147 return 0;
148}
149
150/*
151 * Function iriap_cleanup (void)
152 *
153 * Initializes the IrIAP layer, called by the module cleanup code in
154 * irmod.c
155 */
156void __exit iriap_cleanup(void)
157{
158 irlmp_unregister_service(service_handle);
159
160 hashbin_delete(iriap, (FREE_FUNC) __iriap_close);
161 hashbin_delete(irias_objects, (FREE_FUNC) __irias_delete_object);
162}
163
164/*
165 * Function iriap_open (void)
166 *
167 * Opens an instance of the IrIAP layer, and registers with IrLMP
168 */
169struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv,
170 CONFIRM_CALLBACK callback)
171{
172 struct iriap_cb *self;
173
174 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
175
176 self = kmalloc(sizeof(struct iriap_cb), GFP_ATOMIC);
177 if (!self) {
178 IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
179 return NULL;
180 }
181
182 /*
183 * Initialize instance
184 */
185 memset(self, 0, sizeof(struct iriap_cb));
186
187 self->magic = IAS_MAGIC;
188 self->mode = mode;
189 if (mode == IAS_CLIENT)
190 iriap_register_lsap(self, slsap_sel, mode);
191
192 self->confirm = callback;
193 self->priv = priv;
194
195 /* iriap_getvaluebyclass_request() will construct packets before
196 * we connect, so this must have a sane value... Jean II */
197 self->max_header_size = LMP_MAX_HEADER;
198
199 init_timer(&self->watchdog_timer);
200
201 hashbin_insert(iriap, (irda_queue_t *) self, (long) self, NULL);
202
203 /* Initialize state machines */
204 iriap_next_client_state(self, S_DISCONNECT);
205 iriap_next_call_state(self, S_MAKE_CALL);
206 iriap_next_server_state(self, R_DISCONNECT);
207 iriap_next_r_connect_state(self, R_WAITING);
208
209 return self;
210}
211EXPORT_SYMBOL(iriap_open);
212
213/*
214 * Function __iriap_close (self)
215 *
216 * Removes (deallocates) the IrIAP instance
217 *
218 */
219static void __iriap_close(struct iriap_cb *self)
220{
221 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
222
223 IRDA_ASSERT(self != NULL, return;);
224 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
225
226 del_timer(&self->watchdog_timer);
227
228 if (self->request_skb)
229 dev_kfree_skb(self->request_skb);
230
231 self->magic = 0;
232
233 kfree(self);
234}
235
236/*
237 * Function iriap_close (void)
238 *
239 * Closes IrIAP and deregisters with IrLMP
240 */
241void iriap_close(struct iriap_cb *self)
242{
243 struct iriap_cb *entry;
244
245 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
246
247 IRDA_ASSERT(self != NULL, return;);
248 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
249
250 if (self->lsap) {
251 irlmp_close_lsap(self->lsap);
252 self->lsap = NULL;
253 }
254
255 entry = (struct iriap_cb *) hashbin_remove(iriap, (long) self, NULL);
256 IRDA_ASSERT(entry == self, return;);
257
258 __iriap_close(self);
259}
260EXPORT_SYMBOL(iriap_close);
261
262static int iriap_register_lsap(struct iriap_cb *self, __u8 slsap_sel, int mode)
263{
264 notify_t notify;
265
266 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
267
268 irda_notify_init(&notify);
269 notify.connect_confirm = iriap_connect_confirm;
270 notify.connect_indication = iriap_connect_indication;
271 notify.disconnect_indication = iriap_disconnect_indication;
272 notify.data_indication = iriap_data_indication;
273 notify.instance = self;
274 if (mode == IAS_CLIENT)
275 strcpy(notify.name, "IrIAS cli");
276 else
277 strcpy(notify.name, "IrIAS srv");
278
279 self->lsap = irlmp_open_lsap(slsap_sel, &notify, 0);
280 if (self->lsap == NULL) {
281 IRDA_ERROR("%s: Unable to allocated LSAP!\n", __FUNCTION__);
282 return -1;
283 }
284 self->slsap_sel = self->lsap->slsap_sel;
285
286 return 0;
287}
288
289/*
290 * Function iriap_disconnect_indication (handle, reason)
291 *
292 * Got disconnect, so clean up everything associated with this connection
293 *
294 */
295static void iriap_disconnect_indication(void *instance, void *sap,
296 LM_REASON reason,
297 struct sk_buff *skb)
298{
299 struct iriap_cb *self;
300
301 IRDA_DEBUG(4, "%s(), reason=%s\n", __FUNCTION__, irlmp_reasons[reason]);
302
303 self = (struct iriap_cb *) instance;
304
305 IRDA_ASSERT(self != NULL, return;);
306 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
307
308 IRDA_ASSERT(iriap != NULL, return;);
309
310 del_timer(&self->watchdog_timer);
311
312 /* Not needed */
313 if (skb)
314 dev_kfree_skb(skb);
315
316 if (self->mode == IAS_CLIENT) {
317 IRDA_DEBUG(4, "%s(), disconnect as client\n", __FUNCTION__);
318
319
320 iriap_do_client_event(self, IAP_LM_DISCONNECT_INDICATION,
321 NULL);
322 /*
323 * Inform service user that the request failed by sending
324 * it a NULL value. Warning, the client might close us, so
325 * remember no to use self anymore after calling confirm
326 */
327 if (self->confirm)
328 self->confirm(IAS_DISCONNECT, 0, NULL, self->priv);
329 } else {
330 IRDA_DEBUG(4, "%s(), disconnect as server\n", __FUNCTION__);
331 iriap_do_server_event(self, IAP_LM_DISCONNECT_INDICATION,
332 NULL);
333 iriap_close(self);
334 }
335}
336
337/*
338 * Function iriap_disconnect_request (handle)
339 */
340static void iriap_disconnect_request(struct iriap_cb *self)
341{
342 struct sk_buff *tx_skb;
343
344 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
345
346 IRDA_ASSERT(self != NULL, return;);
347 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
348
349 tx_skb = dev_alloc_skb(64);
350 if (tx_skb == NULL) {
351 IRDA_DEBUG(0, "%s(), Could not allocate an sk_buff of length %d\n",
352 __FUNCTION__, 64);
353 return;
354 }
355
356 /*
357 * Reserve space for MUX control and LAP header
358 */
359 skb_reserve(tx_skb, LMP_MAX_HEADER);
360
361 irlmp_disconnect_request(self->lsap, tx_skb);
362}
363
364/*
365 * Function iriap_getvaluebyclass (addr, name, attr)
366 *
367 * Retreive all values from attribute in all objects with given class
368 * name
369 */
370int iriap_getvaluebyclass_request(struct iriap_cb *self,
371 __u32 saddr, __u32 daddr,
372 char *name, char *attr)
373{
374 struct sk_buff *tx_skb;
375 int name_len, attr_len, skb_len;
376 __u8 *frame;
377
378 IRDA_ASSERT(self != NULL, return -1;);
379 IRDA_ASSERT(self->magic == IAS_MAGIC, return -1;);
380
381 /* Client must supply the destination device address */
382 if (!daddr)
383 return -1;
384
385 self->daddr = daddr;
386 self->saddr = saddr;
387
388 /*
389 * Save operation, so we know what the later indication is about
390 */
391 self->operation = GET_VALUE_BY_CLASS;
392
393 /* Give ourselves 10 secs to finish this operation */
394 iriap_start_watchdog_timer(self, 10*HZ);
395
396 name_len = strlen(name); /* Up to IAS_MAX_CLASSNAME = 60 */
397 attr_len = strlen(attr); /* Up to IAS_MAX_ATTRIBNAME = 60 */
398
399 skb_len = self->max_header_size+2+name_len+1+attr_len+4;
400 tx_skb = dev_alloc_skb(skb_len);
401 if (!tx_skb)
402 return -ENOMEM;
403
404 /* Reserve space for MUX and LAP header */
405 skb_reserve(tx_skb, self->max_header_size);
406 skb_put(tx_skb, 3+name_len+attr_len);
407 frame = tx_skb->data;
408
409 /* Build frame */
410 frame[0] = IAP_LST | GET_VALUE_BY_CLASS;
411 frame[1] = name_len; /* Insert length of name */
412 memcpy(frame+2, name, name_len); /* Insert name */
413 frame[2+name_len] = attr_len; /* Insert length of attr */
414 memcpy(frame+3+name_len, attr, attr_len); /* Insert attr */
415
416 iriap_do_client_event(self, IAP_CALL_REQUEST_GVBC, tx_skb);
417
418 /* Drop reference count - see state_s_disconnect(). */
419 dev_kfree_skb(tx_skb);
420
421 return 0;
422}
423EXPORT_SYMBOL(iriap_getvaluebyclass_request);
424
425/*
426 * Function iriap_getvaluebyclass_confirm (self, skb)
427 *
428 * Got result from GetValueByClass command. Parse it and return result
429 * to service user.
430 *
431 */
432static void iriap_getvaluebyclass_confirm(struct iriap_cb *self,
433 struct sk_buff *skb)
434{
435 struct ias_value *value;
436 int charset;
437 __u32 value_len;
438 __u32 tmp_cpu32;
439 __u16 obj_id;
440 __u16 len;
441 __u8 type;
442 __u8 *fp;
443 int n;
444
445 IRDA_ASSERT(self != NULL, return;);
446 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
447 IRDA_ASSERT(skb != NULL, return;);
448
449 /* Initialize variables */
450 fp = skb->data;
451 n = 2;
452
453 /* Get length, MSB first */
454 len = be16_to_cpu(get_unaligned((__u16 *)(fp+n))); n += 2;
455
456 IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);
457
458 /* Get object ID, MSB first */
459 obj_id = be16_to_cpu(get_unaligned((__u16 *)(fp+n))); n += 2;
460
461 type = fp[n++];
462 IRDA_DEBUG(4, "%s(), Value type = %d\n", __FUNCTION__, type);
463
464 switch (type) {
465 case IAS_INTEGER:
466 memcpy(&tmp_cpu32, fp+n, 4); n += 4;
467 be32_to_cpus(&tmp_cpu32);
468 value = irias_new_integer_value(tmp_cpu32);
469
470 /* Legal values restricted to 0x01-0x6f, page 15 irttp */
471 IRDA_DEBUG(4, "%s(), lsap=%d\n", __FUNCTION__, value->t.integer);
472 break;
473 case IAS_STRING:
474 charset = fp[n++];
475
476 switch (charset) {
477 case CS_ASCII:
478 break;
479/* case CS_ISO_8859_1: */
480/* case CS_ISO_8859_2: */
481/* case CS_ISO_8859_3: */
482/* case CS_ISO_8859_4: */
483/* case CS_ISO_8859_5: */
484/* case CS_ISO_8859_6: */
485/* case CS_ISO_8859_7: */
486/* case CS_ISO_8859_8: */
487/* case CS_ISO_8859_9: */
488/* case CS_UNICODE: */
489 default:
490 IRDA_DEBUG(0, "%s(), charset %s, not supported\n",
491 __FUNCTION__, ias_charset_types[charset]);
492
493 /* Aborting, close connection! */
494 iriap_disconnect_request(self);
495 return;
496 /* break; */
497 }
498 value_len = fp[n++];
499 IRDA_DEBUG(4, "%s(), strlen=%d\n", __FUNCTION__, value_len);
500
501 /* Make sure the string is null-terminated */
502 fp[n+value_len] = 0x00;
503 IRDA_DEBUG(4, "Got string %s\n", fp+n);
504
505 /* Will truncate to IAS_MAX_STRING bytes */
506 value = irias_new_string_value(fp+n);
507 break;
508 case IAS_OCT_SEQ:
509 value_len = be16_to_cpu(get_unaligned((__u16 *)(fp+n)));
510 n += 2;
511
512 /* Will truncate to IAS_MAX_OCTET_STRING bytes */
513 value = irias_new_octseq_value(fp+n, value_len);
514 break;
515 default:
516 value = irias_new_missing_value();
517 break;
518 }
519
520 /* Finished, close connection! */
521 iriap_disconnect_request(self);
522
523 /* Warning, the client might close us, so remember no to use self
524 * anymore after calling confirm
525 */
526 if (self->confirm)
527 self->confirm(IAS_SUCCESS, obj_id, value, self->priv);
528 else {
529 IRDA_DEBUG(0, "%s(), missing handler!\n", __FUNCTION__);
530 irias_delete_value(value);
531 }
532}
533
534/*
535 * Function iriap_getvaluebyclass_response ()
536 *
537 * Send answer back to remote LM-IAS
538 *
539 */
540static void iriap_getvaluebyclass_response(struct iriap_cb *self,
541 __u16 obj_id,
542 __u8 ret_code,
543 struct ias_value *value)
544{
545 struct sk_buff *tx_skb;
546 int n;
547 __u32 tmp_be32, tmp_be16;
548 __u8 *fp;
549
550 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
551
552 IRDA_ASSERT(self != NULL, return;);
553 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
554 IRDA_ASSERT(value != NULL, return;);
555 IRDA_ASSERT(value->len <= 1024, return;);
556
557 /* Initialize variables */
558 n = 0;
559
560 /*
561 * We must adjust the size of the response after the length of the
562 * value. We add 32 bytes because of the 6 bytes for the frame and
563 * max 5 bytes for the value coding.
564 */
565 tx_skb = dev_alloc_skb(value->len + self->max_header_size + 32);
566 if (!tx_skb)
567 return;
568
569 /* Reserve space for MUX and LAP header */
570 skb_reserve(tx_skb, self->max_header_size);
571 skb_put(tx_skb, 6);
572
573 fp = tx_skb->data;
574
575 /* Build frame */
576 fp[n++] = GET_VALUE_BY_CLASS | IAP_LST;
577 fp[n++] = ret_code;
578
579 /* Insert list length (MSB first) */
580 tmp_be16 = __constant_htons(0x0001);
581 memcpy(fp+n, &tmp_be16, 2); n += 2;
582
583 /* Insert object identifier ( MSB first) */
584 tmp_be16 = cpu_to_be16(obj_id);
585 memcpy(fp+n, &tmp_be16, 2); n += 2;
586
587 switch (value->type) {
588 case IAS_STRING:
589 skb_put(tx_skb, 3 + value->len);
590 fp[n++] = value->type;
591 fp[n++] = 0; /* ASCII */
592 fp[n++] = (__u8) value->len;
593 memcpy(fp+n, value->t.string, value->len); n+=value->len;
594 break;
595 case IAS_INTEGER:
596 skb_put(tx_skb, 5);
597 fp[n++] = value->type;
598
599 tmp_be32 = cpu_to_be32(value->t.integer);
600 memcpy(fp+n, &tmp_be32, 4); n += 4;
601 break;
602 case IAS_OCT_SEQ:
603 skb_put(tx_skb, 3 + value->len);
604 fp[n++] = value->type;
605
606 tmp_be16 = cpu_to_be16(value->len);
607 memcpy(fp+n, &tmp_be16, 2); n += 2;
608 memcpy(fp+n, value->t.oct_seq, value->len); n+=value->len;
609 break;
610 case IAS_MISSING:
611 IRDA_DEBUG( 3, "%s: sending IAS_MISSING\n", __FUNCTION__);
612 skb_put(tx_skb, 1);
613 fp[n++] = value->type;
614 break;
615 default:
616 IRDA_DEBUG(0, "%s(), type not implemented!\n", __FUNCTION__);
617 break;
618 }
619 iriap_do_r_connect_event(self, IAP_CALL_RESPONSE, tx_skb);
620
621 /* Drop reference count - see state_r_execute(). */
622 dev_kfree_skb(tx_skb);
623}
624
625/*
626 * Function iriap_getvaluebyclass_indication (self, skb)
627 *
628 * getvaluebyclass is requested from peer LM-IAS
629 *
630 */
631static void iriap_getvaluebyclass_indication(struct iriap_cb *self,
632 struct sk_buff *skb)
633{
634 struct ias_object *obj;
635 struct ias_attrib *attrib;
636 int name_len;
637 int attr_len;
638 char name[IAS_MAX_CLASSNAME + 1]; /* 60 bytes */
639 char attr[IAS_MAX_ATTRIBNAME + 1]; /* 60 bytes */
640 __u8 *fp;
641 int n;
642
643 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
644
645 IRDA_ASSERT(self != NULL, return;);
646 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
647 IRDA_ASSERT(skb != NULL, return;);
648
649 fp = skb->data;
650 n = 1;
651
652 name_len = fp[n++];
653 memcpy(name, fp+n, name_len); n+=name_len;
654 name[name_len] = '\0';
655
656 attr_len = fp[n++];
657 memcpy(attr, fp+n, attr_len); n+=attr_len;
658 attr[attr_len] = '\0';
659
660 IRDA_DEBUG(4, "LM-IAS: Looking up %s: %s\n", name, attr);
661 obj = irias_find_object(name);
662
663 if (obj == NULL) {
664 IRDA_DEBUG(2, "LM-IAS: Object %s not found\n", name);
665 iriap_getvaluebyclass_response(self, 0x1235, IAS_CLASS_UNKNOWN,
666 &irias_missing);
667 return;
668 }
669 IRDA_DEBUG(4, "LM-IAS: found %s, id=%d\n", obj->name, obj->id);
670
671 attrib = irias_find_attrib(obj, attr);
672 if (attrib == NULL) {
673 IRDA_DEBUG(2, "LM-IAS: Attribute %s not found\n", attr);
674 iriap_getvaluebyclass_response(self, obj->id,
675 IAS_ATTRIB_UNKNOWN,
676 &irias_missing);
677 return;
678 }
679
680 /* We have a match; send the value. */
681 iriap_getvaluebyclass_response(self, obj->id, IAS_SUCCESS,
682 attrib->value);
683
684 return;
685}
686
687/*
688 * Function iriap_send_ack (void)
689 *
690 * Currently not used
691 *
692 */
693void iriap_send_ack(struct iriap_cb *self)
694{
695 struct sk_buff *tx_skb;
696 __u8 *frame;
697
698 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
699
700 IRDA_ASSERT(self != NULL, return;);
701 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
702
703 tx_skb = dev_alloc_skb(64);
704 if (!tx_skb)
705 return;
706
707 /* Reserve space for MUX and LAP header */
708 skb_reserve(tx_skb, self->max_header_size);
709 skb_put(tx_skb, 1);
710 frame = tx_skb->data;
711
712 /* Build frame */
713 frame[0] = IAP_LST | IAP_ACK | self->operation;
714
715 irlmp_data_request(self->lsap, tx_skb);
716}
717
718void iriap_connect_request(struct iriap_cb *self)
719{
720 int ret;
721
722 IRDA_ASSERT(self != NULL, return;);
723 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
724
725 ret = irlmp_connect_request(self->lsap, LSAP_IAS,
726 self->saddr, self->daddr,
727 NULL, NULL);
728 if (ret < 0) {
729 IRDA_DEBUG(0, "%s(), connect failed!\n", __FUNCTION__);
730 self->confirm(IAS_DISCONNECT, 0, NULL, self->priv);
731 }
732}
733
734/*
735 * Function iriap_connect_confirm (handle, skb)
736 *
737 * LSAP connection confirmed!
738 *
739 */
740static void iriap_connect_confirm(void *instance, void *sap,
741 struct qos_info *qos, __u32 max_seg_size,
742 __u8 max_header_size,
743 struct sk_buff *skb)
744{
745 struct iriap_cb *self;
746
747 self = (struct iriap_cb *) instance;
748
749 IRDA_ASSERT(self != NULL, return;);
750 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
751 IRDA_ASSERT(skb != NULL, return;);
752
753 self->max_data_size = max_seg_size;
754 self->max_header_size = max_header_size;
755
756 del_timer(&self->watchdog_timer);
757
758 iriap_do_client_event(self, IAP_LM_CONNECT_CONFIRM, skb);
759
760 /* Drop reference count - see state_s_make_call(). */
761 dev_kfree_skb(skb);
762}
763
764/*
765 * Function iriap_connect_indication ( handle, skb)
766 *
767 * Remote LM-IAS is requesting connection
768 *
769 */
770static void iriap_connect_indication(void *instance, void *sap,
771 struct qos_info *qos, __u32 max_seg_size,
772 __u8 max_header_size,
773 struct sk_buff *skb)
774{
775 struct iriap_cb *self, *new;
776
777 IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
778
779 self = (struct iriap_cb *) instance;
780
781 IRDA_ASSERT(skb != NULL, return;);
782 IRDA_ASSERT(self != NULL, goto out;);
783 IRDA_ASSERT(self->magic == IAS_MAGIC, goto out;);
784
785 /* Start new server */
786 new = iriap_open(LSAP_IAS, IAS_SERVER, NULL, NULL);
787 if (!new) {
788 IRDA_DEBUG(0, "%s(), open failed\n", __FUNCTION__);
789 goto out;
790 }
791
792 /* Now attach up the new "socket" */
793 new->lsap = irlmp_dup(self->lsap, new);
794 if (!new->lsap) {
795 IRDA_DEBUG(0, "%s(), dup failed!\n", __FUNCTION__);
796 goto out;
797 }
798
799 new->max_data_size = max_seg_size;
800 new->max_header_size = max_header_size;
801
802 /* Clean up the original one to keep it in listen state */
803 irlmp_listen(self->lsap);
804
805 iriap_do_server_event(new, IAP_LM_CONNECT_INDICATION, skb);
806
807out:
808 /* Drop reference count - see state_r_disconnect(). */
809 dev_kfree_skb(skb);
810}
811
812/*
813 * Function iriap_data_indication (handle, skb)
814 *
815 * Receives data from connection identified by handle from IrLMP
816 *
817 */
818static int iriap_data_indication(void *instance, void *sap,
819 struct sk_buff *skb)
820{
821 struct iriap_cb *self;
822 __u8 *frame;
823 __u8 opcode;
824
825 IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
826
827 self = (struct iriap_cb *) instance;
828
829 IRDA_ASSERT(skb != NULL, return 0;);
830 IRDA_ASSERT(self != NULL, goto out;);
831 IRDA_ASSERT(self->magic == IAS_MAGIC, goto out;);
832
833 frame = skb->data;
834
835 if (self->mode == IAS_SERVER) {
836 /* Call server */
837 IRDA_DEBUG(4, "%s(), Calling server!\n", __FUNCTION__);
838 iriap_do_r_connect_event(self, IAP_RECV_F_LST, skb);
839 goto out;
840 }
841 opcode = frame[0];
842 if (~opcode & IAP_LST) {
843 IRDA_WARNING("%s:, IrIAS multiframe commands or "
844 "results is not implemented yet!\n",
845 __FUNCTION__);
846 goto out;
847 }
848
849 /* Check for ack frames since they don't contain any data */
850 if (opcode & IAP_ACK) {
851 IRDA_DEBUG(0, "%s() Got ack frame!\n", __FUNCTION__);
852 goto out;
853 }
854
855 opcode &= ~IAP_LST; /* Mask away LST bit */
856
857 switch (opcode) {
858 case GET_INFO_BASE:
859 IRDA_DEBUG(0, "IrLMP GetInfoBaseDetails not implemented!\n");
860 break;
861 case GET_VALUE_BY_CLASS:
862 iriap_do_call_event(self, IAP_RECV_F_LST, NULL);
863
864 switch (frame[1]) {
865 case IAS_SUCCESS:
866 iriap_getvaluebyclass_confirm(self, skb);
867 break;
868 case IAS_CLASS_UNKNOWN:
869 IRDA_DEBUG(1, "%s(), No such class!\n", __FUNCTION__);
870 /* Finished, close connection! */
871 iriap_disconnect_request(self);
872
873 /*
874 * Warning, the client might close us, so remember
875 * no to use self anymore after calling confirm
876 */
877 if (self->confirm)
878 self->confirm(IAS_CLASS_UNKNOWN, 0, NULL,
879 self->priv);
880 break;
881 case IAS_ATTRIB_UNKNOWN:
882 IRDA_DEBUG(1, "%s(), No such attribute!\n", __FUNCTION__);
883 /* Finished, close connection! */
884 iriap_disconnect_request(self);
885
886 /*
887 * Warning, the client might close us, so remember
888 * no to use self anymore after calling confirm
889 */
890 if (self->confirm)
891 self->confirm(IAS_ATTRIB_UNKNOWN, 0, NULL,
892 self->priv);
893 break;
894 }
895 break;
896 default:
897 IRDA_DEBUG(0, "%s(), Unknown op-code: %02x\n", __FUNCTION__,
898 opcode);
899 break;
900 }
901
902out:
903 /* Cleanup - sub-calls will have done skb_get() as needed. */
904 dev_kfree_skb(skb);
905 return 0;
906}
907
908/*
909 * Function iriap_call_indication (self, skb)
910 *
911 * Received call to server from peer LM-IAS
912 *
913 */
914void iriap_call_indication(struct iriap_cb *self, struct sk_buff *skb)
915{
916 __u8 *fp;
917 __u8 opcode;
918
919 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
920
921 IRDA_ASSERT(self != NULL, return;);
922 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
923 IRDA_ASSERT(skb != NULL, return;);
924
925 fp = skb->data;
926
927 opcode = fp[0];
928 if (~opcode & 0x80) {
929 IRDA_WARNING("%s: IrIAS multiframe commands or results"
930 "is not implemented yet!\n", __FUNCTION__);
931 return;
932 }
933 opcode &= 0x7f; /* Mask away LST bit */
934
935 switch (opcode) {
936 case GET_INFO_BASE:
937 IRDA_WARNING("%s: GetInfoBaseDetails not implemented yet!\n",
938 __FUNCTION__);
939 break;
940 case GET_VALUE_BY_CLASS:
941 iriap_getvaluebyclass_indication(self, skb);
942 break;
943 }
944 /* skb will be cleaned up in iriap_data_indication */
945}
946
947/*
948 * Function iriap_watchdog_timer_expired (data)
949 *
950 * Query has taken too long time, so abort
951 *
952 */
953static void iriap_watchdog_timer_expired(void *data)
954{
955 struct iriap_cb *self = (struct iriap_cb *) data;
956
957 IRDA_ASSERT(self != NULL, return;);
958 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
959
960 /* iriap_close(self); */
961}
962
963#ifdef CONFIG_PROC_FS
964
965static const char *ias_value_types[] = {
966 "IAS_MISSING",
967 "IAS_INTEGER",
968 "IAS_OCT_SEQ",
969 "IAS_STRING"
970};
971
972static inline struct ias_object *irias_seq_idx(loff_t pos)
973{
974 struct ias_object *obj;
975
976 for (obj = (struct ias_object *) hashbin_get_first(irias_objects);
977 obj; obj = (struct ias_object *) hashbin_get_next(irias_objects)) {
978 if (pos-- == 0)
979 break;
980 }
981
982 return obj;
983}
984
985static void *irias_seq_start(struct seq_file *seq, loff_t *pos)
986{
987 spin_lock_irq(&irias_objects->hb_spinlock);
988
989 return *pos ? irias_seq_idx(*pos - 1) : SEQ_START_TOKEN;
990}
991
992static void *irias_seq_next(struct seq_file *seq, void *v, loff_t *pos)
993{
994 ++*pos;
995
996 return (v == SEQ_START_TOKEN)
997 ? (void *) hashbin_get_first(irias_objects)
998 : (void *) hashbin_get_next(irias_objects);
999}
1000
1001static void irias_seq_stop(struct seq_file *seq, void *v)
1002{
1003 spin_unlock_irq(&irias_objects->hb_spinlock);
1004}
1005
1006static int irias_seq_show(struct seq_file *seq, void *v)
1007{
1008 if (v == SEQ_START_TOKEN)
1009 seq_puts(seq, "LM-IAS Objects:\n");
1010 else {
1011 struct ias_object *obj = v;
1012 struct ias_attrib *attrib;
1013
1014 IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -EINVAL;);
1015
1016 seq_printf(seq, "name: %s, id=%d\n",
1017 obj->name, obj->id);
1018
1019 /* Careful for priority inversions here !
1020 * All other uses of attrib spinlock are independent of
1021 * the object spinlock, so we are safe. Jean II */
1022 spin_lock(&obj->attribs->hb_spinlock);
1023
1024 /* List all attributes for this object */
1025 for (attrib = (struct ias_attrib *) hashbin_get_first(obj->attribs);
1026 attrib != NULL;
1027 attrib = (struct ias_attrib *) hashbin_get_next(obj->attribs)) {
1028
1029 IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC,
1030 goto outloop; );
1031
1032 seq_printf(seq, " - Attribute name: \"%s\", ",
1033 attrib->name);
1034 seq_printf(seq, "value[%s]: ",
1035 ias_value_types[attrib->value->type]);
1036
1037 switch (attrib->value->type) {
1038 case IAS_INTEGER:
1039 seq_printf(seq, "%d\n",
1040 attrib->value->t.integer);
1041 break;
1042 case IAS_STRING:
1043 seq_printf(seq, "\"%s\"\n",
1044 attrib->value->t.string);
1045 break;
1046 case IAS_OCT_SEQ:
1047 seq_printf(seq, "octet sequence (%d bytes)\n",
1048 attrib->value->len);
1049 break;
1050 case IAS_MISSING:
1051 seq_puts(seq, "missing\n");
1052 break;
1053 default:
1054 seq_printf(seq, "type %d?\n",
1055 attrib->value->type);
1056 }
1057 seq_putc(seq, '\n');
1058
1059 }
1060 IRDA_ASSERT_LABEL(outloop:)
1061 spin_unlock(&obj->attribs->hb_spinlock);
1062 }
1063
1064 return 0;
1065}
1066
1067static struct seq_operations irias_seq_ops = {
1068 .start = irias_seq_start,
1069 .next = irias_seq_next,
1070 .stop = irias_seq_stop,
1071 .show = irias_seq_show,
1072};
1073
1074static int irias_seq_open(struct inode *inode, struct file *file)
1075{
1076 IRDA_ASSERT( irias_objects != NULL, return -EINVAL;);
1077
1078 return seq_open(file, &irias_seq_ops);
1079}
1080
1081struct file_operations irias_seq_fops = {
1082 .owner = THIS_MODULE,
1083 .open = irias_seq_open,
1084 .read = seq_read,
1085 .llseek = seq_lseek,
1086 .release = seq_release,
1087};
1088
1089#endif /* PROC_FS */
diff --git a/net/irda/iriap_event.c b/net/irda/iriap_event.c
new file mode 100644
index 00000000000..a73607450de
--- /dev/null
+++ b/net/irda/iriap_event.c
@@ -0,0 +1,502 @@
1/*********************************************************************
2 *
3 * Filename: iriap_event.c
4 * Version: 0.1
5 * Description: IAP Finite State Machine
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Thu Aug 21 00:02:07 1997
9 * Modified at: Wed Mar 1 11:28:34 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1997, 1999-2000 Dag Brattli <dagb@cs.uit.no>,
13 * All Rights Reserved.
14 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
20 *
21 * Neither Dag Brattli nor University of Tromsø admit liability nor
22 * provide warranty for any of this software. This material is
23 * provided "AS-IS" and at no charge.
24 *
25 ********************************************************************/
26
27#include <net/irda/irda.h>
28#include <net/irda/irlmp.h>
29#include <net/irda/iriap.h>
30#include <net/irda/iriap_event.h>
31
32static void state_s_disconnect (struct iriap_cb *self, IRIAP_EVENT event,
33 struct sk_buff *skb);
34static void state_s_connecting (struct iriap_cb *self, IRIAP_EVENT event,
35 struct sk_buff *skb);
36static void state_s_call (struct iriap_cb *self, IRIAP_EVENT event,
37 struct sk_buff *skb);
38
39static void state_s_make_call (struct iriap_cb *self, IRIAP_EVENT event,
40 struct sk_buff *skb);
41static void state_s_calling (struct iriap_cb *self, IRIAP_EVENT event,
42 struct sk_buff *skb);
43static void state_s_outstanding (struct iriap_cb *self, IRIAP_EVENT event,
44 struct sk_buff *skb);
45static void state_s_replying (struct iriap_cb *self, IRIAP_EVENT event,
46 struct sk_buff *skb);
47static void state_s_wait_for_call(struct iriap_cb *self, IRIAP_EVENT event,
48 struct sk_buff *skb);
49static void state_s_wait_active (struct iriap_cb *self, IRIAP_EVENT event,
50 struct sk_buff *skb);
51
52static void state_r_disconnect (struct iriap_cb *self, IRIAP_EVENT event,
53 struct sk_buff *skb);
54static void state_r_call (struct iriap_cb *self, IRIAP_EVENT event,
55 struct sk_buff *skb);
56static void state_r_waiting (struct iriap_cb *self, IRIAP_EVENT event,
57 struct sk_buff *skb);
58static void state_r_wait_active (struct iriap_cb *self, IRIAP_EVENT event,
59 struct sk_buff *skb);
60static void state_r_receiving (struct iriap_cb *self, IRIAP_EVENT event,
61 struct sk_buff *skb);
62static void state_r_execute (struct iriap_cb *self, IRIAP_EVENT event,
63 struct sk_buff *skb);
64static void state_r_returning (struct iriap_cb *self, IRIAP_EVENT event,
65 struct sk_buff *skb);
66
67static void (*iriap_state[])(struct iriap_cb *self, IRIAP_EVENT event,
68 struct sk_buff *skb) = {
69 /* Client FSM */
70 state_s_disconnect,
71 state_s_connecting,
72 state_s_call,
73
74 /* S-Call FSM */
75 state_s_make_call,
76 state_s_calling,
77 state_s_outstanding,
78 state_s_replying,
79 state_s_wait_for_call,
80 state_s_wait_active,
81
82 /* Server FSM */
83 state_r_disconnect,
84 state_r_call,
85
86 /* R-Connect FSM */
87 state_r_waiting,
88 state_r_wait_active,
89 state_r_receiving,
90 state_r_execute,
91 state_r_returning,
92};
93
94void iriap_next_client_state(struct iriap_cb *self, IRIAP_STATE state)
95{
96 IRDA_ASSERT(self != NULL, return;);
97 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
98
99 self->client_state = state;
100}
101
102void iriap_next_call_state(struct iriap_cb *self, IRIAP_STATE state)
103{
104 IRDA_ASSERT(self != NULL, return;);
105 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
106
107 self->call_state = state;
108}
109
110void iriap_next_server_state(struct iriap_cb *self, IRIAP_STATE state)
111{
112 IRDA_ASSERT(self != NULL, return;);
113 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
114
115 self->server_state = state;
116}
117
118void iriap_next_r_connect_state(struct iriap_cb *self, IRIAP_STATE state)
119{
120 IRDA_ASSERT(self != NULL, return;);
121 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
122
123 self->r_connect_state = state;
124}
125
126void iriap_do_client_event(struct iriap_cb *self, IRIAP_EVENT event,
127 struct sk_buff *skb)
128{
129 IRDA_ASSERT(self != NULL, return;);
130 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
131
132 (*iriap_state[ self->client_state]) (self, event, skb);
133}
134
135void iriap_do_call_event(struct iriap_cb *self, IRIAP_EVENT event,
136 struct sk_buff *skb)
137{
138 IRDA_ASSERT(self != NULL, return;);
139 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
140
141 (*iriap_state[ self->call_state]) (self, event, skb);
142}
143
144void iriap_do_server_event(struct iriap_cb *self, IRIAP_EVENT event,
145 struct sk_buff *skb)
146{
147 IRDA_ASSERT(self != NULL, return;);
148 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
149
150 (*iriap_state[ self->server_state]) (self, event, skb);
151}
152
153void iriap_do_r_connect_event(struct iriap_cb *self, IRIAP_EVENT event,
154 struct sk_buff *skb)
155{
156 IRDA_ASSERT(self != NULL, return;);
157 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
158
159 (*iriap_state[ self->r_connect_state]) (self, event, skb);
160}
161
162
163/*
164 * Function state_s_disconnect (event, skb)
165 *
166 * S-Disconnect, The device has no LSAP connection to a particular
167 * remote device.
168 */
169static void state_s_disconnect(struct iriap_cb *self, IRIAP_EVENT event,
170 struct sk_buff *skb)
171{
172 IRDA_ASSERT(self != NULL, return;);
173 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
174
175 switch (event) {
176 case IAP_CALL_REQUEST_GVBC:
177 iriap_next_client_state(self, S_CONNECTING);
178 IRDA_ASSERT(self->request_skb == NULL, return;);
179 /* Don't forget to refcount it -
180 * see iriap_getvaluebyclass_request(). */
181 skb_get(skb);
182 self->request_skb = skb;
183 iriap_connect_request(self);
184 break;
185 case IAP_LM_DISCONNECT_INDICATION:
186 break;
187 default:
188 IRDA_DEBUG(0, "%s(), Unknown event %d\n", __FUNCTION__, event);
189 break;
190 }
191}
192
193/*
194 * Function state_s_connecting (self, event, skb)
195 *
196 * S-Connecting
197 *
198 */
199static void state_s_connecting(struct iriap_cb *self, IRIAP_EVENT event,
200 struct sk_buff *skb)
201{
202 IRDA_ASSERT(self != NULL, return;);
203 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
204
205 switch (event) {
206 case IAP_LM_CONNECT_CONFIRM:
207 /*
208 * Jump to S-Call FSM
209 */
210 iriap_do_call_event(self, IAP_CALL_REQUEST, skb);
211 /* iriap_call_request(self, 0,0,0); */
212 iriap_next_client_state(self, S_CALL);
213 break;
214 case IAP_LM_DISCONNECT_INDICATION:
215 /* Abort calls */
216 iriap_next_call_state(self, S_MAKE_CALL);
217 iriap_next_client_state(self, S_DISCONNECT);
218 break;
219 default:
220 IRDA_DEBUG(0, "%s(), Unknown event %d\n", __FUNCTION__, event);
221 break;
222 }
223}
224
225/*
226 * Function state_s_call (self, event, skb)
227 *
228 * S-Call, The device can process calls to a specific remote
229 * device. Whenever the LSAP connection is disconnected, this state
230 * catches that event and clears up
231 */
232static void state_s_call(struct iriap_cb *self, IRIAP_EVENT event,
233 struct sk_buff *skb)
234{
235 IRDA_ASSERT(self != NULL, return;);
236
237 switch (event) {
238 case IAP_LM_DISCONNECT_INDICATION:
239 /* Abort calls */
240 iriap_next_call_state(self, S_MAKE_CALL);
241 iriap_next_client_state(self, S_DISCONNECT);
242 break;
243 default:
244 IRDA_DEBUG(0, "state_s_call: Unknown event %d\n", event);
245 break;
246 }
247}
248
249/*
250 * Function state_s_make_call (event, skb)
251 *
252 * S-Make-Call
253 *
254 */
255static void state_s_make_call(struct iriap_cb *self, IRIAP_EVENT event,
256 struct sk_buff *skb)
257{
258 struct sk_buff *tx_skb;
259
260 IRDA_ASSERT(self != NULL, return;);
261
262 switch (event) {
263 case IAP_CALL_REQUEST:
264 /* Already refcounted - see state_s_disconnect() */
265 tx_skb = self->request_skb;
266 self->request_skb = NULL;
267
268 irlmp_data_request(self->lsap, tx_skb);
269 iriap_next_call_state(self, S_OUTSTANDING);
270 break;
271 default:
272 IRDA_DEBUG(0, "%s(), Unknown event %d\n", __FUNCTION__, event);
273 break;
274 }
275}
276
277/*
278 * Function state_s_calling (event, skb)
279 *
280 * S-Calling
281 *
282 */
283static void state_s_calling(struct iriap_cb *self, IRIAP_EVENT event,
284 struct sk_buff *skb)
285{
286 IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__);
287}
288
289/*
290 * Function state_s_outstanding (event, skb)
291 *
292 * S-Outstanding, The device is waiting for a response to a command
293 *
294 */
295static void state_s_outstanding(struct iriap_cb *self, IRIAP_EVENT event,
296 struct sk_buff *skb)
297{
298 IRDA_ASSERT(self != NULL, return;);
299
300 switch (event) {
301 case IAP_RECV_F_LST:
302 /*iriap_send_ack(self);*/
303 /*LM_Idle_request(idle); */
304
305 iriap_next_call_state(self, S_WAIT_FOR_CALL);
306 break;
307 default:
308 IRDA_DEBUG(0, "%s(), Unknown event %d\n", __FUNCTION__, event);
309 break;
310 }
311}
312
313/*
314 * Function state_s_replying (event, skb)
315 *
316 * S-Replying, The device is collecting a multiple part response
317 */
318static void state_s_replying(struct iriap_cb *self, IRIAP_EVENT event,
319 struct sk_buff *skb)
320{
321 IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__);
322}
323
324/*
325 * Function state_s_wait_for_call (event, skb)
326 *
327 * S-Wait-for-Call
328 *
329 */
330static void state_s_wait_for_call(struct iriap_cb *self, IRIAP_EVENT event,
331 struct sk_buff *skb)
332{
333 IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__);
334}
335
336
337/*
338 * Function state_s_wait_active (event, skb)
339 *
340 * S-Wait-Active
341 *
342 */
343static void state_s_wait_active(struct iriap_cb *self, IRIAP_EVENT event,
344 struct sk_buff *skb)
345{
346 IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__);
347}
348
349/**************************************************************************
350 *
351 * Server FSM
352 *
353 **************************************************************************/
354
355/*
356 * Function state_r_disconnect (self, event, skb)
357 *
358 * LM-IAS server is disconnected (not processing any requests!)
359 *
360 */
361static void state_r_disconnect(struct iriap_cb *self, IRIAP_EVENT event,
362 struct sk_buff *skb)
363{
364 struct sk_buff *tx_skb;
365
366 switch (event) {
367 case IAP_LM_CONNECT_INDICATION:
368 tx_skb = dev_alloc_skb(64);
369 if (tx_skb == NULL) {
370 IRDA_WARNING("%s: unable to malloc!\n", __FUNCTION__);
371 return;
372 }
373
374 /* Reserve space for MUX_CONTROL and LAP header */
375 skb_reserve(tx_skb, LMP_MAX_HEADER);
376
377 irlmp_connect_response(self->lsap, tx_skb);
378 /*LM_Idle_request(idle); */
379
380 iriap_next_server_state(self, R_CALL);
381
382 /*
383 * Jump to R-Connect FSM, we skip R-Waiting since we do not
384 * care about LM_Idle_request()!
385 */
386 iriap_next_r_connect_state(self, R_RECEIVING);
387 break;
388 default:
389 IRDA_DEBUG(0, "%s(), unknown event %d\n", __FUNCTION__, event);
390 break;
391 }
392}
393
394/*
395 * Function state_r_call (self, event, skb)
396 */
397static void state_r_call(struct iriap_cb *self, IRIAP_EVENT event,
398 struct sk_buff *skb)
399{
400 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
401
402 switch (event) {
403 case IAP_LM_DISCONNECT_INDICATION:
404 /* Abort call */
405 iriap_next_server_state(self, R_DISCONNECT);
406 iriap_next_r_connect_state(self, R_WAITING);
407 break;
408 default:
409 IRDA_DEBUG(0, "%s(), unknown event!\n", __FUNCTION__);
410 break;
411 }
412}
413
414/*
415 * R-Connect FSM
416 */
417
418/*
419 * Function state_r_waiting (self, event, skb)
420 */
421static void state_r_waiting(struct iriap_cb *self, IRIAP_EVENT event,
422 struct sk_buff *skb)
423{
424 IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__);
425}
426
427static void state_r_wait_active(struct iriap_cb *self, IRIAP_EVENT event,
428 struct sk_buff *skb)
429{
430 IRDA_DEBUG(0, "%s(), Not implemented\n", __FUNCTION__);
431}
432
433/*
434 * Function state_r_receiving (self, event, skb)
435 *
436 * We are receiving a command
437 *
438 */
439static void state_r_receiving(struct iriap_cb *self, IRIAP_EVENT event,
440 struct sk_buff *skb)
441{
442 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
443
444 switch (event) {
445 case IAP_RECV_F_LST:
446 iriap_next_r_connect_state(self, R_EXECUTE);
447
448 iriap_call_indication(self, skb);
449 break;
450 default:
451 IRDA_DEBUG(0, "%s(), unknown event!\n", __FUNCTION__);
452 break;
453 }
454}
455
456/*
457 * Function state_r_execute (self, event, skb)
458 *
459 * The server is processing the request
460 *
461 */
462static void state_r_execute(struct iriap_cb *self, IRIAP_EVENT event,
463 struct sk_buff *skb)
464{
465 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
466
467 IRDA_ASSERT(skb != NULL, return;);
468 IRDA_ASSERT(self != NULL, return;);
469 IRDA_ASSERT(self->magic == IAS_MAGIC, return;);
470
471 switch (event) {
472 case IAP_CALL_RESPONSE:
473 /*
474 * Since we don't implement the Waiting state, we return
475 * to state Receiving instead, DB.
476 */
477 iriap_next_r_connect_state(self, R_RECEIVING);
478
479 /* Don't forget to refcount it - see
480 * iriap_getvaluebyclass_response(). */
481 skb_get(skb);
482
483 irlmp_data_request(self->lsap, skb);
484 break;
485 default:
486 IRDA_DEBUG(0, "%s(), unknown event!\n", __FUNCTION__);
487 break;
488 }
489}
490
491static void state_r_returning(struct iriap_cb *self, IRIAP_EVENT event,
492 struct sk_buff *skb)
493{
494 IRDA_DEBUG(0, "%s(), event=%d\n", __FUNCTION__, event);
495
496 switch (event) {
497 case IAP_RECV_F_LST:
498 break;
499 default:
500 break;
501 }
502}
diff --git a/net/irda/irias_object.c b/net/irda/irias_object.c
new file mode 100644
index 00000000000..6fec428b451
--- /dev/null
+++ b/net/irda/irias_object.c
@@ -0,0 +1,580 @@
1/*********************************************************************
2 *
3 * Filename: irias_object.c
4 * Version: 0.3
5 * Description: IAS object database and functions
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Thu Oct 1 22:50:04 1998
9 * Modified at: Wed Dec 15 11:23:16 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * Neither Dag Brattli nor University of Tromsø admit liability nor
20 * provide warranty for any of this software. This material is
21 * provided "AS-IS" and at no charge.
22 *
23 ********************************************************************/
24
25#include <linux/string.h>
26#include <linux/socket.h>
27#include <linux/module.h>
28
29#include <net/irda/irda.h>
30#include <net/irda/irias_object.h>
31
32hashbin_t *irias_objects;
33
34/*
35 * Used when a missing value needs to be returned
36 */
37struct ias_value irias_missing = { IAS_MISSING, 0, 0, 0, {0}};
38
39/*
40 * Function strndup (str, max)
41 *
42 * My own kernel version of strndup!
43 *
44 * Faster, check boundary... Jean II
45 */
46static char *strndup(char *str, int max)
47{
48 char *new_str;
49 int len;
50
51 /* Check string */
52 if (str == NULL)
53 return NULL;
54 /* Check length, truncate */
55 len = strlen(str);
56 if(len > max)
57 len = max;
58
59 /* Allocate new string */
60 new_str = kmalloc(len + 1, GFP_ATOMIC);
61 if (new_str == NULL) {
62 IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
63 return NULL;
64 }
65
66 /* Copy and truncate */
67 memcpy(new_str, str, len);
68 new_str[len] = '\0';
69
70 return new_str;
71}
72
73/*
74 * Function ias_new_object (name, id)
75 *
76 * Create a new IAS object
77 *
78 */
79struct ias_object *irias_new_object( char *name, int id)
80{
81 struct ias_object *obj;
82
83 IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
84
85 obj = (struct ias_object *) kmalloc(sizeof(struct ias_object),
86 GFP_ATOMIC);
87 if (obj == NULL) {
88 IRDA_WARNING("%s(), Unable to allocate object!\n",
89 __FUNCTION__);
90 return NULL;
91 }
92 memset(obj, 0, sizeof( struct ias_object));
93
94 obj->magic = IAS_OBJECT_MAGIC;
95 obj->name = strndup(name, IAS_MAX_CLASSNAME);
96 obj->id = id;
97
98 /* Locking notes : the attrib spinlock has lower precendence
99 * than the objects spinlock. Never grap the objects spinlock
100 * while holding any attrib spinlock (risk of deadlock). Jean II */
101 obj->attribs = hashbin_new(HB_LOCK);
102
103 if (obj->attribs == NULL) {
104 IRDA_WARNING("%s(), Unable to allocate attribs!\n",
105 __FUNCTION__);
106 kfree(obj);
107 return NULL;
108 }
109
110 return obj;
111}
112EXPORT_SYMBOL(irias_new_object);
113
114/*
115 * Function irias_delete_attrib (attrib)
116 *
117 * Delete given attribute and deallocate all its memory
118 *
119 */
120static void __irias_delete_attrib(struct ias_attrib *attrib)
121{
122 IRDA_ASSERT(attrib != NULL, return;);
123 IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
124
125 if (attrib->name)
126 kfree(attrib->name);
127
128 irias_delete_value(attrib->value);
129 attrib->magic = ~IAS_ATTRIB_MAGIC;
130
131 kfree(attrib);
132}
133
134void __irias_delete_object(struct ias_object *obj)
135{
136 IRDA_ASSERT(obj != NULL, return;);
137 IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
138
139 if (obj->name)
140 kfree(obj->name);
141
142 hashbin_delete(obj->attribs, (FREE_FUNC) __irias_delete_attrib);
143
144 obj->magic = ~IAS_OBJECT_MAGIC;
145
146 kfree(obj);
147}
148
149/*
150 * Function irias_delete_object (obj)
151 *
152 * Remove object from hashbin and deallocate all attributes associated with
153 * with this object and the object itself
154 *
155 */
156int irias_delete_object(struct ias_object *obj)
157{
158 struct ias_object *node;
159
160 IRDA_ASSERT(obj != NULL, return -1;);
161 IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
162
163 /* Remove from list */
164 node = hashbin_remove_this(irias_objects, (irda_queue_t *) obj);
165 if (!node)
166 IRDA_DEBUG( 0, "%s(), object already removed!\n",
167 __FUNCTION__);
168
169 /* Destroy */
170 __irias_delete_object(obj);
171
172 return 0;
173}
174EXPORT_SYMBOL(irias_delete_object);
175
176/*
177 * Function irias_delete_attrib (obj)
178 *
179 * Remove attribute from hashbin and, if it was the last attribute of
180 * the object, remove the object as well.
181 *
182 */
183int irias_delete_attrib(struct ias_object *obj, struct ias_attrib *attrib,
184 int cleanobject)
185{
186 struct ias_attrib *node;
187
188 IRDA_ASSERT(obj != NULL, return -1;);
189 IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
190 IRDA_ASSERT(attrib != NULL, return -1;);
191
192 /* Remove attribute from object */
193 node = hashbin_remove_this(obj->attribs, (irda_queue_t *) attrib);
194 if (!node)
195 return 0; /* Already removed or non-existent */
196
197 /* Deallocate attribute */
198 __irias_delete_attrib(node);
199
200 /* Check if object has still some attributes, destroy it if none.
201 * At first glance, this look dangerous, as the kernel reference
202 * various IAS objects. However, we only use this function on
203 * user attributes, not kernel attributes, so there is no risk
204 * of deleting a kernel object this way. Jean II */
205 node = (struct ias_attrib *) hashbin_get_first(obj->attribs);
206 if (cleanobject && !node)
207 irias_delete_object(obj);
208
209 return 0;
210}
211
212/*
213 * Function irias_insert_object (obj)
214 *
215 * Insert an object into the LM-IAS database
216 *
217 */
218void irias_insert_object(struct ias_object *obj)
219{
220 IRDA_ASSERT(obj != NULL, return;);
221 IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
222
223 hashbin_insert(irias_objects, (irda_queue_t *) obj, 0, obj->name);
224}
225EXPORT_SYMBOL(irias_insert_object);
226
227/*
228 * Function irias_find_object (name)
229 *
230 * Find object with given name
231 *
232 */
233struct ias_object *irias_find_object(char *name)
234{
235 IRDA_ASSERT(name != NULL, return NULL;);
236
237 /* Unsafe (locking), object might change */
238 return hashbin_lock_find(irias_objects, 0, name);
239}
240EXPORT_SYMBOL(irias_find_object);
241
242/*
243 * Function irias_find_attrib (obj, name)
244 *
245 * Find named attribute in object
246 *
247 */
248struct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name)
249{
250 struct ias_attrib *attrib;
251
252 IRDA_ASSERT(obj != NULL, return NULL;);
253 IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return NULL;);
254 IRDA_ASSERT(name != NULL, return NULL;);
255
256 attrib = hashbin_lock_find(obj->attribs, 0, name);
257 if (attrib == NULL)
258 return NULL;
259
260 /* Unsafe (locking), attrib might change */
261 return attrib;
262}
263EXPORT_SYMBOL(irias_find_attrib);
264
265/*
266 * Function irias_add_attribute (obj, attrib)
267 *
268 * Add attribute to object
269 *
270 */
271static void irias_add_attrib(struct ias_object *obj, struct ias_attrib *attrib,
272 int owner)
273{
274 IRDA_ASSERT(obj != NULL, return;);
275 IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
276
277 IRDA_ASSERT(attrib != NULL, return;);
278 IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
279
280 /* Set if attrib is owned by kernel or user space */
281 attrib->value->owner = owner;
282
283 hashbin_insert(obj->attribs, (irda_queue_t *) attrib, 0, attrib->name);
284}
285
286/*
287 * Function irias_object_change_attribute (obj_name, attrib_name, new_value)
288 *
289 * Change the value of an objects attribute.
290 *
291 */
292int irias_object_change_attribute(char *obj_name, char *attrib_name,
293 struct ias_value *new_value)
294{
295 struct ias_object *obj;
296 struct ias_attrib *attrib;
297 unsigned long flags;
298
299 /* Find object */
300 obj = hashbin_lock_find(irias_objects, 0, obj_name);
301 if (obj == NULL) {
302 IRDA_WARNING("%s: Unable to find object: %s\n", __FUNCTION__,
303 obj_name);
304 return -1;
305 }
306
307 /* Slightly unsafe (obj might get removed under us) */
308 spin_lock_irqsave(&obj->attribs->hb_spinlock, flags);
309
310 /* Find attribute */
311 attrib = hashbin_find(obj->attribs, 0, attrib_name);
312 if (attrib == NULL) {
313 IRDA_WARNING("%s: Unable to find attribute: %s\n",
314 __FUNCTION__, attrib_name);
315 spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
316 return -1;
317 }
318
319 if ( attrib->value->type != new_value->type) {
320 IRDA_DEBUG( 0, "%s(), changing value type not allowed!\n",
321 __FUNCTION__);
322 spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
323 return -1;
324 }
325
326 /* Delete old value */
327 irias_delete_value(attrib->value);
328
329 /* Insert new value */
330 attrib->value = new_value;
331
332 /* Success */
333 spin_unlock_irqrestore(&obj->attribs->hb_spinlock, flags);
334 return 0;
335}
336EXPORT_SYMBOL(irias_object_change_attribute);
337
338/*
339 * Function irias_object_add_integer_attrib (obj, name, value)
340 *
341 * Add an integer attribute to an LM-IAS object
342 *
343 */
344void irias_add_integer_attrib(struct ias_object *obj, char *name, int value,
345 int owner)
346{
347 struct ias_attrib *attrib;
348
349 IRDA_ASSERT(obj != NULL, return;);
350 IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
351 IRDA_ASSERT(name != NULL, return;);
352
353 attrib = (struct ias_attrib *) kmalloc(sizeof(struct ias_attrib),
354 GFP_ATOMIC);
355 if (attrib == NULL) {
356 IRDA_WARNING("%s: Unable to allocate attribute!\n",
357 __FUNCTION__);
358 return;
359 }
360 memset(attrib, 0, sizeof( struct ias_attrib));
361
362 attrib->magic = IAS_ATTRIB_MAGIC;
363 attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
364
365 /* Insert value */
366 attrib->value = irias_new_integer_value(value);
367
368 irias_add_attrib(obj, attrib, owner);
369}
370EXPORT_SYMBOL(irias_add_integer_attrib);
371
372 /*
373 * Function irias_add_octseq_attrib (obj, name, octet_seq, len)
374 *
375 * Add a octet sequence attribute to an LM-IAS object
376 *
377 */
378
379void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets,
380 int len, int owner)
381{
382 struct ias_attrib *attrib;
383
384 IRDA_ASSERT(obj != NULL, return;);
385 IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
386
387 IRDA_ASSERT(name != NULL, return;);
388 IRDA_ASSERT(octets != NULL, return;);
389
390 attrib = (struct ias_attrib *) kmalloc(sizeof(struct ias_attrib),
391 GFP_ATOMIC);
392 if (attrib == NULL) {
393 IRDA_WARNING("%s: Unable to allocate attribute!\n",
394 __FUNCTION__);
395 return;
396 }
397 memset(attrib, 0, sizeof( struct ias_attrib));
398
399 attrib->magic = IAS_ATTRIB_MAGIC;
400 attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
401
402 attrib->value = irias_new_octseq_value( octets, len);
403
404 irias_add_attrib(obj, attrib, owner);
405}
406EXPORT_SYMBOL(irias_add_octseq_attrib);
407
408/*
409 * Function irias_object_add_string_attrib (obj, string)
410 *
411 * Add a string attribute to an LM-IAS object
412 *
413 */
414void irias_add_string_attrib(struct ias_object *obj, char *name, char *value,
415 int owner)
416{
417 struct ias_attrib *attrib;
418
419 IRDA_ASSERT(obj != NULL, return;);
420 IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
421
422 IRDA_ASSERT(name != NULL, return;);
423 IRDA_ASSERT(value != NULL, return;);
424
425 attrib = (struct ias_attrib *) kmalloc(sizeof( struct ias_attrib),
426 GFP_ATOMIC);
427 if (attrib == NULL) {
428 IRDA_WARNING("%s: Unable to allocate attribute!\n",
429 __FUNCTION__);
430 return;
431 }
432 memset(attrib, 0, sizeof( struct ias_attrib));
433
434 attrib->magic = IAS_ATTRIB_MAGIC;
435 attrib->name = strndup(name, IAS_MAX_ATTRIBNAME);
436
437 attrib->value = irias_new_string_value(value);
438
439 irias_add_attrib(obj, attrib, owner);
440}
441EXPORT_SYMBOL(irias_add_string_attrib);
442
443/*
444 * Function irias_new_integer_value (integer)
445 *
446 * Create new IAS integer value
447 *
448 */
449struct ias_value *irias_new_integer_value(int integer)
450{
451 struct ias_value *value;
452
453 value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
454 if (value == NULL) {
455 IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
456 return NULL;
457 }
458 memset(value, 0, sizeof(struct ias_value));
459
460 value->type = IAS_INTEGER;
461 value->len = 4;
462 value->t.integer = integer;
463
464 return value;
465}
466EXPORT_SYMBOL(irias_new_integer_value);
467
468/*
469 * Function irias_new_string_value (string)
470 *
471 * Create new IAS string value
472 *
473 * Per IrLMP 1.1, 4.3.3.2, strings are up to 256 chars - Jean II
474 */
475struct ias_value *irias_new_string_value(char *string)
476{
477 struct ias_value *value;
478
479 value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
480 if (value == NULL) {
481 IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
482 return NULL;
483 }
484 memset( value, 0, sizeof( struct ias_value));
485
486 value->type = IAS_STRING;
487 value->charset = CS_ASCII;
488 value->t.string = strndup(string, IAS_MAX_STRING);
489 value->len = strlen(value->t.string);
490
491 return value;
492}
493EXPORT_SYMBOL(irias_new_string_value);
494
495/*
496 * Function irias_new_octseq_value (octets, len)
497 *
498 * Create new IAS octet-sequence value
499 *
500 * Per IrLMP 1.1, 4.3.3.2, octet-sequence are up to 1024 bytes - Jean II
501 */
502struct ias_value *irias_new_octseq_value(__u8 *octseq , int len)
503{
504 struct ias_value *value;
505
506 value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
507 if (value == NULL) {
508 IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
509 return NULL;
510 }
511 memset(value, 0, sizeof(struct ias_value));
512
513 value->type = IAS_OCT_SEQ;
514 /* Check length */
515 if(len > IAS_MAX_OCTET_STRING)
516 len = IAS_MAX_OCTET_STRING;
517 value->len = len;
518
519 value->t.oct_seq = kmalloc(len, GFP_ATOMIC);
520 if (value->t.oct_seq == NULL){
521 IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
522 kfree(value);
523 return NULL;
524 }
525 memcpy(value->t.oct_seq, octseq , len);
526 return value;
527}
528EXPORT_SYMBOL(irias_new_octseq_value);
529
530struct ias_value *irias_new_missing_value(void)
531{
532 struct ias_value *value;
533
534 value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
535 if (value == NULL) {
536 IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
537 return NULL;
538 }
539 memset(value, 0, sizeof(struct ias_value));
540
541 value->type = IAS_MISSING;
542 value->len = 0;
543
544 return value;
545}
546
547/*
548 * Function irias_delete_value (value)
549 *
550 * Delete IAS value
551 *
552 */
553void irias_delete_value(struct ias_value *value)
554{
555 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
556
557 IRDA_ASSERT(value != NULL, return;);
558
559 switch (value->type) {
560 case IAS_INTEGER: /* Fallthrough */
561 case IAS_MISSING:
562 /* No need to deallocate */
563 break;
564 case IAS_STRING:
565 /* If string, deallocate string */
566 if (value->t.string != NULL)
567 kfree(value->t.string);
568 break;
569 case IAS_OCT_SEQ:
570 /* If byte stream, deallocate byte stream */
571 if (value->t.oct_seq != NULL)
572 kfree(value->t.oct_seq);
573 break;
574 default:
575 IRDA_DEBUG(0, "%s(), Unknown value type!\n", __FUNCTION__);
576 break;
577 }
578 kfree(value);
579}
580EXPORT_SYMBOL(irias_delete_value);
diff --git a/net/irda/irlan/Kconfig b/net/irda/irlan/Kconfig
new file mode 100644
index 00000000000..951abc2e3a7
--- /dev/null
+++ b/net/irda/irlan/Kconfig
@@ -0,0 +1,14 @@
1config IRLAN
2 tristate "IrLAN protocol"
3 depends on IRDA
4 help
5 Say Y here if you want to build support for the IrLAN protocol.
6 To compile it as a module, choose M here: the module will be called
7 irlan. IrLAN emulates an Ethernet and makes it possible to put up
8 a wireless LAN using infrared beams.
9
10 The IrLAN protocol can be used to talk with infrared access points
11 like the HP NetbeamIR, or the ESI JetEye NET. You can also connect
12 to another Linux machine running the IrLAN protocol for ad-hoc
13 networking!
14
diff --git a/net/irda/irlan/Makefile b/net/irda/irlan/Makefile
new file mode 100644
index 00000000000..77549bc8641
--- /dev/null
+++ b/net/irda/irlan/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the Linux IrDA IrLAN protocol layer.
3#
4
5obj-$(CONFIG_IRLAN) += irlan.o
6
7irlan-objs := irlan_common.o irlan_eth.o irlan_event.o irlan_client.o irlan_provider.o irlan_filter.o irlan_provider_event.o irlan_client_event.o
diff --git a/net/irda/irlan/irlan_client.c b/net/irda/irlan/irlan_client.c
new file mode 100644
index 00000000000..f8e6cb0db04
--- /dev/null
+++ b/net/irda/irlan/irlan_client.c
@@ -0,0 +1,576 @@
1/*********************************************************************
2 *
3 * Filename: irlan_client.c
4 * Version: 0.9
5 * Description: IrDA LAN Access Protocol (IrLAN) Client
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Aug 31 20:14:37 1997
9 * Modified at: Tue Dec 14 15:47:02 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 * Sources: skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
12 * slip.c by Laurence Culhane, <loz@holmes.demon.co.uk>
13 * Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
14 *
15 * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
16 * All Rights Reserved.
17 *
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License as
20 * published by the Free Software Foundation; either version 2 of
21 * the License, or (at your option) any later version.
22 *
23 * Neither Dag Brattli nor University of Tromsø admit liability nor
24 * provide warranty for any of this software. This material is
25 * provided "AS-IS" and at no charge.
26 *
27 ********************************************************************/
28
29#include <linux/kernel.h>
30#include <linux/string.h>
31#include <linux/errno.h>
32#include <linux/init.h>
33#include <linux/netdevice.h>
34#include <linux/etherdevice.h>
35#include <linux/if_arp.h>
36#include <linux/bitops.h>
37#include <net/arp.h>
38
39#include <asm/system.h>
40#include <asm/byteorder.h>
41
42#include <net/irda/irda.h>
43#include <net/irda/irttp.h>
44#include <net/irda/irlmp.h>
45#include <net/irda/irias_object.h>
46#include <net/irda/iriap.h>
47#include <net/irda/timer.h>
48
49#include <net/irda/irlan_common.h>
50#include <net/irda/irlan_event.h>
51#include <net/irda/irlan_eth.h>
52#include <net/irda/irlan_provider.h>
53#include <net/irda/irlan_client.h>
54
55#undef CONFIG_IRLAN_GRATUITOUS_ARP
56
57static void irlan_client_ctrl_disconnect_indication(void *instance, void *sap,
58 LM_REASON reason,
59 struct sk_buff *);
60static int irlan_client_ctrl_data_indication(void *instance, void *sap,
61 struct sk_buff *skb);
62static void irlan_client_ctrl_connect_confirm(void *instance, void *sap,
63 struct qos_info *qos,
64 __u32 max_sdu_size,
65 __u8 max_header_size,
66 struct sk_buff *);
67static void irlan_check_response_param(struct irlan_cb *self, char *param,
68 char *value, int val_len);
69static void irlan_client_open_ctrl_tsap(struct irlan_cb *self);
70
71static void irlan_client_kick_timer_expired(void *data)
72{
73 struct irlan_cb *self = (struct irlan_cb *) data;
74
75 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
76
77 IRDA_ASSERT(self != NULL, return;);
78 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
79
80 /*
81 * If we are in peer mode, the client may not have got the discovery
82 * indication it needs to make progress. If the client is still in
83 * IDLE state, we must kick it to, but only if the provider is not IDLE
84 */
85 if ((self->provider.access_type == ACCESS_PEER) &&
86 (self->client.state == IRLAN_IDLE) &&
87 (self->provider.state != IRLAN_IDLE)) {
88 irlan_client_wakeup(self, self->saddr, self->daddr);
89 }
90}
91
92static void irlan_client_start_kick_timer(struct irlan_cb *self, int timeout)
93{
94 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
95
96 irda_start_timer(&self->client.kick_timer, timeout, (void *) self,
97 irlan_client_kick_timer_expired);
98}
99
100/*
101 * Function irlan_client_wakeup (self, saddr, daddr)
102 *
103 * Wake up client
104 *
105 */
106void irlan_client_wakeup(struct irlan_cb *self, __u32 saddr, __u32 daddr)
107{
108 IRDA_DEBUG(1, "%s()\n", __FUNCTION__ );
109
110 IRDA_ASSERT(self != NULL, return;);
111 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
112
113 /*
114 * Check if we are already awake, or if we are a provider in direct
115 * mode (in that case we must leave the client idle
116 */
117 if ((self->client.state != IRLAN_IDLE) ||
118 (self->provider.access_type == ACCESS_DIRECT))
119 {
120 IRDA_DEBUG(0, "%s(), already awake!\n", __FUNCTION__ );
121 return;
122 }
123
124 /* Addresses may have changed! */
125 self->saddr = saddr;
126 self->daddr = daddr;
127
128 if (self->disconnect_reason == LM_USER_REQUEST) {
129 IRDA_DEBUG(0, "%s(), still stopped by user\n", __FUNCTION__ );
130 return;
131 }
132
133 /* Open TSAPs */
134 irlan_client_open_ctrl_tsap(self);
135 irlan_open_data_tsap(self);
136
137 irlan_do_client_event(self, IRLAN_DISCOVERY_INDICATION, NULL);
138
139 /* Start kick timer */
140 irlan_client_start_kick_timer(self, 2*HZ);
141}
142
143/*
144 * Function irlan_discovery_indication (daddr)
145 *
146 * Remote device with IrLAN server support discovered
147 *
148 */
149void irlan_client_discovery_indication(discinfo_t *discovery,
150 DISCOVERY_MODE mode,
151 void *priv)
152{
153 struct irlan_cb *self;
154 __u32 saddr, daddr;
155
156 IRDA_DEBUG(1, "%s()\n", __FUNCTION__ );
157
158 IRDA_ASSERT(discovery != NULL, return;);
159
160 /*
161 * I didn't check it, but I bet that IrLAN suffer from the same
162 * deficiency as IrComm and doesn't handle two instances
163 * simultaneously connecting to each other.
164 * Same workaround, drop passive discoveries.
165 * Jean II */
166 if(mode == DISCOVERY_PASSIVE)
167 return;
168
169 saddr = discovery->saddr;
170 daddr = discovery->daddr;
171
172 /* Find instance */
173 rcu_read_lock();
174 self = irlan_get_any();
175 if (self) {
176 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
177
178 IRDA_DEBUG(1, "%s(), Found instance (%08x)!\n", __FUNCTION__ ,
179 daddr);
180
181 irlan_client_wakeup(self, saddr, daddr);
182 }
183 rcu_read_unlock();
184}
185
186/*
187 * Function irlan_client_data_indication (handle, skb)
188 *
189 * This function gets the data that is received on the control channel
190 *
191 */
192static int irlan_client_ctrl_data_indication(void *instance, void *sap,
193 struct sk_buff *skb)
194{
195 struct irlan_cb *self;
196
197 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
198
199 self = (struct irlan_cb *) instance;
200
201 IRDA_ASSERT(self != NULL, return -1;);
202 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
203 IRDA_ASSERT(skb != NULL, return -1;);
204
205 irlan_do_client_event(self, IRLAN_DATA_INDICATION, skb);
206
207 /* Ready for a new command */
208 IRDA_DEBUG(2, "%s(), clearing tx_busy\n", __FUNCTION__ );
209 self->client.tx_busy = FALSE;
210
211 /* Check if we have some queued commands waiting to be sent */
212 irlan_run_ctrl_tx_queue(self);
213
214 return 0;
215}
216
217static void irlan_client_ctrl_disconnect_indication(void *instance, void *sap,
218 LM_REASON reason,
219 struct sk_buff *userdata)
220{
221 struct irlan_cb *self;
222 struct tsap_cb *tsap;
223 struct sk_buff *skb;
224
225 IRDA_DEBUG(4, "%s(), reason=%d\n", __FUNCTION__ , reason);
226
227 self = (struct irlan_cb *) instance;
228 tsap = (struct tsap_cb *) sap;
229
230 IRDA_ASSERT(self != NULL, return;);
231 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
232 IRDA_ASSERT(tsap != NULL, return;);
233 IRDA_ASSERT(tsap->magic == TTP_TSAP_MAGIC, return;);
234
235 IRDA_ASSERT(tsap == self->client.tsap_ctrl, return;);
236
237 /* Remove frames queued on the control channel */
238 while ((skb = skb_dequeue(&self->client.txq)) != NULL) {
239 dev_kfree_skb(skb);
240 }
241 self->client.tx_busy = FALSE;
242
243 irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
244}
245
246/*
247 * Function irlan_client_open_tsaps (self)
248 *
249 * Initialize callbacks and open IrTTP TSAPs
250 *
251 */
252static void irlan_client_open_ctrl_tsap(struct irlan_cb *self)
253{
254 struct tsap_cb *tsap;
255 notify_t notify;
256
257 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
258
259 IRDA_ASSERT(self != NULL, return;);
260 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
261
262 /* Check if already open */
263 if (self->client.tsap_ctrl)
264 return;
265
266 irda_notify_init(&notify);
267
268 /* Set up callbacks */
269 notify.data_indication = irlan_client_ctrl_data_indication;
270 notify.connect_confirm = irlan_client_ctrl_connect_confirm;
271 notify.disconnect_indication = irlan_client_ctrl_disconnect_indication;
272 notify.instance = self;
273 strlcpy(notify.name, "IrLAN ctrl (c)", sizeof(notify.name));
274
275 tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, &notify);
276 if (!tsap) {
277 IRDA_DEBUG(2, "%s(), Got no tsap!\n", __FUNCTION__ );
278 return;
279 }
280 self->client.tsap_ctrl = tsap;
281}
282
283/*
284 * Function irlan_client_connect_confirm (handle, skb)
285 *
286 * Connection to peer IrLAN laye confirmed
287 *
288 */
289static void irlan_client_ctrl_connect_confirm(void *instance, void *sap,
290 struct qos_info *qos,
291 __u32 max_sdu_size,
292 __u8 max_header_size,
293 struct sk_buff *skb)
294{
295 struct irlan_cb *self;
296
297 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
298
299 self = (struct irlan_cb *) instance;
300
301 IRDA_ASSERT(self != NULL, return;);
302 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
303
304 self->client.max_sdu_size = max_sdu_size;
305 self->client.max_header_size = max_header_size;
306
307 /* TODO: we could set the MTU depending on the max_sdu_size */
308
309 irlan_do_client_event(self, IRLAN_CONNECT_COMPLETE, NULL);
310}
311
312/*
313 * Function print_ret_code (code)
314 *
315 * Print return code of request to peer IrLAN layer.
316 *
317 */
318static void print_ret_code(__u8 code)
319{
320 switch(code) {
321 case 0:
322 printk(KERN_INFO "Success\n");
323 break;
324 case 1:
325 IRDA_WARNING("IrLAN: Insufficient resources\n");
326 break;
327 case 2:
328 IRDA_WARNING("IrLAN: Invalid command format\n");
329 break;
330 case 3:
331 IRDA_WARNING("IrLAN: Command not supported\n");
332 break;
333 case 4:
334 IRDA_WARNING("IrLAN: Parameter not supported\n");
335 break;
336 case 5:
337 IRDA_WARNING("IrLAN: Value not supported\n");
338 break;
339 case 6:
340 IRDA_WARNING("IrLAN: Not open\n");
341 break;
342 case 7:
343 IRDA_WARNING("IrLAN: Authentication required\n");
344 break;
345 case 8:
346 IRDA_WARNING("IrLAN: Invalid password\n");
347 break;
348 case 9:
349 IRDA_WARNING("IrLAN: Protocol error\n");
350 break;
351 case 255:
352 IRDA_WARNING("IrLAN: Asynchronous status\n");
353 break;
354 }
355}
356
357/*
358 * Function irlan_client_parse_response (self, skb)
359 *
360 * Extract all parameters from received buffer, then feed them to
361 * check_params for parsing
362 */
363void irlan_client_parse_response(struct irlan_cb *self, struct sk_buff *skb)
364{
365 __u8 *frame;
366 __u8 *ptr;
367 int count;
368 int ret;
369 __u16 val_len;
370 int i;
371 char *name;
372 char *value;
373
374 IRDA_ASSERT(skb != NULL, return;);
375
376 IRDA_DEBUG(4, "%s() skb->len=%d\n", __FUNCTION__ , (int) skb->len);
377
378 IRDA_ASSERT(self != NULL, return;);
379 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
380
381 if (!skb) {
382 IRDA_ERROR("%s(), Got NULL skb!\n", __FUNCTION__);
383 return;
384 }
385 frame = skb->data;
386
387 /*
388 * Check return code and print it if not success
389 */
390 if (frame[0]) {
391 print_ret_code(frame[0]);
392 return;
393 }
394
395 name = kmalloc(255, GFP_ATOMIC);
396 if (!name)
397 return;
398 value = kmalloc(1016, GFP_ATOMIC);
399 if (!value) {
400 kfree(name);
401 return;
402 }
403
404 /* How many parameters? */
405 count = frame[1];
406
407 IRDA_DEBUG(4, "%s(), got %d parameters\n", __FUNCTION__ , count);
408
409 ptr = frame+2;
410
411 /* For all parameters */
412 for (i=0; i<count;i++) {
413 ret = irlan_extract_param(ptr, name, value, &val_len);
414 if (ret < 0) {
415 IRDA_DEBUG(2, "%s(), IrLAN, Error!\n", __FUNCTION__ );
416 break;
417 }
418 ptr += ret;
419 irlan_check_response_param(self, name, value, val_len);
420 }
421 /* Cleanup */
422 kfree(name);
423 kfree(value);
424}
425
426/*
427 * Function irlan_check_response_param (self, param, value, val_len)
428 *
429 * Check which parameter is received and update local variables
430 *
431 */
432static void irlan_check_response_param(struct irlan_cb *self, char *param,
433 char *value, int val_len)
434{
435 __u16 tmp_cpu; /* Temporary value in host order */
436 __u8 *bytes;
437 int i;
438
439 IRDA_DEBUG(4, "%s(), parm=%s\n", __FUNCTION__ , param);
440
441 IRDA_ASSERT(self != NULL, return;);
442 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
443
444 /* Media type */
445 if (strcmp(param, "MEDIA") == 0) {
446 if (strcmp(value, "802.3") == 0)
447 self->media = MEDIA_802_3;
448 else
449 self->media = MEDIA_802_5;
450 return;
451 }
452 if (strcmp(param, "FILTER_TYPE") == 0) {
453 if (strcmp(value, "DIRECTED") == 0)
454 self->client.filter_type |= IRLAN_DIRECTED;
455 else if (strcmp(value, "FUNCTIONAL") == 0)
456 self->client.filter_type |= IRLAN_FUNCTIONAL;
457 else if (strcmp(value, "GROUP") == 0)
458 self->client.filter_type |= IRLAN_GROUP;
459 else if (strcmp(value, "MAC_FRAME") == 0)
460 self->client.filter_type |= IRLAN_MAC_FRAME;
461 else if (strcmp(value, "MULTICAST") == 0)
462 self->client.filter_type |= IRLAN_MULTICAST;
463 else if (strcmp(value, "BROADCAST") == 0)
464 self->client.filter_type |= IRLAN_BROADCAST;
465 else if (strcmp(value, "IPX_SOCKET") == 0)
466 self->client.filter_type |= IRLAN_IPX_SOCKET;
467
468 }
469 if (strcmp(param, "ACCESS_TYPE") == 0) {
470 if (strcmp(value, "DIRECT") == 0)
471 self->client.access_type = ACCESS_DIRECT;
472 else if (strcmp(value, "PEER") == 0)
473 self->client.access_type = ACCESS_PEER;
474 else if (strcmp(value, "HOSTED") == 0)
475 self->client.access_type = ACCESS_HOSTED;
476 else {
477 IRDA_DEBUG(2, "%s(), unknown access type!\n", __FUNCTION__ );
478 }
479 }
480 /* IRLAN version */
481 if (strcmp(param, "IRLAN_VER") == 0) {
482 IRDA_DEBUG(4, "IrLAN version %d.%d\n", (__u8) value[0],
483 (__u8) value[1]);
484
485 self->version[0] = value[0];
486 self->version[1] = value[1];
487 return;
488 }
489 /* Which remote TSAP to use for data channel */
490 if (strcmp(param, "DATA_CHAN") == 0) {
491 self->dtsap_sel_data = value[0];
492 IRDA_DEBUG(4, "Data TSAP = %02x\n", self->dtsap_sel_data);
493 return;
494 }
495 if (strcmp(param, "CON_ARB") == 0) {
496 memcpy(&tmp_cpu, value, 2); /* Align value */
497 le16_to_cpus(&tmp_cpu); /* Convert to host order */
498 self->client.recv_arb_val = tmp_cpu;
499 IRDA_DEBUG(2, "%s(), receive arb val=%d\n", __FUNCTION__ ,
500 self->client.recv_arb_val);
501 }
502 if (strcmp(param, "MAX_FRAME") == 0) {
503 memcpy(&tmp_cpu, value, 2); /* Align value */
504 le16_to_cpus(&tmp_cpu); /* Convert to host order */
505 self->client.max_frame = tmp_cpu;
506 IRDA_DEBUG(4, "%s(), max frame=%d\n", __FUNCTION__ ,
507 self->client.max_frame);
508 }
509
510 /* RECONNECT_KEY, in case the link goes down! */
511 if (strcmp(param, "RECONNECT_KEY") == 0) {
512 IRDA_DEBUG(4, "Got reconnect key: ");
513 /* for (i = 0; i < val_len; i++) */
514/* printk("%02x", value[i]); */
515 memcpy(self->client.reconnect_key, value, val_len);
516 self->client.key_len = val_len;
517 IRDA_DEBUG(4, "\n");
518 }
519 /* FILTER_ENTRY, have we got an ethernet address? */
520 if (strcmp(param, "FILTER_ENTRY") == 0) {
521 bytes = value;
522 IRDA_DEBUG(4, "Ethernet address = %02x:%02x:%02x:%02x:%02x:%02x\n",
523 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4],
524 bytes[5]);
525 for (i = 0; i < 6; i++)
526 self->dev->dev_addr[i] = bytes[i];
527 }
528}
529
530/*
531 * Function irlan_client_get_value_confirm (obj_id, value)
532 *
533 * Got results from remote LM-IAS
534 *
535 */
536void irlan_client_get_value_confirm(int result, __u16 obj_id,
537 struct ias_value *value, void *priv)
538{
539 struct irlan_cb *self;
540
541 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
542
543 IRDA_ASSERT(priv != NULL, return;);
544
545 self = (struct irlan_cb *) priv;
546 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
547
548 /* We probably don't need to make any more queries */
549 iriap_close(self->client.iriap);
550 self->client.iriap = NULL;
551
552 /* Check if request succeeded */
553 if (result != IAS_SUCCESS) {
554 IRDA_DEBUG(2, "%s(), got NULL value!\n", __FUNCTION__ );
555 irlan_do_client_event(self, IRLAN_IAS_PROVIDER_NOT_AVAIL,
556 NULL);
557 return;
558 }
559
560 switch (value->type) {
561 case IAS_INTEGER:
562 self->dtsap_sel_ctrl = value->t.integer;
563
564 if (value->t.integer != -1) {
565 irlan_do_client_event(self, IRLAN_IAS_PROVIDER_AVAIL,
566 NULL);
567 return;
568 }
569 irias_delete_value(value);
570 break;
571 default:
572 IRDA_DEBUG(2, "%s(), unknown type!\n", __FUNCTION__ );
573 break;
574 }
575 irlan_do_client_event(self, IRLAN_IAS_PROVIDER_NOT_AVAIL, NULL);
576}
diff --git a/net/irda/irlan/irlan_client_event.c b/net/irda/irlan/irlan_client_event.c
new file mode 100644
index 00000000000..ce943b69e99
--- /dev/null
+++ b/net/irda/irlan/irlan_client_event.c
@@ -0,0 +1,533 @@
1/*********************************************************************
2 *
3 * Filename: irlan_client_event.c
4 * Version: 0.9
5 * Description: IrLAN client state machine
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Aug 31 20:14:37 1997
9 * Modified at: Sun Dec 26 21:52:24 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
13 * All Rights Reserved.
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * Neither Dag Brattli nor University of Tromsø admit liability nor
21 * provide warranty for any of this software. This material is
22 * provided "AS-IS" and at no charge.
23 *
24 ********************************************************************/
25
26#include <linux/skbuff.h>
27
28#include <net/irda/irda.h>
29#include <net/irda/timer.h>
30#include <net/irda/irmod.h>
31#include <net/irda/iriap.h>
32#include <net/irda/irlmp.h>
33#include <net/irda/irttp.h>
34
35#include <net/irda/irlan_common.h>
36#include <net/irda/irlan_client.h>
37#include <net/irda/irlan_event.h>
38
39static int irlan_client_state_idle (struct irlan_cb *self, IRLAN_EVENT event,
40 struct sk_buff *skb);
41static int irlan_client_state_query(struct irlan_cb *self, IRLAN_EVENT event,
42 struct sk_buff *skb);
43static int irlan_client_state_conn (struct irlan_cb *self, IRLAN_EVENT event,
44 struct sk_buff *skb);
45static int irlan_client_state_info (struct irlan_cb *self, IRLAN_EVENT event,
46 struct sk_buff *skb);
47static int irlan_client_state_media(struct irlan_cb *self, IRLAN_EVENT event,
48 struct sk_buff *skb);
49static int irlan_client_state_open (struct irlan_cb *self, IRLAN_EVENT event,
50 struct sk_buff *skb);
51static int irlan_client_state_wait (struct irlan_cb *self, IRLAN_EVENT event,
52 struct sk_buff *skb);
53static int irlan_client_state_arb (struct irlan_cb *self, IRLAN_EVENT event,
54 struct sk_buff *skb);
55static int irlan_client_state_data (struct irlan_cb *self, IRLAN_EVENT event,
56 struct sk_buff *skb);
57static int irlan_client_state_close(struct irlan_cb *self, IRLAN_EVENT event,
58 struct sk_buff *skb);
59static int irlan_client_state_sync (struct irlan_cb *self, IRLAN_EVENT event,
60 struct sk_buff *skb);
61
62static int (*state[])(struct irlan_cb *, IRLAN_EVENT event, struct sk_buff *) =
63{
64 irlan_client_state_idle,
65 irlan_client_state_query,
66 irlan_client_state_conn,
67 irlan_client_state_info,
68 irlan_client_state_media,
69 irlan_client_state_open,
70 irlan_client_state_wait,
71 irlan_client_state_arb,
72 irlan_client_state_data,
73 irlan_client_state_close,
74 irlan_client_state_sync
75};
76
77void irlan_do_client_event(struct irlan_cb *self, IRLAN_EVENT event,
78 struct sk_buff *skb)
79{
80 IRDA_ASSERT(self != NULL, return;);
81 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
82
83 (*state[ self->client.state]) (self, event, skb);
84}
85
86/*
87 * Function irlan_client_state_idle (event, skb, info)
88 *
89 * IDLE, We are waiting for an indication that there is a provider
90 * available.
91 */
92static int irlan_client_state_idle(struct irlan_cb *self, IRLAN_EVENT event,
93 struct sk_buff *skb)
94{
95 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
96
97 IRDA_ASSERT(self != NULL, return -1;);
98 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
99
100 switch (event) {
101 case IRLAN_DISCOVERY_INDICATION:
102 if (self->client.iriap) {
103 IRDA_WARNING("%s(), busy with a previous query\n",
104 __FUNCTION__);
105 return -EBUSY;
106 }
107
108 self->client.iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
109 irlan_client_get_value_confirm);
110 /* Get some values from peer IAS */
111 irlan_next_client_state(self, IRLAN_QUERY);
112 iriap_getvaluebyclass_request(self->client.iriap,
113 self->saddr, self->daddr,
114 "IrLAN", "IrDA:TinyTP:LsapSel");
115 break;
116 case IRLAN_WATCHDOG_TIMEOUT:
117 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
118 break;
119 default:
120 IRDA_DEBUG(4, "%s(), Unknown event %d\n", __FUNCTION__ , event);
121 break;
122 }
123 if (skb)
124 dev_kfree_skb(skb);
125
126 return 0;
127}
128
129/*
130 * Function irlan_client_state_query (event, skb, info)
131 *
132 * QUERY, We have queryed the remote IAS and is ready to connect
133 * to provider, just waiting for the confirm.
134 *
135 */
136static int irlan_client_state_query(struct irlan_cb *self, IRLAN_EVENT event,
137 struct sk_buff *skb)
138{
139 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
140
141 IRDA_ASSERT(self != NULL, return -1;);
142 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
143
144 switch(event) {
145 case IRLAN_IAS_PROVIDER_AVAIL:
146 IRDA_ASSERT(self->dtsap_sel_ctrl != 0, return -1;);
147
148 self->client.open_retries = 0;
149
150 irttp_connect_request(self->client.tsap_ctrl,
151 self->dtsap_sel_ctrl,
152 self->saddr, self->daddr, NULL,
153 IRLAN_MTU, NULL);
154 irlan_next_client_state(self, IRLAN_CONN);
155 break;
156 case IRLAN_IAS_PROVIDER_NOT_AVAIL:
157 IRDA_DEBUG(2, "%s(), IAS_PROVIDER_NOT_AVAIL\n", __FUNCTION__ );
158 irlan_next_client_state(self, IRLAN_IDLE);
159
160 /* Give the client a kick! */
161 if ((self->provider.access_type == ACCESS_PEER) &&
162 (self->provider.state != IRLAN_IDLE))
163 irlan_client_wakeup(self, self->saddr, self->daddr);
164 break;
165 case IRLAN_LMP_DISCONNECT:
166 case IRLAN_LAP_DISCONNECT:
167 irlan_next_client_state(self, IRLAN_IDLE);
168 break;
169 case IRLAN_WATCHDOG_TIMEOUT:
170 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
171 break;
172 default:
173 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
174 break;
175 }
176 if (skb)
177 dev_kfree_skb(skb);
178
179 return 0;
180}
181
182/*
183 * Function irlan_client_state_conn (event, skb, info)
184 *
185 * CONN, We have connected to a provider but has not issued any
186 * commands yet.
187 *
188 */
189static int irlan_client_state_conn(struct irlan_cb *self, IRLAN_EVENT event,
190 struct sk_buff *skb)
191{
192 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
193
194 IRDA_ASSERT(self != NULL, return -1;);
195
196 switch (event) {
197 case IRLAN_CONNECT_COMPLETE:
198 /* Send getinfo cmd */
199 irlan_get_provider_info(self);
200 irlan_next_client_state(self, IRLAN_INFO);
201 break;
202 case IRLAN_LMP_DISCONNECT:
203 case IRLAN_LAP_DISCONNECT:
204 irlan_next_client_state(self, IRLAN_IDLE);
205 break;
206 case IRLAN_WATCHDOG_TIMEOUT:
207 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
208 break;
209 default:
210 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
211 break;
212 }
213 if (skb)
214 dev_kfree_skb(skb);
215
216 return 0;
217}
218
219/*
220 * Function irlan_client_state_info (self, event, skb, info)
221 *
222 * INFO, We have issued a GetInfo command and is awaiting a reply.
223 */
224static int irlan_client_state_info(struct irlan_cb *self, IRLAN_EVENT event,
225 struct sk_buff *skb)
226{
227 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
228
229 IRDA_ASSERT(self != NULL, return -1;);
230
231 switch (event) {
232 case IRLAN_DATA_INDICATION:
233 IRDA_ASSERT(skb != NULL, return -1;);
234
235 irlan_client_parse_response(self, skb);
236
237 irlan_next_client_state(self, IRLAN_MEDIA);
238
239 irlan_get_media_char(self);
240 break;
241
242 case IRLAN_LMP_DISCONNECT:
243 case IRLAN_LAP_DISCONNECT:
244 irlan_next_client_state(self, IRLAN_IDLE);
245 break;
246 case IRLAN_WATCHDOG_TIMEOUT:
247 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
248 break;
249 default:
250 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
251 break;
252 }
253 if (skb)
254 dev_kfree_skb(skb);
255
256 return 0;
257}
258
259/*
260 * Function irlan_client_state_media (self, event, skb, info)
261 *
262 * MEDIA, The irlan_client has issued a GetMedia command and is awaiting a
263 * reply.
264 *
265 */
266static int irlan_client_state_media(struct irlan_cb *self, IRLAN_EVENT event,
267 struct sk_buff *skb)
268{
269 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
270
271 IRDA_ASSERT(self != NULL, return -1;);
272
273 switch(event) {
274 case IRLAN_DATA_INDICATION:
275 irlan_client_parse_response(self, skb);
276 irlan_open_data_channel(self);
277 irlan_next_client_state(self, IRLAN_OPEN);
278 break;
279 case IRLAN_LMP_DISCONNECT:
280 case IRLAN_LAP_DISCONNECT:
281 irlan_next_client_state(self, IRLAN_IDLE);
282 break;
283 case IRLAN_WATCHDOG_TIMEOUT:
284 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
285 break;
286 default:
287 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
288 break;
289 }
290 if (skb)
291 dev_kfree_skb(skb);
292
293 return 0;
294}
295
296/*
297 * Function irlan_client_state_open (self, event, skb, info)
298 *
299 * OPEN, The irlan_client has issued a OpenData command and is awaiting a
300 * reply
301 *
302 */
303static int irlan_client_state_open(struct irlan_cb *self, IRLAN_EVENT event,
304 struct sk_buff *skb)
305{
306 struct qos_info qos;
307
308 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
309
310 IRDA_ASSERT(self != NULL, return -1;);
311
312 switch(event) {
313 case IRLAN_DATA_INDICATION:
314 irlan_client_parse_response(self, skb);
315
316 /*
317 * Check if we have got the remote TSAP for data
318 * communications
319 */
320 IRDA_ASSERT(self->dtsap_sel_data != 0, return -1;);
321
322 /* Check which access type we are dealing with */
323 switch (self->client.access_type) {
324 case ACCESS_PEER:
325 if (self->provider.state == IRLAN_OPEN) {
326
327 irlan_next_client_state(self, IRLAN_ARB);
328 irlan_do_client_event(self, IRLAN_CHECK_CON_ARB,
329 NULL);
330 } else {
331
332 irlan_next_client_state(self, IRLAN_WAIT);
333 }
334 break;
335 case ACCESS_DIRECT:
336 case ACCESS_HOSTED:
337 qos.link_disc_time.bits = 0x01; /* 3 secs */
338
339 irttp_connect_request(self->tsap_data,
340 self->dtsap_sel_data,
341 self->saddr, self->daddr, &qos,
342 IRLAN_MTU, NULL);
343
344 irlan_next_client_state(self, IRLAN_DATA);
345 break;
346 default:
347 IRDA_DEBUG(2, "%s(), unknown access type!\n", __FUNCTION__ );
348 break;
349 }
350 break;
351 case IRLAN_LMP_DISCONNECT:
352 case IRLAN_LAP_DISCONNECT:
353 irlan_next_client_state(self, IRLAN_IDLE);
354 break;
355 case IRLAN_WATCHDOG_TIMEOUT:
356 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
357 break;
358 default:
359 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
360 break;
361 }
362
363 if (skb)
364 dev_kfree_skb(skb);
365
366 return 0;
367}
368
369/*
370 * Function irlan_client_state_wait (self, event, skb, info)
371 *
372 * WAIT, The irlan_client is waiting for the local provider to enter the
373 * provider OPEN state.
374 *
375 */
376static int irlan_client_state_wait(struct irlan_cb *self, IRLAN_EVENT event,
377 struct sk_buff *skb)
378{
379 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
380
381 IRDA_ASSERT(self != NULL, return -1;);
382
383 switch(event) {
384 case IRLAN_PROVIDER_SIGNAL:
385 irlan_next_client_state(self, IRLAN_ARB);
386 irlan_do_client_event(self, IRLAN_CHECK_CON_ARB, NULL);
387 break;
388 case IRLAN_LMP_DISCONNECT:
389 case IRLAN_LAP_DISCONNECT:
390 irlan_next_client_state(self, IRLAN_IDLE);
391 break;
392 case IRLAN_WATCHDOG_TIMEOUT:
393 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
394 break;
395 default:
396 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
397 break;
398 }
399 if (skb)
400 dev_kfree_skb(skb);
401
402 return 0;
403}
404
405static int irlan_client_state_arb(struct irlan_cb *self, IRLAN_EVENT event,
406 struct sk_buff *skb)
407{
408 struct qos_info qos;
409
410 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
411
412 IRDA_ASSERT(self != NULL, return -1;);
413
414 switch(event) {
415 case IRLAN_CHECK_CON_ARB:
416 if (self->client.recv_arb_val == self->provider.send_arb_val) {
417 irlan_next_client_state(self, IRLAN_CLOSE);
418 irlan_close_data_channel(self);
419 } else if (self->client.recv_arb_val <
420 self->provider.send_arb_val)
421 {
422 qos.link_disc_time.bits = 0x01; /* 3 secs */
423
424 irlan_next_client_state(self, IRLAN_DATA);
425 irttp_connect_request(self->tsap_data,
426 self->dtsap_sel_data,
427 self->saddr, self->daddr, &qos,
428 IRLAN_MTU, NULL);
429 } else if (self->client.recv_arb_val >
430 self->provider.send_arb_val)
431 {
432 IRDA_DEBUG(2, "%s(), lost the battle :-(\n", __FUNCTION__ );
433 }
434 break;
435 case IRLAN_DATA_CONNECT_INDICATION:
436 irlan_next_client_state(self, IRLAN_DATA);
437 break;
438 case IRLAN_LMP_DISCONNECT:
439 case IRLAN_LAP_DISCONNECT:
440 irlan_next_client_state(self, IRLAN_IDLE);
441 break;
442 case IRLAN_WATCHDOG_TIMEOUT:
443 IRDA_DEBUG(2, "%s(), IRLAN_WATCHDOG_TIMEOUT\n", __FUNCTION__ );
444 break;
445 default:
446 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
447 break;
448 }
449 if (skb)
450 dev_kfree_skb(skb);
451
452 return 0;
453}
454
455/*
456 * Function irlan_client_state_data (self, event, skb, info)
457 *
458 * DATA, The data channel is connected, allowing data transfers between
459 * the local and remote machines.
460 *
461 */
462static int irlan_client_state_data(struct irlan_cb *self, IRLAN_EVENT event,
463 struct sk_buff *skb)
464{
465 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
466
467 IRDA_ASSERT(self != NULL, return -1;);
468 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
469
470 switch(event) {
471 case IRLAN_DATA_INDICATION:
472 irlan_client_parse_response(self, skb);
473 break;
474 case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
475 case IRLAN_LAP_DISCONNECT:
476 irlan_next_client_state(self, IRLAN_IDLE);
477 break;
478 default:
479 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
480 break;
481 }
482 if (skb)
483 dev_kfree_skb(skb);
484
485 return 0;
486}
487
488/*
489 * Function irlan_client_state_close (self, event, skb, info)
490 *
491 *
492 *
493 */
494static int irlan_client_state_close(struct irlan_cb *self, IRLAN_EVENT event,
495 struct sk_buff *skb)
496{
497 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
498
499 if (skb)
500 dev_kfree_skb(skb);
501
502 return 0;
503}
504
505/*
506 * Function irlan_client_state_sync (self, event, skb, info)
507 *
508 *
509 *
510 */
511static int irlan_client_state_sync(struct irlan_cb *self, IRLAN_EVENT event,
512 struct sk_buff *skb)
513{
514 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
515
516 if (skb)
517 dev_kfree_skb(skb);
518
519 return 0;
520}
521
522
523
524
525
526
527
528
529
530
531
532
533
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
new file mode 100644
index 00000000000..657d1221057
--- /dev/null
+++ b/net/irda/irlan/irlan_common.c
@@ -0,0 +1,1200 @@
1/*********************************************************************
2 *
3 * Filename: irlan_common.c
4 * Version: 0.9
5 * Description: IrDA LAN Access Protocol Implementation
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Aug 31 20:14:37 1997
9 * Modified at: Sun Dec 26 21:53:10 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>,
13 * All Rights Reserved.
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * Neither Dag Brattli nor University of Tromsø admit liability nor
21 * provide warranty for any of this software. This material is
22 * provided "AS-IS" and at no charge.
23 *
24 ********************************************************************/
25
26#include <linux/config.h>
27#include <linux/module.h>
28
29#include <linux/kernel.h>
30#include <linux/string.h>
31#include <linux/init.h>
32#include <linux/errno.h>
33#include <linux/proc_fs.h>
34#include <linux/seq_file.h>
35#include <linux/random.h>
36#include <linux/netdevice.h>
37#include <linux/etherdevice.h>
38#include <linux/rtnetlink.h>
39#include <linux/moduleparam.h>
40#include <linux/bitops.h>
41
42#include <asm/system.h>
43#include <asm/byteorder.h>
44
45#include <net/irda/irda.h>
46#include <net/irda/irttp.h>
47#include <net/irda/irlmp.h>
48#include <net/irda/iriap.h>
49#include <net/irda/timer.h>
50
51#include <net/irda/irlan_common.h>
52#include <net/irda/irlan_client.h>
53#include <net/irda/irlan_provider.h>
54#include <net/irda/irlan_eth.h>
55#include <net/irda/irlan_filter.h>
56
57
58/*
59 * Send gratuitous ARP when connected to a new AP or not. May be a clever
60 * thing to do, but for some reason the machine crashes if you use DHCP. So
61 * lets not use it by default.
62 */
63#undef CONFIG_IRLAN_SEND_GRATUITOUS_ARP
64
65/* extern char sysctl_devname[]; */
66
67/*
68 * Master structure
69 */
70static LIST_HEAD(irlans);
71
72static void *ckey;
73static void *skey;
74
75/* Module parameters */
76static int eth; /* Use "eth" or "irlan" name for devices */
77static int access = ACCESS_PEER; /* PEER, DIRECT or HOSTED */
78
79#ifdef CONFIG_PROC_FS
80static const char *irlan_access[] = {
81 "UNKNOWN",
82 "DIRECT",
83 "PEER",
84 "HOSTED"
85};
86
87static const char *irlan_media[] = {
88 "UNKNOWN",
89 "802.3",
90 "802.5"
91};
92
93extern struct proc_dir_entry *proc_irda;
94
95static int irlan_seq_open(struct inode *inode, struct file *file);
96
97static struct file_operations irlan_fops = {
98 .owner = THIS_MODULE,
99 .open = irlan_seq_open,
100 .read = seq_read,
101 .llseek = seq_lseek,
102 .release = seq_release,
103};
104
105extern struct proc_dir_entry *proc_irda;
106#endif /* CONFIG_PROC_FS */
107
108static struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr);
109static void __irlan_close(struct irlan_cb *self);
110static int __irlan_insert_param(struct sk_buff *skb, char *param, int type,
111 __u8 value_byte, __u16 value_short,
112 __u8 *value_array, __u16 value_len);
113static void irlan_open_unicast_addr(struct irlan_cb *self);
114static void irlan_get_unicast_addr(struct irlan_cb *self);
115void irlan_close_tsaps(struct irlan_cb *self);
116
117/*
118 * Function irlan_init (void)
119 *
120 * Initialize IrLAN layer
121 *
122 */
123static int __init irlan_init(void)
124{
125 struct irlan_cb *new;
126 __u16 hints;
127
128 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
129
130#ifdef CONFIG_PROC_FS
131 { struct proc_dir_entry *proc;
132 proc = create_proc_entry("irlan", 0, proc_irda);
133 if (!proc) {
134 printk(KERN_ERR "irlan_init: can't create /proc entry!\n");
135 return -ENODEV;
136 }
137
138 proc->proc_fops = &irlan_fops;
139 }
140#endif /* CONFIG_PROC_FS */
141
142 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
143 hints = irlmp_service_to_hint(S_LAN);
144
145 /* Register with IrLMP as a client */
146 ckey = irlmp_register_client(hints, &irlan_client_discovery_indication,
147 NULL, NULL);
148
149 /* Register with IrLMP as a service */
150 skey = irlmp_register_service(hints);
151
152 /* Start the master IrLAN instance (the only one for now) */
153 new = irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY);
154
155 /* The master will only open its (listen) control TSAP */
156 irlan_provider_open_ctrl_tsap(new);
157
158 /* Do some fast discovery! */
159 irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS);
160
161 return 0;
162}
163
164static void __exit irlan_cleanup(void)
165{
166 struct irlan_cb *self, *next;
167
168 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
169
170 irlmp_unregister_client(ckey);
171 irlmp_unregister_service(skey);
172
173#ifdef CONFIG_PROC_FS
174 remove_proc_entry("irlan", proc_irda);
175#endif /* CONFIG_PROC_FS */
176
177 /* Cleanup any leftover network devices */
178 rtnl_lock();
179 list_for_each_entry_safe(self, next, &irlans, dev_list) {
180 __irlan_close(self);
181 }
182 rtnl_unlock();
183}
184
185/*
186 * Function irlan_open (void)
187 *
188 * Open new instance of a client/provider, we should only register the
189 * network device if this instance is ment for a particular client/provider
190 */
191static struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr)
192{
193 struct net_device *dev;
194 struct irlan_cb *self;
195
196 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
197
198 /* Create network device with irlan */
199 dev = alloc_irlandev(eth ? "eth%d" : "irlan%d");
200 if (!dev)
201 return NULL;
202
203 self = dev->priv;
204 self->dev = dev;
205
206 /*
207 * Initialize local device structure
208 */
209 self->magic = IRLAN_MAGIC;
210 self->saddr = saddr;
211 self->daddr = daddr;
212
213 /* Provider access can only be PEER, DIRECT, or HOSTED */
214 self->provider.access_type = access;
215 if (access == ACCESS_DIRECT) {
216 /*
217 * Since we are emulating an IrLAN sever we will have to
218 * give ourself an ethernet address!
219 */
220 dev->dev_addr[0] = 0x40;
221 dev->dev_addr[1] = 0x00;
222 dev->dev_addr[2] = 0x00;
223 dev->dev_addr[3] = 0x00;
224 get_random_bytes(dev->dev_addr+4, 1);
225 get_random_bytes(dev->dev_addr+5, 1);
226 }
227
228 self->media = MEDIA_802_3;
229 self->disconnect_reason = LM_USER_REQUEST;
230 init_timer(&self->watchdog_timer);
231 init_timer(&self->client.kick_timer);
232 init_waitqueue_head(&self->open_wait);
233
234 skb_queue_head_init(&self->client.txq);
235
236 irlan_next_client_state(self, IRLAN_IDLE);
237 irlan_next_provider_state(self, IRLAN_IDLE);
238
239 if (register_netdev(dev)) {
240 IRDA_DEBUG(2, "%s(), register_netdev() failed!\n",
241 __FUNCTION__ );
242 self = NULL;
243 free_netdev(dev);
244 } else {
245 rtnl_lock();
246 list_add_rcu(&self->dev_list, &irlans);
247 rtnl_unlock();
248 }
249
250 return self;
251}
252/*
253 * Function __irlan_close (self)
254 *
255 * This function closes and deallocates the IrLAN client instances. Be
256 * aware that other functions which calls client_close() must
257 * remove self from irlans list first.
258 */
259static void __irlan_close(struct irlan_cb *self)
260{
261 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
262
263 ASSERT_RTNL();
264 IRDA_ASSERT(self != NULL, return;);
265 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
266
267 del_timer_sync(&self->watchdog_timer);
268 del_timer_sync(&self->client.kick_timer);
269
270 /* Close all open connections and remove TSAPs */
271 irlan_close_tsaps(self);
272
273 if (self->client.iriap)
274 iriap_close(self->client.iriap);
275
276 /* Remove frames queued on the control channel */
277 skb_queue_purge(&self->client.txq);
278
279 /* Unregister and free self via destructor */
280 unregister_netdevice(self->dev);
281}
282
283/* Find any instance of irlan, used for client discovery wakeup */
284struct irlan_cb *irlan_get_any(void)
285{
286 struct irlan_cb *self;
287
288 list_for_each_entry_rcu(self, &irlans, dev_list) {
289 return self;
290 }
291 return NULL;
292}
293
294/*
295 * Function irlan_connect_indication (instance, sap, qos, max_sdu_size, skb)
296 *
297 * Here we receive the connect indication for the data channel
298 *
299 */
300static void irlan_connect_indication(void *instance, void *sap,
301 struct qos_info *qos,
302 __u32 max_sdu_size,
303 __u8 max_header_size,
304 struct sk_buff *skb)
305{
306 struct irlan_cb *self;
307 struct tsap_cb *tsap;
308
309 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
310
311 self = (struct irlan_cb *) instance;
312 tsap = (struct tsap_cb *) sap;
313
314 IRDA_ASSERT(self != NULL, return;);
315 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
316 IRDA_ASSERT(tsap == self->tsap_data,return;);
317
318 self->max_sdu_size = max_sdu_size;
319 self->max_header_size = max_header_size;
320
321 IRDA_DEBUG(0, "%s: We are now connected!\n", __FUNCTION__);
322
323 del_timer(&self->watchdog_timer);
324
325 /* If you want to pass the skb to *both* state machines, you will
326 * need to skb_clone() it, so that you don't free it twice.
327 * As the state machines don't need it, git rid of it here...
328 * Jean II */
329 if (skb)
330 dev_kfree_skb(skb);
331
332 irlan_do_provider_event(self, IRLAN_DATA_CONNECT_INDICATION, NULL);
333 irlan_do_client_event(self, IRLAN_DATA_CONNECT_INDICATION, NULL);
334
335 if (self->provider.access_type == ACCESS_PEER) {
336 /*
337 * Data channel is open, so we are now allowed to
338 * configure the remote filter
339 */
340 irlan_get_unicast_addr(self);
341 irlan_open_unicast_addr(self);
342 }
343 /* Ready to transfer Ethernet frames (at last) */
344 netif_start_queue(self->dev); /* Clear reason */
345}
346
347static void irlan_connect_confirm(void *instance, void *sap,
348 struct qos_info *qos,
349 __u32 max_sdu_size,
350 __u8 max_header_size,
351 struct sk_buff *skb)
352{
353 struct irlan_cb *self;
354
355 self = (struct irlan_cb *) instance;
356
357 IRDA_ASSERT(self != NULL, return;);
358 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
359
360 self->max_sdu_size = max_sdu_size;
361 self->max_header_size = max_header_size;
362
363 /* TODO: we could set the MTU depending on the max_sdu_size */
364
365 IRDA_DEBUG(0, "%s: We are now connected!\n", __FUNCTION__);
366 del_timer(&self->watchdog_timer);
367
368 /*
369 * Data channel is open, so we are now allowed to configure the remote
370 * filter
371 */
372 irlan_get_unicast_addr(self);
373 irlan_open_unicast_addr(self);
374
375 /* Open broadcast and multicast filter by default */
376 irlan_set_broadcast_filter(self, TRUE);
377 irlan_set_multicast_filter(self, TRUE);
378
379 /* Ready to transfer Ethernet frames */
380 netif_start_queue(self->dev);
381 self->disconnect_reason = 0; /* Clear reason */
382#ifdef CONFIG_IRLAN_SEND_GRATUITOUS_ARP
383 irlan_eth_send_gratuitous_arp(&self->dev);
384#endif
385 wake_up_interruptible(&self->open_wait);
386}
387
388/*
389 * Function irlan_client_disconnect_indication (handle)
390 *
391 * Callback function for the IrTTP layer. Indicates a disconnection of
392 * the specified connection (handle)
393 */
394static void irlan_disconnect_indication(void *instance,
395 void *sap, LM_REASON reason,
396 struct sk_buff *userdata)
397{
398 struct irlan_cb *self;
399 struct tsap_cb *tsap;
400
401 IRDA_DEBUG(0, "%s(), reason=%d\n", __FUNCTION__ , reason);
402
403 self = (struct irlan_cb *) instance;
404 tsap = (struct tsap_cb *) sap;
405
406 IRDA_ASSERT(self != NULL, return;);
407 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
408 IRDA_ASSERT(tsap != NULL, return;);
409 IRDA_ASSERT(tsap->magic == TTP_TSAP_MAGIC, return;);
410
411 IRDA_ASSERT(tsap == self->tsap_data, return;);
412
413 IRDA_DEBUG(2, "IrLAN, data channel disconnected by peer!\n");
414
415 /* Save reason so we know if we should try to reconnect or not */
416 self->disconnect_reason = reason;
417
418 switch (reason) {
419 case LM_USER_REQUEST: /* User request */
420 IRDA_DEBUG(2, "%s(), User requested\n", __FUNCTION__ );
421 break;
422 case LM_LAP_DISCONNECT: /* Unexpected IrLAP disconnect */
423 IRDA_DEBUG(2, "%s(), Unexpected IrLAP disconnect\n", __FUNCTION__ );
424 break;
425 case LM_CONNECT_FAILURE: /* Failed to establish IrLAP connection */
426 IRDA_DEBUG(2, "%s(), IrLAP connect failed\n", __FUNCTION__ );
427 break;
428 case LM_LAP_RESET: /* IrLAP reset */
429 IRDA_DEBUG(2, "%s(), IrLAP reset\n", __FUNCTION__ );
430 break;
431 case LM_INIT_DISCONNECT:
432 IRDA_DEBUG(2, "%s(), IrLMP connect failed\n", __FUNCTION__ );
433 break;
434 default:
435 IRDA_ERROR("%s(), Unknown disconnect reason\n", __FUNCTION__);
436 break;
437 }
438
439 /* If you want to pass the skb to *both* state machines, you will
440 * need to skb_clone() it, so that you don't free it twice.
441 * As the state machines don't need it, git rid of it here...
442 * Jean II */
443 if (userdata)
444 dev_kfree_skb(userdata);
445
446 irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
447 irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);
448
449 wake_up_interruptible(&self->open_wait);
450}
451
452void irlan_open_data_tsap(struct irlan_cb *self)
453{
454 struct tsap_cb *tsap;
455 notify_t notify;
456
457 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
458
459 IRDA_ASSERT(self != NULL, return;);
460 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
461
462 /* Check if already open */
463 if (self->tsap_data)
464 return;
465
466 irda_notify_init(&notify);
467
468 notify.data_indication = irlan_eth_receive;
469 notify.udata_indication = irlan_eth_receive;
470 notify.connect_indication = irlan_connect_indication;
471 notify.connect_confirm = irlan_connect_confirm;
472 notify.flow_indication = irlan_eth_flow_indication;
473 notify.disconnect_indication = irlan_disconnect_indication;
474 notify.instance = self;
475 strlcpy(notify.name, "IrLAN data", sizeof(notify.name));
476
477 tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, &notify);
478 if (!tsap) {
479 IRDA_DEBUG(2, "%s(), Got no tsap!\n", __FUNCTION__ );
480 return;
481 }
482 self->tsap_data = tsap;
483
484 /*
485 * This is the data TSAP selector which we will pass to the client
486 * when the client ask for it.
487 */
488 self->stsap_sel_data = self->tsap_data->stsap_sel;
489}
490
491void irlan_close_tsaps(struct irlan_cb *self)
492{
493 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
494
495 IRDA_ASSERT(self != NULL, return;);
496 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
497
498 /* Disconnect and close all open TSAP connections */
499 if (self->tsap_data) {
500 irttp_disconnect_request(self->tsap_data, NULL, P_NORMAL);
501 irttp_close_tsap(self->tsap_data);
502 self->tsap_data = NULL;
503 }
504 if (self->client.tsap_ctrl) {
505 irttp_disconnect_request(self->client.tsap_ctrl, NULL,
506 P_NORMAL);
507 irttp_close_tsap(self->client.tsap_ctrl);
508 self->client.tsap_ctrl = NULL;
509 }
510 if (self->provider.tsap_ctrl) {
511 irttp_disconnect_request(self->provider.tsap_ctrl, NULL,
512 P_NORMAL);
513 irttp_close_tsap(self->provider.tsap_ctrl);
514 self->provider.tsap_ctrl = NULL;
515 }
516 self->disconnect_reason = LM_USER_REQUEST;
517}
518
519/*
520 * Function irlan_ias_register (self, tsap_sel)
521 *
522 * Register with LM-IAS
523 *
524 */
525void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel)
526{
527 struct ias_object *obj;
528 struct ias_value *new_value;
529
530 IRDA_ASSERT(self != NULL, return;);
531 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
532
533 /*
534 * Check if object has already been registered by a previous provider.
535 * If that is the case, we just change the value of the attribute
536 */
537 if (!irias_find_object("IrLAN")) {
538 obj = irias_new_object("IrLAN", IAS_IRLAN_ID);
539 irias_add_integer_attrib(obj, "IrDA:TinyTP:LsapSel", tsap_sel,
540 IAS_KERNEL_ATTR);
541 irias_insert_object(obj);
542 } else {
543 new_value = irias_new_integer_value(tsap_sel);
544 irias_object_change_attribute("IrLAN", "IrDA:TinyTP:LsapSel",
545 new_value);
546 }
547
548 /* Register PnP object only if not registered before */
549 if (!irias_find_object("PnP")) {
550 obj = irias_new_object("PnP", IAS_PNP_ID);
551#if 0
552 irias_add_string_attrib(obj, "Name", sysctl_devname,
553 IAS_KERNEL_ATTR);
554#else
555 irias_add_string_attrib(obj, "Name", "Linux", IAS_KERNEL_ATTR);
556#endif
557 irias_add_string_attrib(obj, "DeviceID", "HWP19F0",
558 IAS_KERNEL_ATTR);
559 irias_add_integer_attrib(obj, "CompCnt", 1, IAS_KERNEL_ATTR);
560 if (self->provider.access_type == ACCESS_PEER)
561 irias_add_string_attrib(obj, "Comp#01", "PNP8389",
562 IAS_KERNEL_ATTR);
563 else
564 irias_add_string_attrib(obj, "Comp#01", "PNP8294",
565 IAS_KERNEL_ATTR);
566
567 irias_add_string_attrib(obj, "Manufacturer",
568 "Linux-IrDA Project", IAS_KERNEL_ATTR);
569 irias_insert_object(obj);
570 }
571}
572
573/*
574 * Function irlan_run_ctrl_tx_queue (self)
575 *
576 * Try to send the next command in the control transmit queue
577 *
578 */
579int irlan_run_ctrl_tx_queue(struct irlan_cb *self)
580{
581 struct sk_buff *skb;
582
583 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
584
585 if (irda_lock(&self->client.tx_busy) == FALSE)
586 return -EBUSY;
587
588 skb = skb_dequeue(&self->client.txq);
589 if (!skb) {
590 self->client.tx_busy = FALSE;
591 return 0;
592 }
593
594 /* Check that it's really possible to send commands */
595 if ((self->client.tsap_ctrl == NULL) ||
596 (self->client.state == IRLAN_IDLE))
597 {
598 self->client.tx_busy = FALSE;
599 dev_kfree_skb(skb);
600 return -1;
601 }
602 IRDA_DEBUG(2, "%s(), sending ...\n", __FUNCTION__ );
603
604 return irttp_data_request(self->client.tsap_ctrl, skb);
605}
606
607/*
608 * Function irlan_ctrl_data_request (self, skb)
609 *
610 * This function makes sure that commands on the control channel is being
611 * sent in a command/response fashion
612 */
613static void irlan_ctrl_data_request(struct irlan_cb *self, struct sk_buff *skb)
614{
615 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
616
617 /* Queue command */
618 skb_queue_tail(&self->client.txq, skb);
619
620 /* Try to send command */
621 irlan_run_ctrl_tx_queue(self);
622}
623
624/*
625 * Function irlan_get_provider_info (self)
626 *
627 * Send Get Provider Information command to peer IrLAN layer
628 *
629 */
630void irlan_get_provider_info(struct irlan_cb *self)
631{
632 struct sk_buff *skb;
633 __u8 *frame;
634
635 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
636
637 IRDA_ASSERT(self != NULL, return;);
638 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
639
640 skb = dev_alloc_skb(64);
641 if (!skb)
642 return;
643
644 /* Reserve space for TTP, LMP, and LAP header */
645 skb_reserve(skb, self->client.max_header_size);
646 skb_put(skb, 2);
647
648 frame = skb->data;
649
650 frame[0] = CMD_GET_PROVIDER_INFO;
651 frame[1] = 0x00; /* Zero parameters */
652
653 irlan_ctrl_data_request(self, skb);
654}
655
656/*
657 * Function irlan_open_data_channel (self)
658 *
659 * Send an Open Data Command to provider
660 *
661 */
662void irlan_open_data_channel(struct irlan_cb *self)
663{
664 struct sk_buff *skb;
665 __u8 *frame;
666
667 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
668
669 IRDA_ASSERT(self != NULL, return;);
670 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
671
672 skb = dev_alloc_skb(64);
673 if (!skb)
674 return;
675
676 skb_reserve(skb, self->client.max_header_size);
677 skb_put(skb, 2);
678
679 frame = skb->data;
680
681 /* Build frame */
682 frame[0] = CMD_OPEN_DATA_CHANNEL;
683 frame[1] = 0x02; /* Two parameters */
684
685 irlan_insert_string_param(skb, "MEDIA", "802.3");
686 irlan_insert_string_param(skb, "ACCESS_TYPE", "DIRECT");
687 /* irlan_insert_string_param(skb, "MODE", "UNRELIABLE"); */
688
689/* self->use_udata = TRUE; */
690
691 irlan_ctrl_data_request(self, skb);
692}
693
694void irlan_close_data_channel(struct irlan_cb *self)
695{
696 struct sk_buff *skb;
697 __u8 *frame;
698
699 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
700
701 IRDA_ASSERT(self != NULL, return;);
702 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
703
704 /* Check if the TSAP is still there */
705 if (self->client.tsap_ctrl == NULL)
706 return;
707
708 skb = dev_alloc_skb(64);
709 if (!skb)
710 return;
711
712 skb_reserve(skb, self->client.max_header_size);
713 skb_put(skb, 2);
714
715 frame = skb->data;
716
717 /* Build frame */
718 frame[0] = CMD_CLOSE_DATA_CHAN;
719 frame[1] = 0x01; /* Two parameters */
720
721 irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
722
723 irlan_ctrl_data_request(self, skb);
724}
725
726/*
727 * Function irlan_open_unicast_addr (self)
728 *
729 * Make IrLAN provider accept ethernet frames addressed to the unicast
730 * address.
731 *
732 */
733static void irlan_open_unicast_addr(struct irlan_cb *self)
734{
735 struct sk_buff *skb;
736 __u8 *frame;
737
738 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
739
740 IRDA_ASSERT(self != NULL, return;);
741 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
742
743 skb = dev_alloc_skb(128);
744 if (!skb)
745 return;
746
747 /* Reserve space for TTP, LMP, and LAP header */
748 skb_reserve(skb, self->max_header_size);
749 skb_put(skb, 2);
750
751 frame = skb->data;
752
753 frame[0] = CMD_FILTER_OPERATION;
754 frame[1] = 0x03; /* Three parameters */
755 irlan_insert_byte_param(skb, "DATA_CHAN" , self->dtsap_sel_data);
756 irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");
757 irlan_insert_string_param(skb, "FILTER_MODE", "FILTER");
758
759 irlan_ctrl_data_request(self, skb);
760}
761
762/*
763 * Function irlan_set_broadcast_filter (self, status)
764 *
765 * Make IrLAN provider accept ethernet frames addressed to the broadcast
766 * address. Be careful with the use of this one, since there may be a lot
767 * of broadcast traffic out there. We can still function without this
768 * one but then _we_ have to initiate all communication with other
769 * hosts, since ARP request for this host will not be answered.
770 */
771void irlan_set_broadcast_filter(struct irlan_cb *self, int status)
772{
773 struct sk_buff *skb;
774 __u8 *frame;
775
776 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
777
778 IRDA_ASSERT(self != NULL, return;);
779 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
780
781 skb = dev_alloc_skb(128);
782 if (!skb)
783 return;
784
785 /* Reserve space for TTP, LMP, and LAP header */
786 skb_reserve(skb, self->client.max_header_size);
787 skb_put(skb, 2);
788
789 frame = skb->data;
790
791 frame[0] = CMD_FILTER_OPERATION;
792 frame[1] = 0x03; /* Three parameters */
793 irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
794 irlan_insert_string_param(skb, "FILTER_TYPE", "BROADCAST");
795 if (status)
796 irlan_insert_string_param(skb, "FILTER_MODE", "FILTER");
797 else
798 irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
799
800 irlan_ctrl_data_request(self, skb);
801}
802
803/*
804 * Function irlan_set_multicast_filter (self, status)
805 *
806 * Make IrLAN provider accept ethernet frames addressed to the multicast
807 * address.
808 *
809 */
810void irlan_set_multicast_filter(struct irlan_cb *self, int status)
811{
812 struct sk_buff *skb;
813 __u8 *frame;
814
815 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
816
817 IRDA_ASSERT(self != NULL, return;);
818 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
819
820 skb = dev_alloc_skb(128);
821 if (!skb)
822 return;
823
824 /* Reserve space for TTP, LMP, and LAP header */
825 skb_reserve(skb, self->client.max_header_size);
826 skb_put(skb, 2);
827
828 frame = skb->data;
829
830 frame[0] = CMD_FILTER_OPERATION;
831 frame[1] = 0x03; /* Three parameters */
832 irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
833 irlan_insert_string_param(skb, "FILTER_TYPE", "MULTICAST");
834 if (status)
835 irlan_insert_string_param(skb, "FILTER_MODE", "ALL");
836 else
837 irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
838
839 irlan_ctrl_data_request(self, skb);
840}
841
842/*
843 * Function irlan_get_unicast_addr (self)
844 *
845 * Retrieves the unicast address from the IrLAN provider. This address
846 * will be inserted into the devices structure, so the ethernet layer
847 * can construct its packets.
848 *
849 */
850static void irlan_get_unicast_addr(struct irlan_cb *self)
851{
852 struct sk_buff *skb;
853 __u8 *frame;
854
855 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
856
857 IRDA_ASSERT(self != NULL, return;);
858 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
859
860 skb = dev_alloc_skb(128);
861 if (!skb)
862 return;
863
864 /* Reserve space for TTP, LMP, and LAP header */
865 skb_reserve(skb, self->client.max_header_size);
866 skb_put(skb, 2);
867
868 frame = skb->data;
869
870 frame[0] = CMD_FILTER_OPERATION;
871 frame[1] = 0x03; /* Three parameters */
872 irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
873 irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");
874 irlan_insert_string_param(skb, "FILTER_OPERATION", "DYNAMIC");
875
876 irlan_ctrl_data_request(self, skb);
877}
878
879/*
880 * Function irlan_get_media_char (self)
881 *
882 *
883 *
884 */
885void irlan_get_media_char(struct irlan_cb *self)
886{
887 struct sk_buff *skb;
888 __u8 *frame;
889
890 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
891
892 IRDA_ASSERT(self != NULL, return;);
893 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
894
895 skb = dev_alloc_skb(64);
896 if (!skb)
897 return;
898
899 /* Reserve space for TTP, LMP, and LAP header */
900 skb_reserve(skb, self->client.max_header_size);
901 skb_put(skb, 2);
902
903 frame = skb->data;
904
905 /* Build frame */
906 frame[0] = CMD_GET_MEDIA_CHAR;
907 frame[1] = 0x01; /* One parameter */
908
909 irlan_insert_string_param(skb, "MEDIA", "802.3");
910 irlan_ctrl_data_request(self, skb);
911}
912
913/*
914 * Function insert_byte_param (skb, param, value)
915 *
916 * Insert byte parameter into frame
917 *
918 */
919int irlan_insert_byte_param(struct sk_buff *skb, char *param, __u8 value)
920{
921 return __irlan_insert_param(skb, param, IRLAN_BYTE, value, 0, NULL, 0);
922}
923
924int irlan_insert_short_param(struct sk_buff *skb, char *param, __u16 value)
925{
926 return __irlan_insert_param(skb, param, IRLAN_SHORT, 0, value, NULL, 0);
927}
928
929/*
930 * Function insert_string (skb, param, value)
931 *
932 * Insert string parameter into frame
933 *
934 */
935int irlan_insert_string_param(struct sk_buff *skb, char *param, char *string)
936{
937 int string_len = strlen(string);
938
939 return __irlan_insert_param(skb, param, IRLAN_ARRAY, 0, 0, string,
940 string_len);
941}
942
943/*
944 * Function insert_array_param(skb, param, value, len_value)
945 *
946 * Insert array parameter into frame
947 *
948 */
949int irlan_insert_array_param(struct sk_buff *skb, char *name, __u8 *array,
950 __u16 array_len)
951{
952 return __irlan_insert_param(skb, name, IRLAN_ARRAY, 0, 0, array,
953 array_len);
954}
955
956/*
957 * Function insert_param (skb, param, value, byte)
958 *
959 * Insert parameter at end of buffer, structure of a parameter is:
960 *
961 * -----------------------------------------------------------------------
962 * | Name Length[1] | Param Name[1..255] | Val Length[2] | Value[0..1016]|
963 * -----------------------------------------------------------------------
964 */
965static int __irlan_insert_param(struct sk_buff *skb, char *param, int type,
966 __u8 value_byte, __u16 value_short,
967 __u8 *value_array, __u16 value_len)
968{
969 __u8 *frame;
970 __u8 param_len;
971 __u16 tmp_le; /* Temporary value in little endian format */
972 int n=0;
973
974 if (skb == NULL) {
975 IRDA_DEBUG(2, "%s(), Got NULL skb\n", __FUNCTION__ );
976 return 0;
977 }
978
979 param_len = strlen(param);
980 switch (type) {
981 case IRLAN_BYTE:
982 value_len = 1;
983 break;
984 case IRLAN_SHORT:
985 value_len = 2;
986 break;
987 case IRLAN_ARRAY:
988 IRDA_ASSERT(value_array != NULL, return 0;);
989 IRDA_ASSERT(value_len > 0, return 0;);
990 break;
991 default:
992 IRDA_DEBUG(2, "%s(), Unknown parameter type!\n", __FUNCTION__ );
993 return 0;
994 break;
995 }
996
997 /* Insert at end of sk-buffer */
998 frame = skb->tail;
999
1000 /* Make space for data */
1001 if (skb_tailroom(skb) < (param_len+value_len+3)) {
1002 IRDA_DEBUG(2, "%s(), No more space at end of skb\n", __FUNCTION__ );
1003 return 0;
1004 }
1005 skb_put(skb, param_len+value_len+3);
1006
1007 /* Insert parameter length */
1008 frame[n++] = param_len;
1009
1010 /* Insert parameter */
1011 memcpy(frame+n, param, param_len); n += param_len;
1012
1013 /* Insert value length (2 byte little endian format, LSB first) */
1014 tmp_le = cpu_to_le16(value_len);
1015 memcpy(frame+n, &tmp_le, 2); n += 2; /* To avoid alignment problems */
1016
1017 /* Insert value */
1018 switch (type) {
1019 case IRLAN_BYTE:
1020 frame[n++] = value_byte;
1021 break;
1022 case IRLAN_SHORT:
1023 tmp_le = cpu_to_le16(value_short);
1024 memcpy(frame+n, &tmp_le, 2); n += 2;
1025 break;
1026 case IRLAN_ARRAY:
1027 memcpy(frame+n, value_array, value_len); n+=value_len;
1028 break;
1029 default:
1030 break;
1031 }
1032 IRDA_ASSERT(n == (param_len+value_len+3), return 0;);
1033
1034 return param_len+value_len+3;
1035}
1036
1037/*
1038 * Function irlan_extract_param (buf, name, value, len)
1039 *
1040 * Extracts a single parameter name/value pair from buffer and updates
1041 * the buffer pointer to point to the next name/value pair.
1042 */
1043int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len)
1044{
1045 __u8 name_len;
1046 __u16 val_len;
1047 int n=0;
1048
1049 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
1050
1051 /* get length of parameter name (1 byte) */
1052 name_len = buf[n++];
1053
1054 if (name_len > 254) {
1055 IRDA_DEBUG(2, "%s(), name_len > 254\n", __FUNCTION__ );
1056 return -RSP_INVALID_COMMAND_FORMAT;
1057 }
1058
1059 /* get parameter name */
1060 memcpy(name, buf+n, name_len);
1061 name[name_len] = '\0';
1062 n+=name_len;
1063
1064 /*
1065 * Get length of parameter value (2 bytes in little endian
1066 * format)
1067 */
1068 memcpy(&val_len, buf+n, 2); /* To avoid alignment problems */
1069 le16_to_cpus(&val_len); n+=2;
1070
1071 if (val_len > 1016) {
1072 IRDA_DEBUG(2, "%s(), parameter length to long\n", __FUNCTION__ );
1073 return -RSP_INVALID_COMMAND_FORMAT;
1074 }
1075 *len = val_len;
1076
1077 /* get parameter value */
1078 memcpy(value, buf+n, val_len);
1079 value[val_len] = '\0';
1080 n+=val_len;
1081
1082 IRDA_DEBUG(4, "Parameter: %s ", name);
1083 IRDA_DEBUG(4, "Value: %s\n", value);
1084
1085 return n;
1086}
1087
1088#ifdef CONFIG_PROC_FS
1089
1090/*
1091 * Start of reading /proc entries.
1092 * Return entry at pos,
1093 * or start_token to indicate print header line
1094 * or NULL if end of file
1095 */
1096static void *irlan_seq_start(struct seq_file *seq, loff_t *pos)
1097{
1098 int i = 1;
1099 struct irlan_cb *self;
1100
1101 rcu_read_lock();
1102 if (*pos == 0)
1103 return SEQ_START_TOKEN;
1104
1105 list_for_each_entry(self, &irlans, dev_list) {
1106 if (*pos == i)
1107 return self;
1108 ++i;
1109 }
1110 return NULL;
1111}
1112
1113/* Return entry after v, and increment pos */
1114static void *irlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1115{
1116 struct list_head *nxt;
1117
1118 ++*pos;
1119 if (v == SEQ_START_TOKEN)
1120 nxt = irlans.next;
1121 else
1122 nxt = ((struct irlan_cb *)v)->dev_list.next;
1123
1124 return (nxt == &irlans) ? NULL
1125 : list_entry(nxt, struct irlan_cb, dev_list);
1126}
1127
1128/* End of reading /proc file */
1129static void irlan_seq_stop(struct seq_file *seq, void *v)
1130{
1131 rcu_read_unlock();
1132}
1133
1134
1135/*
1136 * Show one entry in /proc file.
1137 */
1138static int irlan_seq_show(struct seq_file *seq, void *v)
1139{
1140 if (v == SEQ_START_TOKEN)
1141 seq_puts(seq, "IrLAN instances:\n");
1142 else {
1143 struct irlan_cb *self = v;
1144
1145 IRDA_ASSERT(self != NULL, return -1;);
1146 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
1147
1148 seq_printf(seq,"ifname: %s,\n",
1149 self->dev->name);
1150 seq_printf(seq,"client state: %s, ",
1151 irlan_state[ self->client.state]);
1152 seq_printf(seq,"provider state: %s,\n",
1153 irlan_state[ self->provider.state]);
1154 seq_printf(seq,"saddr: %#08x, ",
1155 self->saddr);
1156 seq_printf(seq,"daddr: %#08x\n",
1157 self->daddr);
1158 seq_printf(seq,"version: %d.%d,\n",
1159 self->version[1], self->version[0]);
1160 seq_printf(seq,"access type: %s\n",
1161 irlan_access[self->client.access_type]);
1162 seq_printf(seq,"media: %s\n",
1163 irlan_media[self->media]);
1164
1165 seq_printf(seq,"local filter:\n");
1166 seq_printf(seq,"remote filter: ");
1167 irlan_print_filter(seq, self->client.filter_type);
1168 seq_printf(seq,"tx busy: %s\n",
1169 netif_queue_stopped(self->dev) ? "TRUE" : "FALSE");
1170
1171 seq_putc(seq,'\n');
1172 }
1173 return 0;
1174}
1175
1176static struct seq_operations irlan_seq_ops = {
1177 .start = irlan_seq_start,
1178 .next = irlan_seq_next,
1179 .stop = irlan_seq_stop,
1180 .show = irlan_seq_show,
1181};
1182
1183static int irlan_seq_open(struct inode *inode, struct file *file)
1184{
1185 return seq_open(file, &irlan_seq_ops);
1186}
1187#endif
1188
1189MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
1190MODULE_DESCRIPTION("The Linux IrDA LAN protocol");
1191MODULE_LICENSE("GPL");
1192
1193module_param(eth, bool, 0);
1194MODULE_PARM_DESC(eth, "Name devices ethX (0) or irlanX (1)");
1195module_param(access, int, 0);
1196MODULE_PARM_DESC(access, "Access type DIRECT=1, PEER=2, HOSTED=3");
1197
1198module_init(irlan_init);
1199module_exit(irlan_cleanup);
1200
diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c
new file mode 100644
index 00000000000..071cd2cefd8
--- /dev/null
+++ b/net/irda/irlan/irlan_eth.c
@@ -0,0 +1,387 @@
1/*********************************************************************
2 *
3 * Filename: irlan_eth.c
4 * Version:
5 * Description:
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Thu Oct 15 08:37:58 1998
9 * Modified at: Tue Mar 21 09:06:41 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 * Sources: skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
12 * slip.c by Laurence Culhane, <loz@holmes.demon.co.uk>
13 * Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
14 *
15 * Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved.
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License as
19 * published by the Free Software Foundation; either version 2 of
20 * the License, or (at your option) any later version.
21 *
22 * Neither Dag Brattli nor University of Tromsø admit liability nor
23 * provide warranty for any of this software. This material is
24 * provided "AS-IS" and at no charge.
25 *
26 ********************************************************************/
27
28#include <linux/config.h>
29#include <linux/netdevice.h>
30#include <linux/etherdevice.h>
31#include <linux/inetdevice.h>
32#include <linux/if_arp.h>
33#include <linux/module.h>
34#include <net/arp.h>
35
36#include <net/irda/irda.h>
37#include <net/irda/irmod.h>
38#include <net/irda/irlan_common.h>
39#include <net/irda/irlan_client.h>
40#include <net/irda/irlan_event.h>
41#include <net/irda/irlan_eth.h>
42
43static int irlan_eth_open(struct net_device *dev);
44static int irlan_eth_close(struct net_device *dev);
45static int irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev);
46static void irlan_eth_set_multicast_list( struct net_device *dev);
47static struct net_device_stats *irlan_eth_get_stats(struct net_device *dev);
48
49/*
50 * Function irlan_eth_setup (dev)
51 *
52 * The network device initialization function.
53 *
54 */
55static void irlan_eth_setup(struct net_device *dev)
56{
57 dev->open = irlan_eth_open;
58 dev->stop = irlan_eth_close;
59 dev->hard_start_xmit = irlan_eth_xmit;
60 dev->get_stats = irlan_eth_get_stats;
61 dev->set_multicast_list = irlan_eth_set_multicast_list;
62 dev->destructor = free_netdev;
63
64 SET_MODULE_OWNER(dev);
65
66 ether_setup(dev);
67
68 /*
69 * Lets do all queueing in IrTTP instead of this device driver.
70 * Queueing here as well can introduce some strange latency
71 * problems, which we will avoid by setting the queue size to 0.
72 */
73 /*
74 * The bugs in IrTTP and IrLAN that created this latency issue
75 * have now been fixed, and we can propagate flow control properly
76 * to the network layer. However, this requires a minimal queue of
77 * packets for the device.
78 * Without flow control, the Tx Queue is 14 (ttp) + 0 (dev) = 14
79 * With flow control, the Tx Queue is 7 (ttp) + 4 (dev) = 11
80 * See irlan_eth_flow_indication()...
81 * Note : this number was randomly selected and would need to
82 * be adjusted.
83 * Jean II */
84 dev->tx_queue_len = 4;
85}
86
87/*
88 * Function alloc_irlandev
89 *
90 * Allocate network device and control block
91 *
92 */
93struct net_device *alloc_irlandev(const char *name)
94{
95 return alloc_netdev(sizeof(struct irlan_cb), name,
96 irlan_eth_setup);
97}
98
99/*
100 * Function irlan_eth_open (dev)
101 *
102 * Network device has been opened by user
103 *
104 */
105static int irlan_eth_open(struct net_device *dev)
106{
107 struct irlan_cb *self = netdev_priv(dev);
108
109 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
110
111 /* Ready to play! */
112 netif_stop_queue(dev); /* Wait until data link is ready */
113
114 /* We are now open, so time to do some work */
115 self->disconnect_reason = 0;
116 irlan_client_wakeup(self, self->saddr, self->daddr);
117
118 /* Make sure we have a hardware address before we return,
119 so DHCP clients gets happy */
120 return wait_event_interruptible(self->open_wait,
121 !self->tsap_data->connected);
122}
123
124/*
125 * Function irlan_eth_close (dev)
126 *
127 * Stop the ether network device, his function will usually be called by
128 * ifconfig down. We should now disconnect the link, We start the
129 * close timer, so that the instance will be removed if we are unable
130 * to discover the remote device after the disconnect.
131 */
132static int irlan_eth_close(struct net_device *dev)
133{
134 struct irlan_cb *self = netdev_priv(dev);
135
136 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
137
138 /* Stop device */
139 netif_stop_queue(dev);
140
141 irlan_close_data_channel(self);
142 irlan_close_tsaps(self);
143
144 irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
145 irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);
146
147 /* Remove frames queued on the control channel */
148 skb_queue_purge(&self->client.txq);
149
150 self->client.tx_busy = 0;
151
152 return 0;
153}
154
155/*
156 * Function irlan_eth_tx (skb)
157 *
158 * Transmits ethernet frames over IrDA link.
159 *
160 */
161static int irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev)
162{
163 struct irlan_cb *self = netdev_priv(dev);
164 int ret;
165
166 /* skb headroom large enough to contain all IrDA-headers? */
167 if ((skb_headroom(skb) < self->max_header_size) || (skb_shared(skb))) {
168 struct sk_buff *new_skb =
169 skb_realloc_headroom(skb, self->max_header_size);
170
171 /* We have to free the original skb anyway */
172 dev_kfree_skb(skb);
173
174 /* Did the realloc succeed? */
175 if (new_skb == NULL)
176 return 0;
177
178 /* Use the new skb instead */
179 skb = new_skb;
180 }
181
182 dev->trans_start = jiffies;
183
184 /* Now queue the packet in the transport layer */
185 if (self->use_udata)
186 ret = irttp_udata_request(self->tsap_data, skb);
187 else
188 ret = irttp_data_request(self->tsap_data, skb);
189
190 if (ret < 0) {
191 /*
192 * IrTTPs tx queue is full, so we just have to
193 * drop the frame! You might think that we should
194 * just return -1 and don't deallocate the frame,
195 * but that is dangerous since it's possible that
196 * we have replaced the original skb with a new
197 * one with larger headroom, and that would really
198 * confuse do_dev_queue_xmit() in dev.c! I have
199 * tried :-) DB
200 */
201 /* irttp_data_request already free the packet */
202 self->stats.tx_dropped++;
203 } else {
204 self->stats.tx_packets++;
205 self->stats.tx_bytes += skb->len;
206 }
207
208 return 0;
209}
210
211/*
212 * Function irlan_eth_receive (handle, skb)
213 *
214 * This function gets the data that is received on the data channel
215 *
216 */
217int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb)
218{
219 struct irlan_cb *self = instance;
220
221 if (skb == NULL) {
222 ++self->stats.rx_dropped;
223 return 0;
224 }
225 if (skb->len < ETH_HLEN) {
226 IRDA_DEBUG(0, "%s() : IrLAN frame too short (%d)\n",
227 __FUNCTION__, skb->len);
228 ++self->stats.rx_dropped;
229 dev_kfree_skb(skb);
230 return 0;
231 }
232
233 /*
234 * Adopt this frame! Important to set all these fields since they
235 * might have been previously set by the low level IrDA network
236 * device driver
237 */
238 skb->dev = self->dev;
239 skb->protocol=eth_type_trans(skb, skb->dev); /* Remove eth header */
240
241 self->stats.rx_packets++;
242 self->stats.rx_bytes += skb->len;
243
244 netif_rx(skb); /* Eat it! */
245
246 return 0;
247}
248
249/*
250 * Function irlan_eth_flow (status)
251 *
252 * Do flow control between IP/Ethernet and IrLAN/IrTTP. This is done by
253 * controlling the queue stop/start.
254 *
255 * The IrDA link layer has the advantage to have flow control, and
256 * IrTTP now properly handles that. Flow controlling the higher layers
257 * prevent us to drop Tx packets in here (up to 15% for a TCP socket,
258 * more for UDP socket).
259 * Also, this allow us to reduce the overall transmit queue, which means
260 * less latency in case of mixed traffic.
261 * Jean II
262 */
263void irlan_eth_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
264{
265 struct irlan_cb *self;
266 struct net_device *dev;
267
268 self = (struct irlan_cb *) instance;
269
270 IRDA_ASSERT(self != NULL, return;);
271 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
272
273 dev = self->dev;
274
275 IRDA_ASSERT(dev != NULL, return;);
276
277 IRDA_DEBUG(0, "%s() : flow %s ; running %d\n", __FUNCTION__,
278 flow == FLOW_STOP ? "FLOW_STOP" : "FLOW_START",
279 netif_running(dev));
280
281 switch (flow) {
282 case FLOW_STOP:
283 /* IrTTP is full, stop higher layers */
284 netif_stop_queue(dev);
285 break;
286 case FLOW_START:
287 default:
288 /* Tell upper layers that its time to transmit frames again */
289 /* Schedule network layer */
290 netif_wake_queue(dev);
291 break;
292 }
293}
294
295/*
296 * Function irlan_etc_send_gratuitous_arp (dev)
297 *
298 * Send gratuitous ARP to announce that we have changed
299 * hardware address, so that all peers updates their ARP tables
300 */
301void irlan_eth_send_gratuitous_arp(struct net_device *dev)
302{
303 struct in_device *in_dev;
304
305 /*
306 * When we get a new MAC address do a gratuitous ARP. This
307 * is useful if we have changed access points on the same
308 * subnet.
309 */
310#ifdef CONFIG_INET
311 IRDA_DEBUG(4, "IrLAN: Sending gratuitous ARP\n");
312 rcu_read_lock();
313 in_dev = __in_dev_get(dev);
314 if (in_dev == NULL)
315 goto out;
316 if (in_dev->ifa_list)
317
318 arp_send(ARPOP_REQUEST, ETH_P_ARP,
319 in_dev->ifa_list->ifa_address,
320 dev,
321 in_dev->ifa_list->ifa_address,
322 NULL, dev->dev_addr, NULL);
323out:
324 rcu_read_unlock();
325#endif /* CONFIG_INET */
326}
327
328/*
329 * Function set_multicast_list (dev)
330 *
331 * Configure the filtering of the device
332 *
333 */
334#define HW_MAX_ADDRS 4 /* Must query to get it! */
335static void irlan_eth_set_multicast_list(struct net_device *dev)
336{
337 struct irlan_cb *self = netdev_priv(dev);
338
339 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
340
341 /* Check if data channel has been connected yet */
342 if (self->client.state != IRLAN_DATA) {
343 IRDA_DEBUG(1, "%s(), delaying!\n", __FUNCTION__ );
344 return;
345 }
346
347 if (dev->flags & IFF_PROMISC) {
348 /* Enable promiscuous mode */
349 IRDA_WARNING("Promiscous mode not implemented by IrLAN!\n");
350 }
351 else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS) {
352 /* Disable promiscuous mode, use normal mode. */
353 IRDA_DEBUG(4, "%s(), Setting multicast filter\n", __FUNCTION__ );
354 /* hardware_set_filter(NULL); */
355
356 irlan_set_multicast_filter(self, TRUE);
357 }
358 else if (dev->mc_count) {
359 IRDA_DEBUG(4, "%s(), Setting multicast filter\n", __FUNCTION__ );
360 /* Walk the address list, and load the filter */
361 /* hardware_set_filter(dev->mc_list); */
362
363 irlan_set_multicast_filter(self, TRUE);
364 }
365 else {
366 IRDA_DEBUG(4, "%s(), Clearing multicast filter\n", __FUNCTION__ );
367 irlan_set_multicast_filter(self, FALSE);
368 }
369
370 if (dev->flags & IFF_BROADCAST)
371 irlan_set_broadcast_filter(self, TRUE);
372 else
373 irlan_set_broadcast_filter(self, FALSE);
374}
375
376/*
377 * Function irlan_get_stats (dev)
378 *
379 * Get the current statistics for this device
380 *
381 */
382static struct net_device_stats *irlan_eth_get_stats(struct net_device *dev)
383{
384 struct irlan_cb *self = netdev_priv(dev);
385
386 return &self->stats;
387}
diff --git a/net/irda/irlan/irlan_event.c b/net/irda/irlan/irlan_event.c
new file mode 100644
index 00000000000..2778d8c6aa3
--- /dev/null
+++ b/net/irda/irlan/irlan_event.c
@@ -0,0 +1,60 @@
1/*********************************************************************
2 *
3 * Filename: irlan_event.c
4 * Version:
5 * Description:
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Tue Oct 20 09:10:16 1998
9 * Modified at: Sat Oct 30 12:59:01 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * Neither Dag Brattli nor University of Tromsø admit liability nor
20 * provide warranty for any of this software. This material is
21 * provided "AS-IS" and at no charge.
22 *
23 ********************************************************************/
24
25#include <net/irda/irlan_event.h>
26
27char *irlan_state[] = {
28 "IRLAN_IDLE",
29 "IRLAN_QUERY",
30 "IRLAN_CONN",
31 "IRLAN_INFO",
32 "IRLAN_MEDIA",
33 "IRLAN_OPEN",
34 "IRLAN_WAIT",
35 "IRLAN_ARB",
36 "IRLAN_DATA",
37 "IRLAN_CLOSE",
38 "IRLAN_SYNC",
39};
40
41void irlan_next_client_state(struct irlan_cb *self, IRLAN_STATE state)
42{
43 IRDA_DEBUG(2, "%s(), %s\n", __FUNCTION__ , irlan_state[state]);
44
45 IRDA_ASSERT(self != NULL, return;);
46 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
47
48 self->client.state = state;
49}
50
51void irlan_next_provider_state(struct irlan_cb *self, IRLAN_STATE state)
52{
53 IRDA_DEBUG(2, "%s(), %s\n", __FUNCTION__ , irlan_state[state]);
54
55 IRDA_ASSERT(self != NULL, return;);
56 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
57
58 self->provider.state = state;
59}
60
diff --git a/net/irda/irlan/irlan_filter.c b/net/irda/irlan/irlan_filter.c
new file mode 100644
index 00000000000..343c5d4a1a1
--- /dev/null
+++ b/net/irda/irlan/irlan_filter.c
@@ -0,0 +1,246 @@
1/*********************************************************************
2 *
3 * Filename: irlan_filter.c
4 * Version:
5 * Description:
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Fri Jan 29 11:16:38 1999
9 * Modified at: Sat Oct 30 12:58:45 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * Neither Dag Brattli nor University of Tromsø admit liability nor
20 * provide warranty for any of this software. This material is
21 * provided "AS-IS" and at no charge.
22 *
23 ********************************************************************/
24
25#include <linux/skbuff.h>
26#include <linux/random.h>
27#include <linux/seq_file.h>
28
29#include <net/irda/irlan_common.h>
30
31/*
32 * Function irlan_filter_request (self, skb)
33 *
34 * Handle filter request from client peer device
35 *
36 */
37void irlan_filter_request(struct irlan_cb *self, struct sk_buff *skb)
38{
39 IRDA_ASSERT(self != NULL, return;);
40 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
41
42 if ((self->provider.filter_type == IRLAN_DIRECTED) &&
43 (self->provider.filter_operation == DYNAMIC))
44 {
45 IRDA_DEBUG(0, "Giving peer a dynamic Ethernet address\n");
46 self->provider.mac_address[0] = 0x40;
47 self->provider.mac_address[1] = 0x00;
48 self->provider.mac_address[2] = 0x00;
49 self->provider.mac_address[3] = 0x00;
50
51 /* Use arbitration value to generate MAC address */
52 if (self->provider.access_type == ACCESS_PEER) {
53 self->provider.mac_address[4] =
54 self->provider.send_arb_val & 0xff;
55 self->provider.mac_address[5] =
56 (self->provider.send_arb_val >> 8) & 0xff;
57 } else {
58 /* Just generate something for now */
59 get_random_bytes(self->provider.mac_address+4, 1);
60 get_random_bytes(self->provider.mac_address+5, 1);
61 }
62
63 skb->data[0] = 0x00; /* Success */
64 skb->data[1] = 0x03;
65 irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
66 irlan_insert_short_param(skb, "MAX_ENTRY", 0x0001);
67 irlan_insert_array_param(skb, "FILTER_ENTRY",
68 self->provider.mac_address, 6);
69 return;
70 }
71
72 if ((self->provider.filter_type == IRLAN_DIRECTED) &&
73 (self->provider.filter_mode == FILTER))
74 {
75 IRDA_DEBUG(0, "Directed filter on\n");
76 skb->data[0] = 0x00; /* Success */
77 skb->data[1] = 0x00;
78 return;
79 }
80 if ((self->provider.filter_type == IRLAN_DIRECTED) &&
81 (self->provider.filter_mode == NONE))
82 {
83 IRDA_DEBUG(0, "Directed filter off\n");
84 skb->data[0] = 0x00; /* Success */
85 skb->data[1] = 0x00;
86 return;
87 }
88
89 if ((self->provider.filter_type == IRLAN_BROADCAST) &&
90 (self->provider.filter_mode == FILTER))
91 {
92 IRDA_DEBUG(0, "Broadcast filter on\n");
93 skb->data[0] = 0x00; /* Success */
94 skb->data[1] = 0x00;
95 return;
96 }
97 if ((self->provider.filter_type == IRLAN_BROADCAST) &&
98 (self->provider.filter_mode == NONE))
99 {
100 IRDA_DEBUG(0, "Broadcast filter off\n");
101 skb->data[0] = 0x00; /* Success */
102 skb->data[1] = 0x00;
103 return;
104 }
105 if ((self->provider.filter_type == IRLAN_MULTICAST) &&
106 (self->provider.filter_mode == FILTER))
107 {
108 IRDA_DEBUG(0, "Multicast filter on\n");
109 skb->data[0] = 0x00; /* Success */
110 skb->data[1] = 0x00;
111 return;
112 }
113 if ((self->provider.filter_type == IRLAN_MULTICAST) &&
114 (self->provider.filter_mode == NONE))
115 {
116 IRDA_DEBUG(0, "Multicast filter off\n");
117 skb->data[0] = 0x00; /* Success */
118 skb->data[1] = 0x00;
119 return;
120 }
121 if ((self->provider.filter_type == IRLAN_MULTICAST) &&
122 (self->provider.filter_operation == GET))
123 {
124 IRDA_DEBUG(0, "Multicast filter get\n");
125 skb->data[0] = 0x00; /* Success? */
126 skb->data[1] = 0x02;
127 irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
128 irlan_insert_short_param(skb, "MAX_ENTRY", 16);
129 return;
130 }
131 skb->data[0] = 0x00; /* Command not supported */
132 skb->data[1] = 0x00;
133
134 IRDA_DEBUG(0, "Not implemented!\n");
135}
136
137/*
138 * Function check_request_param (self, param, value)
139 *
140 * Check parameters in request from peer device
141 *
142 */
143void irlan_check_command_param(struct irlan_cb *self, char *param, char *value)
144{
145 __u8 *bytes;
146
147 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
148
149 bytes = value;
150
151 IRDA_ASSERT(self != NULL, return;);
152 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
153
154 IRDA_DEBUG(4, "%s, %s\n", param, value);
155
156 /*
157 * This is experimental!! DB.
158 */
159 if (strcmp(param, "MODE") == 0) {
160 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
161 self->use_udata = TRUE;
162 return;
163 }
164
165 /*
166 * FILTER_TYPE
167 */
168 if (strcmp(param, "FILTER_TYPE") == 0) {
169 if (strcmp(value, "DIRECTED") == 0) {
170 self->provider.filter_type = IRLAN_DIRECTED;
171 return;
172 }
173 if (strcmp(value, "MULTICAST") == 0) {
174 self->provider.filter_type = IRLAN_MULTICAST;
175 return;
176 }
177 if (strcmp(value, "BROADCAST") == 0) {
178 self->provider.filter_type = IRLAN_BROADCAST;
179 return;
180 }
181 }
182 /*
183 * FILTER_MODE
184 */
185 if (strcmp(param, "FILTER_MODE") == 0) {
186 if (strcmp(value, "ALL") == 0) {
187 self->provider.filter_mode = ALL;
188 return;
189 }
190 if (strcmp(value, "FILTER") == 0) {
191 self->provider.filter_mode = FILTER;
192 return;
193 }
194 if (strcmp(value, "NONE") == 0) {
195 self->provider.filter_mode = FILTER;
196 return;
197 }
198 }
199 /*
200 * FILTER_OPERATION
201 */
202 if (strcmp(param, "FILTER_OPERATION") == 0) {
203 if (strcmp(value, "DYNAMIC") == 0) {
204 self->provider.filter_operation = DYNAMIC;
205 return;
206 }
207 if (strcmp(value, "GET") == 0) {
208 self->provider.filter_operation = GET;
209 return;
210 }
211 }
212}
213
214/*
215 * Function irlan_print_filter (filter_type, buf)
216 *
217 * Print status of filter. Used by /proc file system
218 *
219 */
220#ifdef CONFIG_PROC_FS
221#define MASK2STR(m,s) { .mask = m, .str = s }
222
223void irlan_print_filter(struct seq_file *seq, int filter_type)
224{
225 static struct {
226 int mask;
227 const char *str;
228 } filter_mask2str[] = {
229 MASK2STR(IRLAN_DIRECTED, "DIRECTED"),
230 MASK2STR(IRLAN_FUNCTIONAL, "FUNCTIONAL"),
231 MASK2STR(IRLAN_GROUP, "GROUP"),
232 MASK2STR(IRLAN_MAC_FRAME, "MAC_FRAME"),
233 MASK2STR(IRLAN_MULTICAST, "MULTICAST"),
234 MASK2STR(IRLAN_BROADCAST, "BROADCAST"),
235 MASK2STR(IRLAN_IPX_SOCKET, "IPX_SOCKET"),
236 MASK2STR(0, NULL)
237 }, *p;
238
239 for (p = filter_mask2str; p->str; p++) {
240 if (filter_type & p->mask)
241 seq_printf(seq, "%s ", p->str);
242 }
243 seq_putc(seq, '\n');
244}
245#undef MASK2STR
246#endif
diff --git a/net/irda/irlan/irlan_provider.c b/net/irda/irlan/irlan_provider.c
new file mode 100644
index 00000000000..39c202d1c37
--- /dev/null
+++ b/net/irda/irlan/irlan_provider.c
@@ -0,0 +1,413 @@
1/*********************************************************************
2 *
3 * Filename: irlan_provider.c
4 * Version: 0.9
5 * Description: IrDA LAN Access Protocol Implementation
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Aug 31 20:14:37 1997
9 * Modified at: Sat Oct 30 12:52:10 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 * Sources: skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
12 * slip.c by Laurence Culhane, <loz@holmes.demon.co.uk>
13 * Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
14 *
15 * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
16 * All Rights Reserved.
17 *
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License as
20 * published by the Free Software Foundation; either version 2 of
21 * the License, or (at your option) any later version.
22 *
23 * Neither Dag Brattli nor University of Tromsø admit liability nor
24 * provide warranty for any of this software. This material is
25 * provided "AS-IS" and at no charge.
26 *
27 ********************************************************************/
28
29#include <linux/kernel.h>
30#include <linux/string.h>
31#include <linux/errno.h>
32#include <linux/netdevice.h>
33#include <linux/etherdevice.h>
34#include <linux/init.h>
35#include <linux/random.h>
36#include <linux/bitops.h>
37
38#include <asm/system.h>
39#include <asm/byteorder.h>
40
41#include <net/irda/irda.h>
42#include <net/irda/irttp.h>
43#include <net/irda/irlmp.h>
44#include <net/irda/irias_object.h>
45#include <net/irda/iriap.h>
46#include <net/irda/timer.h>
47
48#include <net/irda/irlan_common.h>
49#include <net/irda/irlan_eth.h>
50#include <net/irda/irlan_event.h>
51#include <net/irda/irlan_provider.h>
52#include <net/irda/irlan_filter.h>
53#include <net/irda/irlan_client.h>
54
55static void irlan_provider_connect_indication(void *instance, void *sap,
56 struct qos_info *qos,
57 __u32 max_sdu_size,
58 __u8 max_header_size,
59 struct sk_buff *skb);
60
61/*
62 * Function irlan_provider_control_data_indication (handle, skb)
63 *
64 * This function gets the data that is received on the control channel
65 *
66 */
67static int irlan_provider_data_indication(void *instance, void *sap,
68 struct sk_buff *skb)
69{
70 struct irlan_cb *self;
71 __u8 code;
72
73 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
74
75 self = (struct irlan_cb *) instance;
76
77 IRDA_ASSERT(self != NULL, return -1;);
78 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
79
80 IRDA_ASSERT(skb != NULL, return -1;);
81
82 code = skb->data[0];
83 switch(code) {
84 case CMD_GET_PROVIDER_INFO:
85 IRDA_DEBUG(4, "Got GET_PROVIDER_INFO command!\n");
86 irlan_do_provider_event(self, IRLAN_GET_INFO_CMD, skb);
87 break;
88
89 case CMD_GET_MEDIA_CHAR:
90 IRDA_DEBUG(4, "Got GET_MEDIA_CHAR command!\n");
91 irlan_do_provider_event(self, IRLAN_GET_MEDIA_CMD, skb);
92 break;
93 case CMD_OPEN_DATA_CHANNEL:
94 IRDA_DEBUG(4, "Got OPEN_DATA_CHANNEL command!\n");
95 irlan_do_provider_event(self, IRLAN_OPEN_DATA_CMD, skb);
96 break;
97 case CMD_FILTER_OPERATION:
98 IRDA_DEBUG(4, "Got FILTER_OPERATION command!\n");
99 irlan_do_provider_event(self, IRLAN_FILTER_CONFIG_CMD, skb);
100 break;
101 case CMD_RECONNECT_DATA_CHAN:
102 IRDA_DEBUG(2, "%s(), Got RECONNECT_DATA_CHAN command\n", __FUNCTION__ );
103 IRDA_DEBUG(2, "%s(), NOT IMPLEMENTED\n", __FUNCTION__ );
104 break;
105 case CMD_CLOSE_DATA_CHAN:
106 IRDA_DEBUG(2, "Got CLOSE_DATA_CHAN command!\n");
107 IRDA_DEBUG(2, "%s(), NOT IMPLEMENTED\n", __FUNCTION__ );
108 break;
109 default:
110 IRDA_DEBUG(2, "%s(), Unknown command!\n", __FUNCTION__ );
111 break;
112 }
113 return 0;
114}
115
116/*
117 * Function irlan_provider_connect_indication (handle, skb, priv)
118 *
119 * Got connection from peer IrLAN client
120 *
121 */
122static void irlan_provider_connect_indication(void *instance, void *sap,
123 struct qos_info *qos,
124 __u32 max_sdu_size,
125 __u8 max_header_size,
126 struct sk_buff *skb)
127{
128 struct irlan_cb *self;
129 struct tsap_cb *tsap;
130 __u32 saddr, daddr;
131
132 IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
133
134 self = (struct irlan_cb *) instance;
135 tsap = (struct tsap_cb *) sap;
136
137 IRDA_ASSERT(self != NULL, return;);
138 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
139
140 IRDA_ASSERT(tsap == self->provider.tsap_ctrl,return;);
141 IRDA_ASSERT(self->provider.state == IRLAN_IDLE, return;);
142
143 daddr = irttp_get_daddr(tsap);
144 saddr = irttp_get_saddr(tsap);
145 self->provider.max_sdu_size = max_sdu_size;
146 self->provider.max_header_size = max_header_size;
147
148 irlan_do_provider_event(self, IRLAN_CONNECT_INDICATION, NULL);
149
150 /*
151 * If we are in peer mode, the client may not have got the discovery
152 * indication it needs to make progress. If the client is still in
153 * IDLE state, we must kick it.
154 */
155 if ((self->provider.access_type == ACCESS_PEER) &&
156 (self->client.state == IRLAN_IDLE))
157 {
158 irlan_client_wakeup(self, self->saddr, self->daddr);
159 }
160}
161
162/*
163 * Function irlan_provider_connect_response (handle)
164 *
165 * Accept incoming connection
166 *
167 */
168void irlan_provider_connect_response(struct irlan_cb *self,
169 struct tsap_cb *tsap)
170{
171 IRDA_ASSERT(self != NULL, return;);
172 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
173
174 /* Just accept */
175 irttp_connect_response(tsap, IRLAN_MTU, NULL);
176}
177
178static void irlan_provider_disconnect_indication(void *instance, void *sap,
179 LM_REASON reason,
180 struct sk_buff *userdata)
181{
182 struct irlan_cb *self;
183 struct tsap_cb *tsap;
184
185 IRDA_DEBUG(4, "%s(), reason=%d\n", __FUNCTION__ , reason);
186
187 self = (struct irlan_cb *) instance;
188 tsap = (struct tsap_cb *) sap;
189
190 IRDA_ASSERT(self != NULL, return;);
191 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
192 IRDA_ASSERT(tsap != NULL, return;);
193 IRDA_ASSERT(tsap->magic == TTP_TSAP_MAGIC, return;);
194
195 IRDA_ASSERT(tsap == self->provider.tsap_ctrl, return;);
196
197 irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);
198}
199
200/*
201 * Function irlan_parse_open_data_cmd (self, skb)
202 *
203 *
204 *
205 */
206int irlan_parse_open_data_cmd(struct irlan_cb *self, struct sk_buff *skb)
207{
208 int ret;
209
210 ret = irlan_provider_parse_command(self, CMD_OPEN_DATA_CHANNEL, skb);
211
212 /* Open data channel */
213 irlan_open_data_tsap(self);
214
215 return ret;
216}
217
218/*
219 * Function parse_command (skb)
220 *
221 * Extract all parameters from received buffer, then feed them to
222 * check_params for parsing
223 *
224 */
225int irlan_provider_parse_command(struct irlan_cb *self, int cmd,
226 struct sk_buff *skb)
227{
228 __u8 *frame;
229 __u8 *ptr;
230 int count;
231 __u16 val_len;
232 int i;
233 char *name;
234 char *value;
235 int ret = RSP_SUCCESS;
236
237 IRDA_ASSERT(skb != NULL, return -RSP_PROTOCOL_ERROR;);
238
239 IRDA_DEBUG(4, "%s(), skb->len=%d\n", __FUNCTION__ , (int)skb->len);
240
241 IRDA_ASSERT(self != NULL, return -RSP_PROTOCOL_ERROR;);
242 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -RSP_PROTOCOL_ERROR;);
243
244 if (!skb)
245 return -RSP_PROTOCOL_ERROR;
246
247 frame = skb->data;
248
249 name = kmalloc(255, GFP_ATOMIC);
250 if (!name)
251 return -RSP_INSUFFICIENT_RESOURCES;
252 value = kmalloc(1016, GFP_ATOMIC);
253 if (!value) {
254 kfree(name);
255 return -RSP_INSUFFICIENT_RESOURCES;
256 }
257
258 /* How many parameters? */
259 count = frame[1];
260
261 IRDA_DEBUG(4, "Got %d parameters\n", count);
262
263 ptr = frame+2;
264
265 /* For all parameters */
266 for (i=0; i<count;i++) {
267 ret = irlan_extract_param(ptr, name, value, &val_len);
268 if (ret < 0) {
269 IRDA_DEBUG(2, "%s(), IrLAN, Error!\n", __FUNCTION__ );
270 break;
271 }
272 ptr+=ret;
273 ret = RSP_SUCCESS;
274 irlan_check_command_param(self, name, value);
275 }
276 /* Cleanup */
277 kfree(name);
278 kfree(value);
279
280 return ret;
281}
282
283/*
284 * Function irlan_provider_send_reply (self, info)
285 *
286 * Send reply to query to peer IrLAN layer
287 *
288 */
289void irlan_provider_send_reply(struct irlan_cb *self, int command,
290 int ret_code)
291{
292 struct sk_buff *skb;
293
294 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
295
296 IRDA_ASSERT(self != NULL, return;);
297 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
298
299 skb = dev_alloc_skb(128);
300 if (!skb)
301 return;
302
303 /* Reserve space for TTP, LMP, and LAP header */
304 skb_reserve(skb, self->provider.max_header_size);
305 skb_put(skb, 2);
306
307 switch (command) {
308 case CMD_GET_PROVIDER_INFO:
309 skb->data[0] = 0x00; /* Success */
310 skb->data[1] = 0x02; /* 2 parameters */
311 switch (self->media) {
312 case MEDIA_802_3:
313 irlan_insert_string_param(skb, "MEDIA", "802.3");
314 break;
315 case MEDIA_802_5:
316 irlan_insert_string_param(skb, "MEDIA", "802.5");
317 break;
318 default:
319 IRDA_DEBUG(2, "%s(), unknown media type!\n", __FUNCTION__ );
320 break;
321 }
322 irlan_insert_short_param(skb, "IRLAN_VER", 0x0101);
323 break;
324
325 case CMD_GET_MEDIA_CHAR:
326 skb->data[0] = 0x00; /* Success */
327 skb->data[1] = 0x05; /* 5 parameters */
328 irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");
329 irlan_insert_string_param(skb, "FILTER_TYPE", "BROADCAST");
330 irlan_insert_string_param(skb, "FILTER_TYPE", "MULTICAST");
331
332 switch (self->provider.access_type) {
333 case ACCESS_DIRECT:
334 irlan_insert_string_param(skb, "ACCESS_TYPE", "DIRECT");
335 break;
336 case ACCESS_PEER:
337 irlan_insert_string_param(skb, "ACCESS_TYPE", "PEER");
338 break;
339 case ACCESS_HOSTED:
340 irlan_insert_string_param(skb, "ACCESS_TYPE", "HOSTED");
341 break;
342 default:
343 IRDA_DEBUG(2, "%s(), Unknown access type\n", __FUNCTION__ );
344 break;
345 }
346 irlan_insert_short_param(skb, "MAX_FRAME", 0x05ee);
347 break;
348 case CMD_OPEN_DATA_CHANNEL:
349 skb->data[0] = 0x00; /* Success */
350 if (self->provider.send_arb_val) {
351 skb->data[1] = 0x03; /* 3 parameters */
352 irlan_insert_short_param(skb, "CON_ARB",
353 self->provider.send_arb_val);
354 } else
355 skb->data[1] = 0x02; /* 2 parameters */
356 irlan_insert_byte_param(skb, "DATA_CHAN", self->stsap_sel_data);
357 irlan_insert_array_param(skb, "RECONNECT_KEY", "LINUX RULES!",
358 12);
359 break;
360 case CMD_FILTER_OPERATION:
361 irlan_filter_request(self, skb);
362 break;
363 default:
364 IRDA_DEBUG(2, "%s(), Unknown command!\n", __FUNCTION__ );
365 break;
366 }
367
368 irttp_data_request(self->provider.tsap_ctrl, skb);
369}
370
371/*
372 * Function irlan_provider_register(void)
373 *
374 * Register provider support so we can accept incoming connections.
375 *
376 */
377int irlan_provider_open_ctrl_tsap(struct irlan_cb *self)
378{
379 struct tsap_cb *tsap;
380 notify_t notify;
381
382 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
383
384 IRDA_ASSERT(self != NULL, return -1;);
385 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
386
387 /* Check if already open */
388 if (self->provider.tsap_ctrl)
389 return -1;
390
391 /*
392 * First register well known control TSAP
393 */
394 irda_notify_init(&notify);
395 notify.data_indication = irlan_provider_data_indication;
396 notify.connect_indication = irlan_provider_connect_indication;
397 notify.disconnect_indication = irlan_provider_disconnect_indication;
398 notify.instance = self;
399 strlcpy(notify.name, "IrLAN ctrl (p)", sizeof(notify.name));
400
401 tsap = irttp_open_tsap(LSAP_ANY, 1, &notify);
402 if (!tsap) {
403 IRDA_DEBUG(2, "%s(), Got no tsap!\n", __FUNCTION__ );
404 return -1;
405 }
406 self->provider.tsap_ctrl = tsap;
407
408 /* Register with LM-IAS */
409 irlan_ias_register(self, tsap->stsap_sel);
410
411 return 0;
412}
413
diff --git a/net/irda/irlan/irlan_provider_event.c b/net/irda/irlan/irlan_provider_event.c
new file mode 100644
index 00000000000..5a086f9827e
--- /dev/null
+++ b/net/irda/irlan/irlan_provider_event.c
@@ -0,0 +1,241 @@
1/*********************************************************************
2 *
3 * Filename: irlan_provider_event.c
4 * Version: 0.9
5 * Description: IrLAN provider state machine)
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Aug 31 20:14:37 1997
9 * Modified at: Sat Oct 30 12:52:41 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * Neither Dag Brattli nor University of Tromsø admit liability nor
20 * provide warranty for any of this software. This material is
21 * provided "AS-IS" and at no charge.
22 *
23 ********************************************************************/
24
25#include <net/irda/irda.h>
26#include <net/irda/iriap.h>
27#include <net/irda/irlmp.h>
28#include <net/irda/irttp.h>
29
30#include <net/irda/irlan_provider.h>
31#include <net/irda/irlan_event.h>
32
33static int irlan_provider_state_idle(struct irlan_cb *self, IRLAN_EVENT event,
34 struct sk_buff *skb);
35static int irlan_provider_state_info(struct irlan_cb *self, IRLAN_EVENT event,
36 struct sk_buff *skb);
37static int irlan_provider_state_open(struct irlan_cb *self, IRLAN_EVENT event,
38 struct sk_buff *skb);
39static int irlan_provider_state_data(struct irlan_cb *self, IRLAN_EVENT event,
40 struct sk_buff *skb);
41
42static int (*state[])(struct irlan_cb *self, IRLAN_EVENT event,
43 struct sk_buff *skb) =
44{
45 irlan_provider_state_idle,
46 NULL, /* Query */
47 NULL, /* Info */
48 irlan_provider_state_info,
49 NULL, /* Media */
50 irlan_provider_state_open,
51 NULL, /* Wait */
52 NULL, /* Arb */
53 irlan_provider_state_data,
54 NULL, /* Close */
55 NULL, /* Sync */
56};
57
58void irlan_do_provider_event(struct irlan_cb *self, IRLAN_EVENT event,
59 struct sk_buff *skb)
60{
61 IRDA_ASSERT(*state[ self->provider.state] != NULL, return;);
62
63 (*state[self->provider.state]) (self, event, skb);
64}
65
66/*
67 * Function irlan_provider_state_idle (event, skb, info)
68 *
69 * IDLE, We are waiting for an indication that there is a provider
70 * available.
71 */
72static int irlan_provider_state_idle(struct irlan_cb *self, IRLAN_EVENT event,
73 struct sk_buff *skb)
74{
75 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
76
77 IRDA_ASSERT(self != NULL, return -1;);
78
79 switch(event) {
80 case IRLAN_CONNECT_INDICATION:
81 irlan_provider_connect_response( self, self->provider.tsap_ctrl);
82 irlan_next_provider_state( self, IRLAN_INFO);
83 break;
84 default:
85 IRDA_DEBUG(4, "%s(), Unknown event %d\n", __FUNCTION__ , event);
86 break;
87 }
88 if (skb)
89 dev_kfree_skb(skb);
90
91 return 0;
92}
93
94/*
95 * Function irlan_provider_state_info (self, event, skb, info)
96 *
97 * INFO, We have issued a GetInfo command and is awaiting a reply.
98 */
99static int irlan_provider_state_info(struct irlan_cb *self, IRLAN_EVENT event,
100 struct sk_buff *skb)
101{
102 int ret;
103
104 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
105
106 IRDA_ASSERT(self != NULL, return -1;);
107
108 switch(event) {
109 case IRLAN_GET_INFO_CMD:
110 /* Be sure to use 802.3 in case of peer mode */
111 if (self->provider.access_type == ACCESS_PEER) {
112 self->media = MEDIA_802_3;
113
114 /* Check if client has started yet */
115 if (self->client.state == IRLAN_IDLE) {
116 /* This should get the client going */
117 irlmp_discovery_request(8);
118 }
119 }
120
121 irlan_provider_send_reply(self, CMD_GET_PROVIDER_INFO,
122 RSP_SUCCESS);
123 /* Keep state */
124 break;
125 case IRLAN_GET_MEDIA_CMD:
126 irlan_provider_send_reply(self, CMD_GET_MEDIA_CHAR,
127 RSP_SUCCESS);
128 /* Keep state */
129 break;
130 case IRLAN_OPEN_DATA_CMD:
131 ret = irlan_parse_open_data_cmd(self, skb);
132 if (self->provider.access_type == ACCESS_PEER) {
133 /* FIXME: make use of random functions! */
134 self->provider.send_arb_val = (jiffies & 0xffff);
135 }
136 irlan_provider_send_reply(self, CMD_OPEN_DATA_CHANNEL, ret);
137
138 if (ret == RSP_SUCCESS) {
139 irlan_next_provider_state(self, IRLAN_OPEN);
140
141 /* Signal client that we are now open */
142 irlan_do_client_event(self, IRLAN_PROVIDER_SIGNAL, NULL);
143 }
144 break;
145 case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
146 case IRLAN_LAP_DISCONNECT:
147 irlan_next_provider_state(self, IRLAN_IDLE);
148 break;
149 default:
150 IRDA_DEBUG( 0, "%s(), Unknown event %d\n", __FUNCTION__ , event);
151 break;
152 }
153 if (skb)
154 dev_kfree_skb(skb);
155
156 return 0;
157}
158
159/*
160 * Function irlan_provider_state_open (self, event, skb, info)
161 *
162 * OPEN, The client has issued a OpenData command and is awaiting a
163 * reply
164 *
165 */
166static int irlan_provider_state_open(struct irlan_cb *self, IRLAN_EVENT event,
167 struct sk_buff *skb)
168{
169 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
170
171 IRDA_ASSERT(self != NULL, return -1;);
172
173 switch(event) {
174 case IRLAN_FILTER_CONFIG_CMD:
175 irlan_provider_parse_command(self, CMD_FILTER_OPERATION, skb);
176 irlan_provider_send_reply(self, CMD_FILTER_OPERATION,
177 RSP_SUCCESS);
178 /* Keep state */
179 break;
180 case IRLAN_DATA_CONNECT_INDICATION:
181 irlan_next_provider_state(self, IRLAN_DATA);
182 irlan_provider_connect_response(self, self->tsap_data);
183 break;
184 case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
185 case IRLAN_LAP_DISCONNECT:
186 irlan_next_provider_state(self, IRLAN_IDLE);
187 break;
188 default:
189 IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
190 break;
191 }
192 if (skb)
193 dev_kfree_skb(skb);
194
195 return 0;
196}
197
198/*
199 * Function irlan_provider_state_data (self, event, skb, info)
200 *
201 * DATA, The data channel is connected, allowing data transfers between
202 * the local and remote machines.
203 *
204 */
205static int irlan_provider_state_data(struct irlan_cb *self, IRLAN_EVENT event,
206 struct sk_buff *skb)
207{
208 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
209
210 IRDA_ASSERT(self != NULL, return -1;);
211 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
212
213 switch(event) {
214 case IRLAN_FILTER_CONFIG_CMD:
215 irlan_provider_parse_command(self, CMD_FILTER_OPERATION, skb);
216 irlan_provider_send_reply(self, CMD_FILTER_OPERATION,
217 RSP_SUCCESS);
218 break;
219 case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
220 case IRLAN_LAP_DISCONNECT:
221 irlan_next_provider_state(self, IRLAN_IDLE);
222 break;
223 default:
224 IRDA_DEBUG( 0, "%s(), Unknown event %d\n", __FUNCTION__ , event);
225 break;
226 }
227 if (skb)
228 dev_kfree_skb(skb);
229
230 return 0;
231}
232
233
234
235
236
237
238
239
240
241
diff --git a/net/irda/irlap.c b/net/irda/irlap.c
new file mode 100644
index 00000000000..046ad0750e4
--- /dev/null
+++ b/net/irda/irlap.c
@@ -0,0 +1,1258 @@
1/*********************************************************************
2 *
3 * Filename: irlap.c
4 * Version: 1.0
5 * Description: IrLAP implementation for Linux
6 * Status: Stable
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Mon Aug 4 20:40:53 1997
9 * Modified at: Tue Dec 14 09:26:44 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
13 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 * MA 02111-1307 USA
29 *
30 ********************************************************************/
31
32#include <linux/config.h>
33#include <linux/slab.h>
34#include <linux/string.h>
35#include <linux/skbuff.h>
36#include <linux/delay.h>
37#include <linux/proc_fs.h>
38#include <linux/init.h>
39#include <linux/random.h>
40#include <linux/module.h>
41#include <linux/seq_file.h>
42
43#include <net/irda/irda.h>
44#include <net/irda/irda_device.h>
45#include <net/irda/irqueue.h>
46#include <net/irda/irlmp.h>
47#include <net/irda/irlmp_frame.h>
48#include <net/irda/irlap_frame.h>
49#include <net/irda/irlap.h>
50#include <net/irda/timer.h>
51#include <net/irda/qos.h>
52
53static hashbin_t *irlap = NULL;
54int sysctl_slot_timeout = SLOT_TIMEOUT * 1000 / HZ;
55
56/* This is the delay of missed pf period before generating an event
57 * to the application. The spec mandate 3 seconds, but in some cases
58 * it's way too long. - Jean II */
59int sysctl_warn_noreply_time = 3;
60
61extern void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb);
62static void __irlap_close(struct irlap_cb *self);
63static void irlap_init_qos_capabilities(struct irlap_cb *self,
64 struct qos_info *qos_user);
65
66#ifdef CONFIG_IRDA_DEBUG
67static char *lap_reasons[] = {
68 "ERROR, NOT USED",
69 "LAP_DISC_INDICATION",
70 "LAP_NO_RESPONSE",
71 "LAP_RESET_INDICATION",
72 "LAP_FOUND_NONE",
73 "LAP_MEDIA_BUSY",
74 "LAP_PRIMARY_CONFLICT",
75 "ERROR, NOT USED",
76};
77#endif /* CONFIG_IRDA_DEBUG */
78
79int __init irlap_init(void)
80{
81 /* Check if the compiler did its job properly.
82 * May happen on some ARM configuration, check with Russell King. */
83 IRDA_ASSERT(sizeof(struct xid_frame) == 14, ;);
84 IRDA_ASSERT(sizeof(struct test_frame) == 10, ;);
85 IRDA_ASSERT(sizeof(struct ua_frame) == 10, ;);
86 IRDA_ASSERT(sizeof(struct snrm_frame) == 11, ;);
87
88 /* Allocate master array */
89 irlap = hashbin_new(HB_LOCK);
90 if (irlap == NULL) {
91 IRDA_ERROR("%s: can't allocate irlap hashbin!\n",
92 __FUNCTION__);
93 return -ENOMEM;
94 }
95
96 return 0;
97}
98
99void __exit irlap_cleanup(void)
100{
101 IRDA_ASSERT(irlap != NULL, return;);
102
103 hashbin_delete(irlap, (FREE_FUNC) __irlap_close);
104}
105
106/*
107 * Function irlap_open (driver)
108 *
109 * Initialize IrLAP layer
110 *
111 */
112struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos,
113 const char *hw_name)
114{
115 struct irlap_cb *self;
116
117 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
118
119 /* Initialize the irlap structure. */
120 self = kmalloc(sizeof(struct irlap_cb), GFP_KERNEL);
121 if (self == NULL)
122 return NULL;
123
124 memset(self, 0, sizeof(struct irlap_cb));
125 self->magic = LAP_MAGIC;
126
127 /* Make a binding between the layers */
128 self->netdev = dev;
129 self->qos_dev = qos;
130 /* Copy hardware name */
131 if(hw_name != NULL) {
132 strlcpy(self->hw_name, hw_name, sizeof(self->hw_name));
133 } else {
134 self->hw_name[0] = '\0';
135 }
136
137 /* FIXME: should we get our own field? */
138 dev->atalk_ptr = self;
139
140 self->state = LAP_OFFLINE;
141
142 /* Initialize transmit queue */
143 skb_queue_head_init(&self->txq);
144 skb_queue_head_init(&self->txq_ultra);
145 skb_queue_head_init(&self->wx_list);
146
147 /* My unique IrLAP device address! */
148 /* We don't want the broadcast address, neither the NULL address
149 * (most often used to signify "invalid"), and we don't want an
150 * address already in use (otherwise connect won't be able
151 * to select the proper link). - Jean II */
152 do {
153 get_random_bytes(&self->saddr, sizeof(self->saddr));
154 } while ((self->saddr == 0x0) || (self->saddr == BROADCAST) ||
155 (hashbin_lock_find(irlap, self->saddr, NULL)) );
156 /* Copy to the driver */
157 memcpy(dev->dev_addr, &self->saddr, 4);
158
159 init_timer(&self->slot_timer);
160 init_timer(&self->query_timer);
161 init_timer(&self->discovery_timer);
162 init_timer(&self->final_timer);
163 init_timer(&self->poll_timer);
164 init_timer(&self->wd_timer);
165 init_timer(&self->backoff_timer);
166 init_timer(&self->media_busy_timer);
167
168 irlap_apply_default_connection_parameters(self);
169
170 self->N3 = 3; /* # connections attemts to try before giving up */
171
172 self->state = LAP_NDM;
173
174 hashbin_insert(irlap, (irda_queue_t *) self, self->saddr, NULL);
175
176 irlmp_register_link(self, self->saddr, &self->notify);
177
178 return self;
179}
180EXPORT_SYMBOL(irlap_open);
181
182/*
183 * Function __irlap_close (self)
184 *
185 * Remove IrLAP and all allocated memory. Stop any pending timers.
186 *
187 */
188static void __irlap_close(struct irlap_cb *self)
189{
190 IRDA_ASSERT(self != NULL, return;);
191 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
192
193 /* Stop timers */
194 del_timer(&self->slot_timer);
195 del_timer(&self->query_timer);
196 del_timer(&self->discovery_timer);
197 del_timer(&self->final_timer);
198 del_timer(&self->poll_timer);
199 del_timer(&self->wd_timer);
200 del_timer(&self->backoff_timer);
201 del_timer(&self->media_busy_timer);
202
203 irlap_flush_all_queues(self);
204
205 self->magic = 0;
206
207 kfree(self);
208}
209
210/*
211 * Function irlap_close (self)
212 *
213 * Remove IrLAP instance
214 *
215 */
216void irlap_close(struct irlap_cb *self)
217{
218 struct irlap_cb *lap;
219
220 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
221
222 IRDA_ASSERT(self != NULL, return;);
223 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
224
225 /* We used to send a LAP_DISC_INDICATION here, but this was
226 * racy. This has been move within irlmp_unregister_link()
227 * itself. Jean II */
228
229 /* Kill the LAP and all LSAPs on top of it */
230 irlmp_unregister_link(self->saddr);
231 self->notify.instance = NULL;
232
233 /* Be sure that we manage to remove ourself from the hash */
234 lap = hashbin_remove(irlap, self->saddr, NULL);
235 if (!lap) {
236 IRDA_DEBUG(1, "%s(), Didn't find myself!\n", __FUNCTION__);
237 return;
238 }
239 __irlap_close(lap);
240}
241EXPORT_SYMBOL(irlap_close);
242
243/*
244 * Function irlap_connect_indication (self, skb)
245 *
246 * Another device is attempting to make a connection
247 *
248 */
249void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb)
250{
251 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
252
253 IRDA_ASSERT(self != NULL, return;);
254 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
255
256 irlap_init_qos_capabilities(self, NULL); /* No user QoS! */
257
258 irlmp_link_connect_indication(self->notify.instance, self->saddr,
259 self->daddr, &self->qos_tx, skb);
260}
261
262/*
263 * Function irlap_connect_response (self, skb)
264 *
265 * Service user has accepted incoming connection
266 *
267 */
268void irlap_connect_response(struct irlap_cb *self, struct sk_buff *userdata)
269{
270 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
271
272 irlap_do_event(self, CONNECT_RESPONSE, userdata, NULL);
273}
274
275/*
276 * Function irlap_connect_request (self, daddr, qos_user, sniff)
277 *
278 * Request connection with another device, sniffing is not implemented
279 * yet.
280 *
281 */
282void irlap_connect_request(struct irlap_cb *self, __u32 daddr,
283 struct qos_info *qos_user, int sniff)
284{
285 IRDA_DEBUG(3, "%s(), daddr=0x%08x\n", __FUNCTION__, daddr);
286
287 IRDA_ASSERT(self != NULL, return;);
288 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
289
290 self->daddr = daddr;
291
292 /*
293 * If the service user specifies QoS values for this connection,
294 * then use them
295 */
296 irlap_init_qos_capabilities(self, qos_user);
297
298 if ((self->state == LAP_NDM) && !self->media_busy)
299 irlap_do_event(self, CONNECT_REQUEST, NULL, NULL);
300 else
301 self->connect_pending = TRUE;
302}
303
304/*
305 * Function irlap_connect_confirm (self, skb)
306 *
307 * Connection request has been accepted
308 *
309 */
310void irlap_connect_confirm(struct irlap_cb *self, struct sk_buff *skb)
311{
312 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
313
314 IRDA_ASSERT(self != NULL, return;);
315 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
316
317 irlmp_link_connect_confirm(self->notify.instance, &self->qos_tx, skb);
318}
319
320/*
321 * Function irlap_data_indication (self, skb)
322 *
323 * Received data frames from IR-port, so we just pass them up to
324 * IrLMP for further processing
325 *
326 */
327void irlap_data_indication(struct irlap_cb *self, struct sk_buff *skb,
328 int unreliable)
329{
330 /* Hide LAP header from IrLMP layer */
331 skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
332
333 irlmp_link_data_indication(self->notify.instance, skb, unreliable);
334}
335
336
337/*
338 * Function irlap_data_request (self, skb)
339 *
340 * Queue data for transmission, must wait until XMIT state
341 *
342 */
343void irlap_data_request(struct irlap_cb *self, struct sk_buff *skb,
344 int unreliable)
345{
346 IRDA_ASSERT(self != NULL, return;);
347 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
348
349 IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
350
351 IRDA_ASSERT(skb_headroom(skb) >= (LAP_ADDR_HEADER+LAP_CTRL_HEADER),
352 return;);
353 skb_push(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
354
355 /*
356 * Must set frame format now so that the rest of the code knows
357 * if its dealing with an I or an UI frame
358 */
359 if (unreliable)
360 skb->data[1] = UI_FRAME;
361 else
362 skb->data[1] = I_FRAME;
363
364 /* Don't forget to refcount it - see irlmp_connect_request(). */
365 skb_get(skb);
366
367 /* Add at the end of the queue (keep ordering) - Jean II */
368 skb_queue_tail(&self->txq, skb);
369
370 /*
371 * Send event if this frame only if we are in the right state
372 * FIXME: udata should be sent first! (skb_queue_head?)
373 */
374 if ((self->state == LAP_XMIT_P) || (self->state == LAP_XMIT_S)) {
375 /* If we are not already processing the Tx queue, trigger
376 * transmission immediately - Jean II */
377 if((skb_queue_len(&self->txq) <= 1) && (!self->local_busy))
378 irlap_do_event(self, DATA_REQUEST, skb, NULL);
379 /* Otherwise, the packets will be sent normally at the
380 * next pf-poll - Jean II */
381 }
382}
383
384/*
385 * Function irlap_unitdata_request (self, skb)
386 *
387 * Send Ultra data. This is data that must be sent outside any connection
388 *
389 */
390#ifdef CONFIG_IRDA_ULTRA
391void irlap_unitdata_request(struct irlap_cb *self, struct sk_buff *skb)
392{
393 IRDA_ASSERT(self != NULL, return;);
394 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
395
396 IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
397
398 IRDA_ASSERT(skb_headroom(skb) >= (LAP_ADDR_HEADER+LAP_CTRL_HEADER),
399 return;);
400 skb_push(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
401
402 skb->data[0] = CBROADCAST;
403 skb->data[1] = UI_FRAME;
404
405 /* Don't need to refcount, see irlmp_connless_data_request() */
406
407 skb_queue_tail(&self->txq_ultra, skb);
408
409 irlap_do_event(self, SEND_UI_FRAME, NULL, NULL);
410}
411#endif /*CONFIG_IRDA_ULTRA */
412
413/*
414 * Function irlap_udata_indication (self, skb)
415 *
416 * Receive Ultra data. This is data that is received outside any connection
417 *
418 */
419#ifdef CONFIG_IRDA_ULTRA
420void irlap_unitdata_indication(struct irlap_cb *self, struct sk_buff *skb)
421{
422 IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
423
424 IRDA_ASSERT(self != NULL, return;);
425 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
426 IRDA_ASSERT(skb != NULL, return;);
427
428 /* Hide LAP header from IrLMP layer */
429 skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
430
431 irlmp_link_unitdata_indication(self->notify.instance, skb);
432}
433#endif /* CONFIG_IRDA_ULTRA */
434
435/*
436 * Function irlap_disconnect_request (void)
437 *
438 * Request to disconnect connection by service user
439 */
440void irlap_disconnect_request(struct irlap_cb *self)
441{
442 IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
443
444 IRDA_ASSERT(self != NULL, return;);
445 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
446
447 /* Don't disconnect until all data frames are successfully sent */
448 if (skb_queue_len(&self->txq) > 0) {
449 self->disconnect_pending = TRUE;
450
451 return;
452 }
453
454 /* Check if we are in the right state for disconnecting */
455 switch (self->state) {
456 case LAP_XMIT_P: /* FALLTROUGH */
457 case LAP_XMIT_S: /* FALLTROUGH */
458 case LAP_CONN: /* FALLTROUGH */
459 case LAP_RESET_WAIT: /* FALLTROUGH */
460 case LAP_RESET_CHECK:
461 irlap_do_event(self, DISCONNECT_REQUEST, NULL, NULL);
462 break;
463 default:
464 IRDA_DEBUG(2, "%s(), disconnect pending!\n", __FUNCTION__);
465 self->disconnect_pending = TRUE;
466 break;
467 }
468}
469
470/*
471 * Function irlap_disconnect_indication (void)
472 *
473 * Disconnect request from other device
474 *
475 */
476void irlap_disconnect_indication(struct irlap_cb *self, LAP_REASON reason)
477{
478 IRDA_DEBUG(1, "%s(), reason=%s\n", __FUNCTION__, lap_reasons[reason]);
479
480 IRDA_ASSERT(self != NULL, return;);
481 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
482
483 /* Flush queues */
484 irlap_flush_all_queues(self);
485
486 switch (reason) {
487 case LAP_RESET_INDICATION:
488 IRDA_DEBUG(1, "%s(), Sending reset request!\n", __FUNCTION__);
489 irlap_do_event(self, RESET_REQUEST, NULL, NULL);
490 break;
491 case LAP_NO_RESPONSE: /* FALLTROUGH */
492 case LAP_DISC_INDICATION: /* FALLTROUGH */
493 case LAP_FOUND_NONE: /* FALLTROUGH */
494 case LAP_MEDIA_BUSY:
495 irlmp_link_disconnect_indication(self->notify.instance, self,
496 reason, NULL);
497 break;
498 default:
499 IRDA_ERROR("%s: Unknown reason %d\n", __FUNCTION__, reason);
500 }
501}
502
503/*
504 * Function irlap_discovery_request (gen_addr_bit)
505 *
506 * Start one single discovery operation.
507 *
508 */
509void irlap_discovery_request(struct irlap_cb *self, discovery_t *discovery)
510{
511 struct irlap_info info;
512
513 IRDA_ASSERT(self != NULL, return;);
514 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
515 IRDA_ASSERT(discovery != NULL, return;);
516
517 IRDA_DEBUG(4, "%s(), nslots = %d\n", __FUNCTION__, discovery->nslots);
518
519 IRDA_ASSERT((discovery->nslots == 1) || (discovery->nslots == 6) ||
520 (discovery->nslots == 8) || (discovery->nslots == 16),
521 return;);
522
523 /* Discovery is only possible in NDM mode */
524 if (self->state != LAP_NDM) {
525 IRDA_DEBUG(4, "%s(), discovery only possible in NDM mode\n",
526 __FUNCTION__);
527 irlap_discovery_confirm(self, NULL);
528 /* Note : in theory, if we are not in NDM, we could postpone
529 * the discovery like we do for connection request.
530 * In practice, it's not worth it. If the media was busy,
531 * it's likely next time around it won't be busy. If we are
532 * in REPLY state, we will get passive discovery info & event.
533 * Jean II */
534 return;
535 }
536
537 /* Check if last discovery request finished in time, or if
538 * it was aborted due to the media busy flag. */
539 if (self->discovery_log != NULL) {
540 hashbin_delete(self->discovery_log, (FREE_FUNC) kfree);
541 self->discovery_log = NULL;
542 }
543
544 /* All operations will occur at predictable time, no need to lock */
545 self->discovery_log = hashbin_new(HB_NOLOCK);
546
547 if (self->discovery_log == NULL) {
548 IRDA_WARNING("%s(), Unable to allocate discovery log!\n",
549 __FUNCTION__);
550 return;
551 }
552
553 info.S = discovery->nslots; /* Number of slots */
554 info.s = 0; /* Current slot */
555
556 self->discovery_cmd = discovery;
557 info.discovery = discovery;
558
559 /* sysctl_slot_timeout bounds are checked in irsysctl.c - Jean II */
560 self->slot_timeout = sysctl_slot_timeout * HZ / 1000;
561
562 irlap_do_event(self, DISCOVERY_REQUEST, NULL, &info);
563}
564
565/*
566 * Function irlap_discovery_confirm (log)
567 *
568 * A device has been discovered in front of this station, we
569 * report directly to LMP.
570 */
571void irlap_discovery_confirm(struct irlap_cb *self, hashbin_t *discovery_log)
572{
573 IRDA_ASSERT(self != NULL, return;);
574 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
575
576 IRDA_ASSERT(self->notify.instance != NULL, return;);
577
578 /*
579 * Check for successful discovery, since we are then allowed to clear
580 * the media busy condition (IrLAP 6.13.4 - p.94). This should allow
581 * us to make connection attempts much faster and easier (i.e. no
582 * collisions).
583 * Setting media busy to false will also generate an event allowing
584 * to process pending events in NDM state machine.
585 * Note : the spec doesn't define what's a successful discovery is.
586 * If we want Ultra to work, it's successful even if there is
587 * nobody discovered - Jean II
588 */
589 if (discovery_log)
590 irda_device_set_media_busy(self->netdev, FALSE);
591
592 /* Inform IrLMP */
593 irlmp_link_discovery_confirm(self->notify.instance, discovery_log);
594}
595
596/*
597 * Function irlap_discovery_indication (log)
598 *
599 * Somebody is trying to discover us!
600 *
601 */
602void irlap_discovery_indication(struct irlap_cb *self, discovery_t *discovery)
603{
604 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
605
606 IRDA_ASSERT(self != NULL, return;);
607 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
608 IRDA_ASSERT(discovery != NULL, return;);
609
610 IRDA_ASSERT(self->notify.instance != NULL, return;);
611
612 /* A device is very likely to connect immediately after it performs
613 * a successful discovery. This means that in our case, we are much
614 * more likely to receive a connection request over the medium.
615 * So, we backoff to avoid collisions.
616 * IrLAP spec 6.13.4 suggest 100ms...
617 * Note : this little trick actually make a *BIG* difference. If I set
618 * my Linux box with discovery enabled and one Ultra frame sent every
619 * second, my Palm has no trouble connecting to it every time !
620 * Jean II */
621 irda_device_set_media_busy(self->netdev, SMALL);
622
623 irlmp_link_discovery_indication(self->notify.instance, discovery);
624}
625
626/*
627 * Function irlap_status_indication (quality_of_link)
628 */
629void irlap_status_indication(struct irlap_cb *self, int quality_of_link)
630{
631 switch (quality_of_link) {
632 case STATUS_NO_ACTIVITY:
633 IRDA_MESSAGE("IrLAP, no activity on link!\n");
634 break;
635 case STATUS_NOISY:
636 IRDA_MESSAGE("IrLAP, noisy link!\n");
637 break;
638 default:
639 break;
640 }
641 irlmp_status_indication(self->notify.instance,
642 quality_of_link, LOCK_NO_CHANGE);
643}
644
645/*
646 * Function irlap_reset_indication (void)
647 */
648void irlap_reset_indication(struct irlap_cb *self)
649{
650 IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
651
652 IRDA_ASSERT(self != NULL, return;);
653 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
654
655 if (self->state == LAP_RESET_WAIT)
656 irlap_do_event(self, RESET_REQUEST, NULL, NULL);
657 else
658 irlap_do_event(self, RESET_RESPONSE, NULL, NULL);
659}
660
661/*
662 * Function irlap_reset_confirm (void)
663 */
664void irlap_reset_confirm(void)
665{
666 IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
667}
668
669/*
670 * Function irlap_generate_rand_time_slot (S, s)
671 *
672 * Generate a random time slot between s and S-1 where
673 * S = Number of slots (0 -> S-1)
674 * s = Current slot
675 */
676int irlap_generate_rand_time_slot(int S, int s)
677{
678 static int rand;
679 int slot;
680
681 IRDA_ASSERT((S - s) > 0, return 0;);
682
683 rand += jiffies;
684 rand ^= (rand << 12);
685 rand ^= (rand >> 20);
686
687 slot = s + rand % (S-s);
688
689 IRDA_ASSERT((slot >= s) || (slot < S), return 0;);
690
691 return slot;
692}
693
694/*
695 * Function irlap_update_nr_received (nr)
696 *
697 * Remove all acknowledged frames in current window queue. This code is
698 * not intuitive and you should not try to change it. If you think it
699 * contains bugs, please mail a patch to the author instead.
700 */
701void irlap_update_nr_received(struct irlap_cb *self, int nr)
702{
703 struct sk_buff *skb = NULL;
704 int count = 0;
705
706 /*
707 * Remove all the ack-ed frames from the window queue.
708 */
709
710 /*
711 * Optimize for the common case. It is most likely that the receiver
712 * will acknowledge all the frames we have sent! So in that case we
713 * delete all frames stored in window.
714 */
715 if (nr == self->vs) {
716 while ((skb = skb_dequeue(&self->wx_list)) != NULL) {
717 dev_kfree_skb(skb);
718 }
719 /* The last acked frame is the next to send minus one */
720 self->va = nr - 1;
721 } else {
722 /* Remove all acknowledged frames in current window */
723 while ((skb_peek(&self->wx_list) != NULL) &&
724 (((self->va+1) % 8) != nr))
725 {
726 skb = skb_dequeue(&self->wx_list);
727 dev_kfree_skb(skb);
728
729 self->va = (self->va + 1) % 8;
730 count++;
731 }
732 }
733
734 /* Advance window */
735 self->window = self->window_size - skb_queue_len(&self->wx_list);
736}
737
738/*
739 * Function irlap_validate_ns_received (ns)
740 *
741 * Validate the next to send (ns) field from received frame.
742 */
743int irlap_validate_ns_received(struct irlap_cb *self, int ns)
744{
745 /* ns as expected? */
746 if (ns == self->vr)
747 return NS_EXPECTED;
748 /*
749 * Stations are allowed to treat invalid NS as unexpected NS
750 * IrLAP, Recv ... with-invalid-Ns. p. 84
751 */
752 return NS_UNEXPECTED;
753
754 /* return NR_INVALID; */
755}
756/*
757 * Function irlap_validate_nr_received (nr)
758 *
759 * Validate the next to receive (nr) field from received frame.
760 *
761 */
762int irlap_validate_nr_received(struct irlap_cb *self, int nr)
763{
764 /* nr as expected? */
765 if (nr == self->vs) {
766 IRDA_DEBUG(4, "%s(), expected!\n", __FUNCTION__);
767 return NR_EXPECTED;
768 }
769
770 /*
771 * unexpected nr? (but within current window), first we check if the
772 * ns numbers of the frames in the current window wrap.
773 */
774 if (self->va < self->vs) {
775 if ((nr >= self->va) && (nr <= self->vs))
776 return NR_UNEXPECTED;
777 } else {
778 if ((nr >= self->va) || (nr <= self->vs))
779 return NR_UNEXPECTED;
780 }
781
782 /* Invalid nr! */
783 return NR_INVALID;
784}
785
786/*
787 * Function irlap_initiate_connection_state ()
788 *
789 * Initialize the connection state parameters
790 *
791 */
792void irlap_initiate_connection_state(struct irlap_cb *self)
793{
794 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
795
796 IRDA_ASSERT(self != NULL, return;);
797 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
798
799 /* Next to send and next to receive */
800 self->vs = self->vr = 0;
801
802 /* Last frame which got acked (0 - 1) % 8 */
803 self->va = 7;
804
805 self->window = 1;
806
807 self->remote_busy = FALSE;
808 self->retry_count = 0;
809}
810
811/*
812 * Function irlap_wait_min_turn_around (self, qos)
813 *
814 * Wait negotiated minimum turn around time, this function actually sets
815 * the number of BOS's that must be sent before the next transmitted
816 * frame in order to delay for the specified amount of time. This is
817 * done to avoid using timers, and the forbidden udelay!
818 */
819void irlap_wait_min_turn_around(struct irlap_cb *self, struct qos_info *qos)
820{
821 __u32 min_turn_time;
822 __u32 speed;
823
824 /* Get QoS values. */
825 speed = qos->baud_rate.value;
826 min_turn_time = qos->min_turn_time.value;
827
828 /* No need to calculate XBOFs for speeds over 115200 bps */
829 if (speed > 115200) {
830 self->mtt_required = min_turn_time;
831 return;
832 }
833
834 /*
835 * Send additional BOF's for the next frame for the requested
836 * min turn time, so now we must calculate how many chars (XBOF's) we
837 * must send for the requested time period (min turn time)
838 */
839 self->xbofs_delay = irlap_min_turn_time_in_bytes(speed, min_turn_time);
840}
841
842/*
843 * Function irlap_flush_all_queues (void)
844 *
845 * Flush all queues
846 *
847 */
848void irlap_flush_all_queues(struct irlap_cb *self)
849{
850 struct sk_buff* skb;
851
852 IRDA_ASSERT(self != NULL, return;);
853 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
854
855 /* Free transmission queue */
856 while ((skb = skb_dequeue(&self->txq)) != NULL)
857 dev_kfree_skb(skb);
858
859 while ((skb = skb_dequeue(&self->txq_ultra)) != NULL)
860 dev_kfree_skb(skb);
861
862 /* Free sliding window buffered packets */
863 while ((skb = skb_dequeue(&self->wx_list)) != NULL)
864 dev_kfree_skb(skb);
865}
866
867/*
868 * Function irlap_setspeed (self, speed)
869 *
870 * Change the speed of the IrDA port
871 *
872 */
873static void irlap_change_speed(struct irlap_cb *self, __u32 speed, int now)
874{
875 struct sk_buff *skb;
876
877 IRDA_DEBUG(0, "%s(), setting speed to %d\n", __FUNCTION__, speed);
878
879 IRDA_ASSERT(self != NULL, return;);
880 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
881
882 self->speed = speed;
883
884 /* Change speed now, or just piggyback speed on frames */
885 if (now) {
886 /* Send down empty frame to trigger speed change */
887 skb = dev_alloc_skb(0);
888 irlap_queue_xmit(self, skb);
889 }
890}
891
892/*
893 * Function irlap_init_qos_capabilities (self, qos)
894 *
895 * Initialize QoS for this IrLAP session, What we do is to compute the
896 * intersection of the QoS capabilities for the user, driver and for
897 * IrLAP itself. Normally, IrLAP will not specify any values, but it can
898 * be used to restrict certain values.
899 */
900static void irlap_init_qos_capabilities(struct irlap_cb *self,
901 struct qos_info *qos_user)
902{
903 IRDA_ASSERT(self != NULL, return;);
904 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
905 IRDA_ASSERT(self->netdev != NULL, return;);
906
907 /* Start out with the maximum QoS support possible */
908 irda_init_max_qos_capabilies(&self->qos_rx);
909
910 /* Apply drivers QoS capabilities */
911 irda_qos_compute_intersection(&self->qos_rx, self->qos_dev);
912
913 /*
914 * Check for user supplied QoS parameters. The service user is only
915 * allowed to supply these values. We check each parameter since the
916 * user may not have set all of them.
917 */
918 if (qos_user) {
919 IRDA_DEBUG(1, "%s(), Found user specified QoS!\n", __FUNCTION__);
920
921 if (qos_user->baud_rate.bits)
922 self->qos_rx.baud_rate.bits &= qos_user->baud_rate.bits;
923
924 if (qos_user->max_turn_time.bits)
925 self->qos_rx.max_turn_time.bits &= qos_user->max_turn_time.bits;
926 if (qos_user->data_size.bits)
927 self->qos_rx.data_size.bits &= qos_user->data_size.bits;
928
929 if (qos_user->link_disc_time.bits)
930 self->qos_rx.link_disc_time.bits &= qos_user->link_disc_time.bits;
931 }
932
933 /* Use 500ms in IrLAP for now */
934 self->qos_rx.max_turn_time.bits &= 0x01;
935
936 /* Set data size */
937 /*self->qos_rx.data_size.bits &= 0x03;*/
938
939 irda_qos_bits_to_value(&self->qos_rx);
940}
941
942/*
943 * Function irlap_apply_default_connection_parameters (void, now)
944 *
945 * Use the default connection and transmission parameters
946 */
947void irlap_apply_default_connection_parameters(struct irlap_cb *self)
948{
949 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
950
951 IRDA_ASSERT(self != NULL, return;);
952 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
953
954 /* xbofs : Default value in NDM */
955 self->next_bofs = 12;
956 self->bofs_count = 12;
957
958 /* NDM Speed is 9600 */
959 irlap_change_speed(self, 9600, TRUE);
960
961 /* Set mbusy when going to NDM state */
962 irda_device_set_media_busy(self->netdev, TRUE);
963
964 /*
965 * Generate random connection address for this session, which must
966 * be 7 bits wide and different from 0x00 and 0xfe
967 */
968 while ((self->caddr == 0x00) || (self->caddr == 0xfe)) {
969 get_random_bytes(&self->caddr, sizeof(self->caddr));
970 self->caddr &= 0xfe;
971 }
972
973 /* Use default values until connection has been negitiated */
974 self->slot_timeout = sysctl_slot_timeout;
975 self->final_timeout = FINAL_TIMEOUT;
976 self->poll_timeout = POLL_TIMEOUT;
977 self->wd_timeout = WD_TIMEOUT;
978
979 /* Set some default values */
980 self->qos_tx.baud_rate.value = 9600;
981 self->qos_rx.baud_rate.value = 9600;
982 self->qos_tx.max_turn_time.value = 0;
983 self->qos_rx.max_turn_time.value = 0;
984 self->qos_tx.min_turn_time.value = 0;
985 self->qos_rx.min_turn_time.value = 0;
986 self->qos_tx.data_size.value = 64;
987 self->qos_rx.data_size.value = 64;
988 self->qos_tx.window_size.value = 1;
989 self->qos_rx.window_size.value = 1;
990 self->qos_tx.additional_bofs.value = 12;
991 self->qos_rx.additional_bofs.value = 12;
992 self->qos_tx.link_disc_time.value = 0;
993 self->qos_rx.link_disc_time.value = 0;
994
995 irlap_flush_all_queues(self);
996
997 self->disconnect_pending = FALSE;
998 self->connect_pending = FALSE;
999}
1000
1001/*
1002 * Function irlap_apply_connection_parameters (qos, now)
1003 *
1004 * Initialize IrLAP with the negotiated QoS values
1005 *
1006 * If 'now' is false, the speed and xbofs will be changed after the next
1007 * frame is sent.
1008 * If 'now' is true, the speed and xbofs is changed immediately
1009 */
1010void irlap_apply_connection_parameters(struct irlap_cb *self, int now)
1011{
1012 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1013
1014 IRDA_ASSERT(self != NULL, return;);
1015 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
1016
1017 /* Set the negotiated xbofs value */
1018 self->next_bofs = self->qos_tx.additional_bofs.value;
1019 if (now)
1020 self->bofs_count = self->next_bofs;
1021
1022 /* Set the negotiated link speed (may need the new xbofs value) */
1023 irlap_change_speed(self, self->qos_tx.baud_rate.value, now);
1024
1025 self->window_size = self->qos_tx.window_size.value;
1026 self->window = self->qos_tx.window_size.value;
1027
1028#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
1029 /*
1030 * Calculate how many bytes it is possible to transmit before the
1031 * link must be turned around
1032 */
1033 self->line_capacity =
1034 irlap_max_line_capacity(self->qos_tx.baud_rate.value,
1035 self->qos_tx.max_turn_time.value);
1036 self->bytes_left = self->line_capacity;
1037#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
1038
1039
1040 /*
1041 * Initialize timeout values, some of the rules are listed on
1042 * page 92 in IrLAP.
1043 */
1044 IRDA_ASSERT(self->qos_tx.max_turn_time.value != 0, return;);
1045 IRDA_ASSERT(self->qos_rx.max_turn_time.value != 0, return;);
1046 /* The poll timeout applies only to the primary station.
1047 * It defines the maximum time the primary stay in XMIT mode
1048 * before timeout and turning the link around (sending a RR).
1049 * Or, this is how much we can keep the pf bit in primary mode.
1050 * Therefore, it must be lower or equal than our *OWN* max turn around.
1051 * Jean II */
1052 self->poll_timeout = self->qos_tx.max_turn_time.value * HZ / 1000;
1053 /* The Final timeout applies only to the primary station.
1054 * It defines the maximum time the primary wait (mostly in RECV mode)
1055 * for an answer from the secondary station before polling it again.
1056 * Therefore, it must be greater or equal than our *PARTNER*
1057 * max turn around time - Jean II */
1058 self->final_timeout = self->qos_rx.max_turn_time.value * HZ / 1000;
1059 /* The Watchdog Bit timeout applies only to the secondary station.
1060 * It defines the maximum time the secondary wait (mostly in RECV mode)
1061 * for poll from the primary station before getting annoyed.
1062 * Therefore, it must be greater or equal than our *PARTNER*
1063 * max turn around time - Jean II */
1064 self->wd_timeout = self->final_timeout * 2;
1065
1066 /*
1067 * N1 and N2 are maximum retry count for *both* the final timer
1068 * and the wd timer (with a factor 2) as defined above.
1069 * After N1 retry of a timer, we give a warning to the user.
1070 * After N2 retry, we consider the link dead and disconnect it.
1071 * Jean II
1072 */
1073
1074 /*
1075 * Set N1 to 0 if Link Disconnect/Threshold Time = 3 and set it to
1076 * 3 seconds otherwise. See page 71 in IrLAP for more details.
1077 * Actually, it's not always 3 seconds, as we allow to set
1078 * it via sysctl... Max maxtt is 500ms, and N1 need to be multiple
1079 * of 2, so 1 second is minimum we can allow. - Jean II
1080 */
1081 if (self->qos_tx.link_disc_time.value == sysctl_warn_noreply_time)
1082 /*
1083 * If we set N1 to 0, it will trigger immediately, which is
1084 * not what we want. What we really want is to disable it,
1085 * Jean II
1086 */
1087 self->N1 = -2; /* Disable - Need to be multiple of 2*/
1088 else
1089 self->N1 = sysctl_warn_noreply_time * 1000 /
1090 self->qos_rx.max_turn_time.value;
1091
1092 IRDA_DEBUG(4, "Setting N1 = %d\n", self->N1);
1093
1094 /* Set N2 to match our own disconnect time */
1095 self->N2 = self->qos_tx.link_disc_time.value * 1000 /
1096 self->qos_rx.max_turn_time.value;
1097 IRDA_DEBUG(4, "Setting N2 = %d\n", self->N2);
1098}
1099
1100#ifdef CONFIG_PROC_FS
1101struct irlap_iter_state {
1102 int id;
1103};
1104
1105static void *irlap_seq_start(struct seq_file *seq, loff_t *pos)
1106{
1107 struct irlap_iter_state *iter = seq->private;
1108 struct irlap_cb *self;
1109
1110 /* Protect our access to the tsap list */
1111 spin_lock_irq(&irlap->hb_spinlock);
1112 iter->id = 0;
1113
1114 for (self = (struct irlap_cb *) hashbin_get_first(irlap);
1115 self; self = (struct irlap_cb *) hashbin_get_next(irlap)) {
1116 if (iter->id == *pos)
1117 break;
1118 ++iter->id;
1119 }
1120
1121 return self;
1122}
1123
1124static void *irlap_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1125{
1126 struct irlap_iter_state *iter = seq->private;
1127
1128 ++*pos;
1129 ++iter->id;
1130 return (void *) hashbin_get_next(irlap);
1131}
1132
1133static void irlap_seq_stop(struct seq_file *seq, void *v)
1134{
1135 spin_unlock_irq(&irlap->hb_spinlock);
1136}
1137
1138static int irlap_seq_show(struct seq_file *seq, void *v)
1139{
1140 const struct irlap_iter_state *iter = seq->private;
1141 const struct irlap_cb *self = v;
1142
1143 IRDA_ASSERT(self->magic == LAP_MAGIC, return -EINVAL;);
1144
1145 seq_printf(seq, "irlap%d ", iter->id);
1146 seq_printf(seq, "state: %s\n",
1147 irlap_state[self->state]);
1148
1149 seq_printf(seq, " device name: %s, ",
1150 (self->netdev) ? self->netdev->name : "bug");
1151 seq_printf(seq, "hardware name: %s\n", self->hw_name);
1152
1153 seq_printf(seq, " caddr: %#02x, ", self->caddr);
1154 seq_printf(seq, "saddr: %#08x, ", self->saddr);
1155 seq_printf(seq, "daddr: %#08x\n", self->daddr);
1156
1157 seq_printf(seq, " win size: %d, ",
1158 self->window_size);
1159 seq_printf(seq, "win: %d, ", self->window);
1160#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
1161 seq_printf(seq, "line capacity: %d, ",
1162 self->line_capacity);
1163 seq_printf(seq, "bytes left: %d\n", self->bytes_left);
1164#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
1165 seq_printf(seq, " tx queue len: %d ",
1166 skb_queue_len(&self->txq));
1167 seq_printf(seq, "win queue len: %d ",
1168 skb_queue_len(&self->wx_list));
1169 seq_printf(seq, "rbusy: %s", self->remote_busy ?
1170 "TRUE" : "FALSE");
1171 seq_printf(seq, " mbusy: %s\n", self->media_busy ?
1172 "TRUE" : "FALSE");
1173
1174 seq_printf(seq, " retrans: %d ", self->retry_count);
1175 seq_printf(seq, "vs: %d ", self->vs);
1176 seq_printf(seq, "vr: %d ", self->vr);
1177 seq_printf(seq, "va: %d\n", self->va);
1178
1179 seq_printf(seq, " qos\tbps\tmaxtt\tdsize\twinsize\taddbofs\tmintt\tldisc\tcomp\n");
1180
1181 seq_printf(seq, " tx\t%d\t",
1182 self->qos_tx.baud_rate.value);
1183 seq_printf(seq, "%d\t",
1184 self->qos_tx.max_turn_time.value);
1185 seq_printf(seq, "%d\t",
1186 self->qos_tx.data_size.value);
1187 seq_printf(seq, "%d\t",
1188 self->qos_tx.window_size.value);
1189 seq_printf(seq, "%d\t",
1190 self->qos_tx.additional_bofs.value);
1191 seq_printf(seq, "%d\t",
1192 self->qos_tx.min_turn_time.value);
1193 seq_printf(seq, "%d\t",
1194 self->qos_tx.link_disc_time.value);
1195 seq_printf(seq, "\n");
1196
1197 seq_printf(seq, " rx\t%d\t",
1198 self->qos_rx.baud_rate.value);
1199 seq_printf(seq, "%d\t",
1200 self->qos_rx.max_turn_time.value);
1201 seq_printf(seq, "%d\t",
1202 self->qos_rx.data_size.value);
1203 seq_printf(seq, "%d\t",
1204 self->qos_rx.window_size.value);
1205 seq_printf(seq, "%d\t",
1206 self->qos_rx.additional_bofs.value);
1207 seq_printf(seq, "%d\t",
1208 self->qos_rx.min_turn_time.value);
1209 seq_printf(seq, "%d\n",
1210 self->qos_rx.link_disc_time.value);
1211
1212 return 0;
1213}
1214
1215static struct seq_operations irlap_seq_ops = {
1216 .start = irlap_seq_start,
1217 .next = irlap_seq_next,
1218 .stop = irlap_seq_stop,
1219 .show = irlap_seq_show,
1220};
1221
1222static int irlap_seq_open(struct inode *inode, struct file *file)
1223{
1224 struct seq_file *seq;
1225 int rc = -ENOMEM;
1226 struct irlap_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
1227
1228 if (!s)
1229 goto out;
1230
1231 if (irlap == NULL) {
1232 rc = -EINVAL;
1233 goto out_kfree;
1234 }
1235
1236 rc = seq_open(file, &irlap_seq_ops);
1237 if (rc)
1238 goto out_kfree;
1239
1240 seq = file->private_data;
1241 seq->private = s;
1242 memset(s, 0, sizeof(*s));
1243out:
1244 return rc;
1245out_kfree:
1246 kfree(s);
1247 goto out;
1248}
1249
1250struct file_operations irlap_seq_fops = {
1251 .owner = THIS_MODULE,
1252 .open = irlap_seq_open,
1253 .read = seq_read,
1254 .llseek = seq_lseek,
1255 .release = seq_release_private,
1256};
1257
1258#endif /* CONFIG_PROC_FS */
diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c
new file mode 100644
index 00000000000..1cd89f5f3b7
--- /dev/null
+++ b/net/irda/irlap_event.c
@@ -0,0 +1,2334 @@
1/*********************************************************************
2 *
3 * Filename: irlap_event.c
4 * Version: 0.9
5 * Description: IrLAP state machine implementation
6 * Status: Experimental.
7 * Author: Dag Brattli <dag@brattli.net>
8 * Created at: Sat Aug 16 00:59:29 1997
9 * Modified at: Sat Dec 25 21:07:57 1999
10 * Modified by: Dag Brattli <dag@brattli.net>
11 *
12 * Copyright (c) 1998-2000 Dag Brattli <dag@brattli.net>,
13 * Copyright (c) 1998 Thomas Davis <ratbert@radiks.net>
14 * All Rights Reserved.
15 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License as
19 * published by the Free Software Foundation; either version 2 of
20 * the License, or (at your option) any later version.
21 *
22 * Neither Dag Brattli nor University of Tromsø admit liability nor
23 * provide warranty for any of this software. This material is
24 * provided "AS-IS" and at no charge.
25 *
26 ********************************************************************/
27
28#include <linux/config.h>
29#include <linux/string.h>
30#include <linux/kernel.h>
31#include <linux/delay.h>
32#include <linux/skbuff.h>
33
34#include <net/irda/irda.h>
35#include <net/irda/irlap_event.h>
36
37#include <net/irda/timer.h>
38#include <net/irda/irlap.h>
39#include <net/irda/irlap_frame.h>
40#include <net/irda/qos.h>
41#include <net/irda/parameters.h>
42#include <net/irda/irlmp.h> /* irlmp_flow_indication(), ... */
43
44#include <net/irda/irda_device.h>
45
46#ifdef CONFIG_IRDA_FAST_RR
47int sysctl_fast_poll_increase = 50;
48#endif
49
50static int irlap_state_ndm (struct irlap_cb *self, IRLAP_EVENT event,
51 struct sk_buff *skb, struct irlap_info *info);
52static int irlap_state_query (struct irlap_cb *self, IRLAP_EVENT event,
53 struct sk_buff *skb, struct irlap_info *info);
54static int irlap_state_reply (struct irlap_cb *self, IRLAP_EVENT event,
55 struct sk_buff *skb, struct irlap_info *info);
56static int irlap_state_conn (struct irlap_cb *self, IRLAP_EVENT event,
57 struct sk_buff *skb, struct irlap_info *info);
58static int irlap_state_setup (struct irlap_cb *self, IRLAP_EVENT event,
59 struct sk_buff *skb, struct irlap_info *info);
60static int irlap_state_offline(struct irlap_cb *self, IRLAP_EVENT event,
61 struct sk_buff *skb, struct irlap_info *info);
62static int irlap_state_xmit_p (struct irlap_cb *self, IRLAP_EVENT event,
63 struct sk_buff *skb, struct irlap_info *info);
64static int irlap_state_pclose (struct irlap_cb *self, IRLAP_EVENT event,
65 struct sk_buff *skb, struct irlap_info *info);
66static int irlap_state_nrm_p (struct irlap_cb *self, IRLAP_EVENT event,
67 struct sk_buff *skb, struct irlap_info *info);
68static int irlap_state_reset_wait(struct irlap_cb *self, IRLAP_EVENT event,
69 struct sk_buff *skb, struct irlap_info *info);
70static int irlap_state_reset (struct irlap_cb *self, IRLAP_EVENT event,
71 struct sk_buff *skb, struct irlap_info *info);
72static int irlap_state_nrm_s (struct irlap_cb *self, IRLAP_EVENT event,
73 struct sk_buff *skb, struct irlap_info *info);
74static int irlap_state_xmit_s (struct irlap_cb *self, IRLAP_EVENT event,
75 struct sk_buff *skb, struct irlap_info *info);
76static int irlap_state_sclose (struct irlap_cb *self, IRLAP_EVENT event,
77 struct sk_buff *skb, struct irlap_info *info);
78static int irlap_state_reset_check(struct irlap_cb *, IRLAP_EVENT event,
79 struct sk_buff *, struct irlap_info *);
80
81#ifdef CONFIG_IRDA_DEBUG
82static const char *irlap_event[] = {
83 "DISCOVERY_REQUEST",
84 "CONNECT_REQUEST",
85 "CONNECT_RESPONSE",
86 "DISCONNECT_REQUEST",
87 "DATA_REQUEST",
88 "RESET_REQUEST",
89 "RESET_RESPONSE",
90 "SEND_I_CMD",
91 "SEND_UI_FRAME",
92 "RECV_DISCOVERY_XID_CMD",
93 "RECV_DISCOVERY_XID_RSP",
94 "RECV_SNRM_CMD",
95 "RECV_TEST_CMD",
96 "RECV_TEST_RSP",
97 "RECV_UA_RSP",
98 "RECV_DM_RSP",
99 "RECV_RD_RSP",
100 "RECV_I_CMD",
101 "RECV_I_RSP",
102 "RECV_UI_FRAME",
103 "RECV_FRMR_RSP",
104 "RECV_RR_CMD",
105 "RECV_RR_RSP",
106 "RECV_RNR_CMD",
107 "RECV_RNR_RSP",
108 "RECV_REJ_CMD",
109 "RECV_REJ_RSP",
110 "RECV_SREJ_CMD",
111 "RECV_SREJ_RSP",
112 "RECV_DISC_CMD",
113 "SLOT_TIMER_EXPIRED",
114 "QUERY_TIMER_EXPIRED",
115 "FINAL_TIMER_EXPIRED",
116 "POLL_TIMER_EXPIRED",
117 "DISCOVERY_TIMER_EXPIRED",
118 "WD_TIMER_EXPIRED",
119 "BACKOFF_TIMER_EXPIRED",
120 "MEDIA_BUSY_TIMER_EXPIRED",
121};
122#endif /* CONFIG_IRDA_DEBUG */
123
124const char *irlap_state[] = {
125 "LAP_NDM",
126 "LAP_QUERY",
127 "LAP_REPLY",
128 "LAP_CONN",
129 "LAP_SETUP",
130 "LAP_OFFLINE",
131 "LAP_XMIT_P",
132 "LAP_PCLOSE",
133 "LAP_NRM_P",
134 "LAP_RESET_WAIT",
135 "LAP_RESET",
136 "LAP_NRM_S",
137 "LAP_XMIT_S",
138 "LAP_SCLOSE",
139 "LAP_RESET_CHECK",
140};
141
142static int (*state[])(struct irlap_cb *self, IRLAP_EVENT event,
143 struct sk_buff *skb, struct irlap_info *info) =
144{
145 irlap_state_ndm,
146 irlap_state_query,
147 irlap_state_reply,
148 irlap_state_conn,
149 irlap_state_setup,
150 irlap_state_offline,
151 irlap_state_xmit_p,
152 irlap_state_pclose,
153 irlap_state_nrm_p,
154 irlap_state_reset_wait,
155 irlap_state_reset,
156 irlap_state_nrm_s,
157 irlap_state_xmit_s,
158 irlap_state_sclose,
159 irlap_state_reset_check,
160};
161
162/*
163 * Function irda_poll_timer_expired (data)
164 *
165 * Poll timer has expired. Normally we must now send a RR frame to the
166 * remote device
167 */
168static void irlap_poll_timer_expired(void *data)
169{
170 struct irlap_cb *self = (struct irlap_cb *) data;
171
172 IRDA_ASSERT(self != NULL, return;);
173 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
174
175 irlap_do_event(self, POLL_TIMER_EXPIRED, NULL, NULL);
176}
177
178/*
179 * Calculate and set time before we will have to send back the pf bit
180 * to the peer. Use in primary.
181 * Make sure that state is XMIT_P/XMIT_S when calling this function
182 * (and that nobody messed up with the state). - Jean II
183 */
184static void irlap_start_poll_timer(struct irlap_cb *self, int timeout)
185{
186 IRDA_ASSERT(self != NULL, return;);
187 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
188
189#ifdef CONFIG_IRDA_FAST_RR
190 /*
191 * Send out the RR frames faster if our own transmit queue is empty, or
192 * if the peer is busy. The effect is a much faster conversation
193 */
194 if ((skb_queue_len(&self->txq) == 0) || (self->remote_busy)) {
195 if (self->fast_RR == TRUE) {
196 /*
197 * Assert that the fast poll timer has not reached the
198 * normal poll timer yet
199 */
200 if (self->fast_RR_timeout < timeout) {
201 /*
202 * FIXME: this should be a more configurable
203 * function
204 */
205 self->fast_RR_timeout +=
206 (sysctl_fast_poll_increase * HZ/1000);
207
208 /* Use this fast(er) timeout instead */
209 timeout = self->fast_RR_timeout;
210 }
211 } else {
212 self->fast_RR = TRUE;
213
214 /* Start with just 0 ms */
215 self->fast_RR_timeout = 0;
216 timeout = 0;
217 }
218 } else
219 self->fast_RR = FALSE;
220
221 IRDA_DEBUG(3, "%s(), timeout=%d (%ld)\n", __FUNCTION__, timeout, jiffies);
222#endif /* CONFIG_IRDA_FAST_RR */
223
224 if (timeout == 0)
225 irlap_do_event(self, POLL_TIMER_EXPIRED, NULL, NULL);
226 else
227 irda_start_timer(&self->poll_timer, timeout, self,
228 irlap_poll_timer_expired);
229}
230
231/*
232 * Function irlap_do_event (event, skb, info)
233 *
234 * Rushes through the state machine without any delay. If state == XMIT
235 * then send queued data frames.
236 */
237void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event,
238 struct sk_buff *skb, struct irlap_info *info)
239{
240 int ret;
241
242 if (!self || self->magic != LAP_MAGIC)
243 return;
244
245 IRDA_DEBUG(3, "%s(), event = %s, state = %s\n", __FUNCTION__,
246 irlap_event[event], irlap_state[self->state]);
247
248 ret = (*state[self->state])(self, event, skb, info);
249
250 /*
251 * Check if there are any pending events that needs to be executed
252 */
253 switch (self->state) {
254 case LAP_XMIT_P: /* FALLTHROUGH */
255 case LAP_XMIT_S:
256 /*
257 * We just received the pf bit and are at the beginning
258 * of a new LAP transmit window.
259 * Check if there are any queued data frames, and do not
260 * try to disconnect link if we send any data frames, since
261 * that will change the state away form XMIT
262 */
263 IRDA_DEBUG(2, "%s() : queue len = %d\n", __FUNCTION__,
264 skb_queue_len(&self->txq));
265
266 if (skb_queue_len(&self->txq)) {
267 /* Prevent race conditions with irlap_data_request() */
268 self->local_busy = TRUE;
269
270 /* Theory of operation.
271 * We send frames up to when we fill the window or
272 * reach line capacity. Those frames will queue up
273 * in the device queue, and the driver will slowly
274 * send them.
275 * After each frame that we send, we poll the higher
276 * layer for more data. It's the right time to do
277 * that because the link layer need to perform the mtt
278 * and then send the first frame, so we can afford
279 * to send a bit of time in kernel space.
280 * The explicit flow indication allow to minimise
281 * buffers (== lower latency), to avoid higher layer
282 * polling via timers (== less context switches) and
283 * to implement a crude scheduler - Jean II */
284
285 /* Try to send away all queued data frames */
286 while ((skb = skb_dequeue(&self->txq)) != NULL) {
287 /* Send one frame */
288 ret = (*state[self->state])(self, SEND_I_CMD,
289 skb, NULL);
290 /* Drop reference count.
291 * It will be increase as needed in
292 * irlap_send_data_xxx() */
293 kfree_skb(skb);
294
295 /* Poll the higher layers for one more frame */
296 irlmp_flow_indication(self->notify.instance,
297 FLOW_START);
298
299 if (ret == -EPROTO)
300 break; /* Try again later! */
301 }
302 /* Finished transmitting */
303 self->local_busy = FALSE;
304 } else if (self->disconnect_pending) {
305 self->disconnect_pending = FALSE;
306
307 ret = (*state[self->state])(self, DISCONNECT_REQUEST,
308 NULL, NULL);
309 }
310 break;
311/* case LAP_NDM: */
312/* case LAP_CONN: */
313/* case LAP_RESET_WAIT: */
314/* case LAP_RESET_CHECK: */
315 default:
316 break;
317 }
318}
319
320/*
321 * Function irlap_next_state (self, state)
322 *
323 * Switches state and provides debug information
324 *
325 */
326static inline void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state)
327{
328 /*
329 if (!self || self->magic != LAP_MAGIC)
330 return;
331
332 IRDA_DEBUG(4, "next LAP state = %s\n", irlap_state[state]);
333 */
334 self->state = state;
335}
336
337/*
338 * Function irlap_state_ndm (event, skb, frame)
339 *
340 * NDM (Normal Disconnected Mode) state
341 *
342 */
343static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event,
344 struct sk_buff *skb, struct irlap_info *info)
345{
346 discovery_t *discovery_rsp;
347 int ret = 0;
348
349 IRDA_ASSERT(self != NULL, return -1;);
350 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
351
352 switch (event) {
353 case CONNECT_REQUEST:
354 IRDA_ASSERT(self->netdev != NULL, return -1;);
355
356 if (self->media_busy) {
357 /* Note : this will never happen, because we test
358 * media busy in irlap_connect_request() and
359 * postpone the event... - Jean II */
360 IRDA_DEBUG(0, "%s(), CONNECT_REQUEST: media busy!\n",
361 __FUNCTION__);
362
363 /* Always switch state before calling upper layers */
364 irlap_next_state(self, LAP_NDM);
365
366 irlap_disconnect_indication(self, LAP_MEDIA_BUSY);
367 } else {
368 irlap_send_snrm_frame(self, &self->qos_rx);
369
370 /* Start Final-bit timer */
371 irlap_start_final_timer(self, self->final_timeout);
372
373 self->retry_count = 0;
374 irlap_next_state(self, LAP_SETUP);
375 }
376 break;
377 case RECV_SNRM_CMD:
378 /* Check if the frame contains and I field */
379 if (info) {
380 self->daddr = info->daddr;
381 self->caddr = info->caddr;
382
383 irlap_next_state(self, LAP_CONN);
384
385 irlap_connect_indication(self, skb);
386 } else {
387 IRDA_DEBUG(0, "%s(), SNRM frame does not "
388 "contain an I field!\n", __FUNCTION__);
389 }
390 break;
391 case DISCOVERY_REQUEST:
392 IRDA_ASSERT(info != NULL, return -1;);
393
394 if (self->media_busy) {
395 IRDA_DEBUG(1, "%s(), DISCOVERY_REQUEST: media busy!\n",
396 __FUNCTION__);
397 /* irlap->log.condition = MEDIA_BUSY; */
398
399 /* This will make IrLMP try again */
400 irlap_discovery_confirm(self, NULL);
401 /* Note : the discovery log is not cleaned up here,
402 * it will be done in irlap_discovery_request()
403 * Jean II */
404 return 0;
405 }
406
407 self->S = info->S;
408 self->s = info->s;
409 irlap_send_discovery_xid_frame(self, info->S, info->s, TRUE,
410 info->discovery);
411 self->frame_sent = FALSE;
412 self->s++;
413
414 irlap_start_slot_timer(self, self->slot_timeout);
415 irlap_next_state(self, LAP_QUERY);
416 break;
417 case RECV_DISCOVERY_XID_CMD:
418 IRDA_ASSERT(info != NULL, return -1;);
419
420 /* Assert that this is not the final slot */
421 if (info->s <= info->S) {
422 self->slot = irlap_generate_rand_time_slot(info->S,
423 info->s);
424 if (self->slot == info->s) {
425 discovery_rsp = irlmp_get_discovery_response();
426 discovery_rsp->data.daddr = info->daddr;
427
428 irlap_send_discovery_xid_frame(self, info->S,
429 self->slot,
430 FALSE,
431 discovery_rsp);
432 self->frame_sent = TRUE;
433 } else
434 self->frame_sent = FALSE;
435
436 /*
437 * Go to reply state until end of discovery to
438 * inhibit our own transmissions. Set the timer
439 * to not stay forever there... Jean II
440 */
441 irlap_start_query_timer(self, info->S, info->s);
442 irlap_next_state(self, LAP_REPLY);
443 } else {
444 /* This is the final slot. How is it possible ?
445 * This would happen is both discoveries are just slightly
446 * offset (if they are in sync, all packets are lost).
447 * Most often, all the discovery requests will be received
448 * in QUERY state (see my comment there), except for the
449 * last frame that will come here.
450 * The big trouble when it happen is that active discovery
451 * doesn't happen, because nobody answer the discoveries
452 * frame of the other guy, so the log shows up empty.
453 * What should we do ?
454 * Not much. It's too late to answer those discovery frames,
455 * so we just pass the info to IrLMP who will put it in the
456 * log (and post an event).
457 * Another cause would be devices that do discovery much
458 * slower than us, however the latest fixes should minimise
459 * those cases...
460 * Jean II
461 */
462 IRDA_DEBUG(1, "%s(), Receiving final discovery request, missed the discovery slots :-(\n", __FUNCTION__);
463
464 /* Last discovery request -> in the log */
465 irlap_discovery_indication(self, info->discovery);
466 }
467 break;
468 case MEDIA_BUSY_TIMER_EXPIRED:
469 /* A bunch of events may be postponed because the media is
470 * busy (usually immediately after we close a connection),
471 * or while we are doing discovery (state query/reply).
472 * In all those cases, the media busy flag will be cleared
473 * when it's OK for us to process those postponed events.
474 * This event is not mentioned in the state machines in the
475 * IrLAP spec. It's because they didn't consider Ultra and
476 * postponing connection request is optional.
477 * Jean II */
478#ifdef CONFIG_IRDA_ULTRA
479 /* Send any pending Ultra frames if any */
480 if (!skb_queue_empty(&self->txq_ultra)) {
481 /* We don't send the frame, just post an event.
482 * Also, previously this code was in timer.c...
483 * Jean II */
484 ret = (*state[self->state])(self, SEND_UI_FRAME,
485 NULL, NULL);
486 }
487#endif /* CONFIG_IRDA_ULTRA */
488 /* Check if we should try to connect.
489 * This code was previously in irlap_do_event() */
490 if (self->connect_pending) {
491 self->connect_pending = FALSE;
492
493 /* This one *should* not pend in this state, except
494 * if a socket try to connect and immediately
495 * disconnect. - clear - Jean II */
496 if (self->disconnect_pending)
497 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
498 else
499 ret = (*state[self->state])(self,
500 CONNECT_REQUEST,
501 NULL, NULL);
502 self->disconnect_pending = FALSE;
503 }
504 /* Note : one way to test if this code works well (including
505 * media busy and small busy) is to create a user space
506 * application generating an Ultra packet every 3.05 sec (or
507 * 2.95 sec) and to see how it interact with discovery.
508 * It's fairly easy to check that no packet is lost, that the
509 * packets are postponed during discovery and that after
510 * discovery indication you have a 100ms "gap".
511 * As connection request and Ultra are now processed the same
512 * way, this avoid the tedious job of trying IrLAP connection
513 * in all those cases...
514 * Jean II */
515 break;
516#ifdef CONFIG_IRDA_ULTRA
517 case SEND_UI_FRAME:
518 {
519 int i;
520 /* Only allowed to repeat an operation twice */
521 for (i=0; ((i<2) && (self->media_busy == FALSE)); i++) {
522 skb = skb_dequeue(&self->txq_ultra);
523 if (skb)
524 irlap_send_ui_frame(self, skb, CBROADCAST,
525 CMD_FRAME);
526 else
527 break;
528 /* irlap_send_ui_frame() won't increase skb reference
529 * count, so no dev_kfree_skb() - Jean II */
530 }
531 if (i == 2) {
532 /* Force us to listen 500 ms again */
533 irda_device_set_media_busy(self->netdev, TRUE);
534 }
535 break;
536 }
537 case RECV_UI_FRAME:
538 /* Only accept broadcast frames in NDM mode */
539 if (info->caddr != CBROADCAST) {
540 IRDA_DEBUG(0, "%s(), not a broadcast frame!\n",
541 __FUNCTION__);
542 } else
543 irlap_unitdata_indication(self, skb);
544 break;
545#endif /* CONFIG_IRDA_ULTRA */
546 case RECV_TEST_CMD:
547 /* Remove test frame header */
548 skb_pull(skb, sizeof(struct test_frame));
549
550 /*
551 * Send response. This skb will not be sent out again, and
552 * will only be used to send out the same info as the cmd
553 */
554 irlap_send_test_frame(self, CBROADCAST, info->daddr, skb);
555 break;
556 case RECV_TEST_RSP:
557 IRDA_DEBUG(0, "%s() not implemented!\n", __FUNCTION__);
558 break;
559 default:
560 IRDA_DEBUG(2, "%s(), Unknown event %s\n", __FUNCTION__,
561 irlap_event[event]);
562
563 ret = -1;
564 break;
565 }
566 return ret;
567}
568
569/*
570 * Function irlap_state_query (event, skb, info)
571 *
572 * QUERY state
573 *
574 */
575static int irlap_state_query(struct irlap_cb *self, IRLAP_EVENT event,
576 struct sk_buff *skb, struct irlap_info *info)
577{
578 int ret = 0;
579
580 IRDA_ASSERT(self != NULL, return -1;);
581 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
582
583 switch (event) {
584 case RECV_DISCOVERY_XID_RSP:
585 IRDA_ASSERT(info != NULL, return -1;);
586 IRDA_ASSERT(info->discovery != NULL, return -1;);
587
588 IRDA_DEBUG(4, "%s(), daddr=%08x\n", __FUNCTION__,
589 info->discovery->data.daddr);
590
591 if (!self->discovery_log) {
592 IRDA_WARNING("%s: discovery log is gone! "
593 "maybe the discovery timeout has been set"
594 " to short?\n", __FUNCTION__);
595 break;
596 }
597 hashbin_insert(self->discovery_log,
598 (irda_queue_t *) info->discovery,
599 info->discovery->data.daddr, NULL);
600
601 /* Keep state */
602 /* irlap_next_state(self, LAP_QUERY); */
603
604 break;
605 case RECV_DISCOVERY_XID_CMD:
606 /* Yes, it is possible to receive those frames in this mode.
607 * Note that most often the last discovery request won't
608 * occur here but in NDM state (see my comment there).
609 * What should we do ?
610 * Not much. We are currently performing our own discovery,
611 * therefore we can't answer those frames. We don't want
612 * to change state either. We just pass the info to
613 * IrLMP who will put it in the log (and post an event).
614 * Jean II
615 */
616
617 IRDA_ASSERT(info != NULL, return -1;);
618
619 IRDA_DEBUG(1, "%s(), Receiving discovery request (s = %d) while performing discovery :-(\n", __FUNCTION__, info->s);
620
621 /* Last discovery request ? */
622 if (info->s == 0xff)
623 irlap_discovery_indication(self, info->discovery);
624 break;
625 case SLOT_TIMER_EXPIRED:
626 /*
627 * Wait a little longer if we detect an incoming frame. This
628 * is not mentioned in the spec, but is a good thing to do,
629 * since we want to work even with devices that violate the
630 * timing requirements.
631 */
632 if (irda_device_is_receiving(self->netdev) && !self->add_wait) {
633 IRDA_DEBUG(2, "%s(), device is slow to answer, "
634 "waiting some more!\n", __FUNCTION__);
635 irlap_start_slot_timer(self, msecs_to_jiffies(10));
636 self->add_wait = TRUE;
637 return ret;
638 }
639 self->add_wait = FALSE;
640
641 if (self->s < self->S) {
642 irlap_send_discovery_xid_frame(self, self->S,
643 self->s, TRUE,
644 self->discovery_cmd);
645 self->s++;
646 irlap_start_slot_timer(self, self->slot_timeout);
647
648 /* Keep state */
649 irlap_next_state(self, LAP_QUERY);
650 } else {
651 /* This is the final slot! */
652 irlap_send_discovery_xid_frame(self, self->S, 0xff,
653 TRUE,
654 self->discovery_cmd);
655
656 /* Always switch state before calling upper layers */
657 irlap_next_state(self, LAP_NDM);
658
659 /*
660 * We are now finished with the discovery procedure,
661 * so now we must return the results
662 */
663 irlap_discovery_confirm(self, self->discovery_log);
664
665 /* IrLMP should now have taken care of the log */
666 self->discovery_log = NULL;
667 }
668 break;
669 default:
670 IRDA_DEBUG(2, "%s(), Unknown event %s\n", __FUNCTION__,
671 irlap_event[event]);
672
673 ret = -1;
674 break;
675 }
676 return ret;
677}
678
679/*
680 * Function irlap_state_reply (self, event, skb, info)
681 *
682 * REPLY, we have received a XID discovery frame from a device and we
683 * are waiting for the right time slot to send a response XID frame
684 *
685 */
686static int irlap_state_reply(struct irlap_cb *self, IRLAP_EVENT event,
687 struct sk_buff *skb, struct irlap_info *info)
688{
689 discovery_t *discovery_rsp;
690 int ret=0;
691
692 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
693
694 IRDA_ASSERT(self != NULL, return -1;);
695 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
696
697 switch (event) {
698 case QUERY_TIMER_EXPIRED:
699 IRDA_DEBUG(0, "%s(), QUERY_TIMER_EXPIRED <%ld>\n",
700 __FUNCTION__, jiffies);
701 irlap_next_state(self, LAP_NDM);
702 break;
703 case RECV_DISCOVERY_XID_CMD:
704 IRDA_ASSERT(info != NULL, return -1;);
705 /* Last frame? */
706 if (info->s == 0xff) {
707 del_timer(&self->query_timer);
708
709 /* info->log.condition = REMOTE; */
710
711 /* Always switch state before calling upper layers */
712 irlap_next_state(self, LAP_NDM);
713
714 irlap_discovery_indication(self, info->discovery);
715 } else {
716 /* If it's our slot, send our reply */
717 if ((info->s >= self->slot) && (!self->frame_sent)) {
718 discovery_rsp = irlmp_get_discovery_response();
719 discovery_rsp->data.daddr = info->daddr;
720
721 irlap_send_discovery_xid_frame(self, info->S,
722 self->slot,
723 FALSE,
724 discovery_rsp);
725
726 self->frame_sent = TRUE;
727 }
728 /* Readjust our timer to accomodate devices
729 * doing faster or slower discovery than us...
730 * Jean II */
731 irlap_start_query_timer(self, info->S, info->s);
732
733 /* Keep state */
734 //irlap_next_state(self, LAP_REPLY);
735 }
736 break;
737 default:
738 IRDA_DEBUG(1, "%s(), Unknown event %d, %s\n", __FUNCTION__,
739 event, irlap_event[event]);
740
741 ret = -1;
742 break;
743 }
744 return ret;
745}
746
747/*
748 * Function irlap_state_conn (event, skb, info)
749 *
750 * CONN, we have received a SNRM command and is waiting for the upper
751 * layer to accept or refuse connection
752 *
753 */
754static int irlap_state_conn(struct irlap_cb *self, IRLAP_EVENT event,
755 struct sk_buff *skb, struct irlap_info *info)
756{
757 int ret = 0;
758
759 IRDA_DEBUG(4, "%s(), event=%s\n", __FUNCTION__, irlap_event[ event]);
760
761 IRDA_ASSERT(self != NULL, return -1;);
762 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
763
764 switch (event) {
765 case CONNECT_RESPONSE:
766 skb_pull(skb, sizeof(struct snrm_frame));
767
768 IRDA_ASSERT(self->netdev != NULL, return -1;);
769
770 irlap_qos_negotiate(self, skb);
771
772 irlap_initiate_connection_state(self);
773
774 /*
775 * Applying the parameters now will make sure we change speed
776 * *after* we have sent the next frame
777 */
778 irlap_apply_connection_parameters(self, FALSE);
779
780 /*
781 * Sending this frame will force a speed change after it has
782 * been sent (i.e. the frame will be sent at 9600).
783 */
784 irlap_send_ua_response_frame(self, &self->qos_rx);
785
786#if 0
787 /*
788 * We are allowed to send two frames, but this may increase
789 * the connect latency, so lets not do it for now.
790 */
791 /* This is full of good intentions, but doesn't work in
792 * practice.
793 * After sending the first UA response, we switch the
794 * dongle to the negotiated speed, which is usually
795 * different than 9600 kb/s.
796 * From there, there is two solutions :
797 * 1) The other end has received the first UA response :
798 * it will set up the connection, move to state LAP_NRM_P,
799 * and will ignore and drop the second UA response.
800 * Actually, it's even worse : the other side will almost
801 * immediately send a RR that will likely collide with the
802 * UA response (depending on negotiated turnaround).
803 * 2) The other end has not received the first UA response,
804 * will stay at 9600 and will never see the second UA response.
805 * Jean II */
806 irlap_send_ua_response_frame(self, &self->qos_rx);
807#endif
808
809 /*
810 * The WD-timer could be set to the duration of the P-timer
811 * for this case, but it is recommended to use twice the
812 * value (note 3 IrLAP p. 60).
813 */
814 irlap_start_wd_timer(self, self->wd_timeout);
815 irlap_next_state(self, LAP_NRM_S);
816
817 break;
818 case RECV_DISCOVERY_XID_CMD:
819 IRDA_DEBUG(3, "%s(), event RECV_DISCOVER_XID_CMD!\n",
820 __FUNCTION__);
821 irlap_next_state(self, LAP_NDM);
822
823 break;
824 case DISCONNECT_REQUEST:
825 IRDA_DEBUG(0, "%s(), Disconnect request!\n", __FUNCTION__);
826 irlap_send_dm_frame(self);
827 irlap_next_state( self, LAP_NDM);
828 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
829 break;
830 default:
831 IRDA_DEBUG(1, "%s(), Unknown event %d, %s\n", __FUNCTION__,
832 event, irlap_event[event]);
833
834 ret = -1;
835 break;
836 }
837
838 return ret;
839}
840
841/*
842 * Function irlap_state_setup (event, skb, frame)
843 *
844 * SETUP state, The local layer has transmitted a SNRM command frame to
845 * a remote peer layer and is awaiting a reply .
846 *
847 */
848static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event,
849 struct sk_buff *skb, struct irlap_info *info)
850{
851 int ret = 0;
852
853 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
854
855 IRDA_ASSERT(self != NULL, return -1;);
856 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
857
858 switch (event) {
859 case FINAL_TIMER_EXPIRED:
860 if (self->retry_count < self->N3) {
861/*
862 * Perform random backoff, Wait a random number of time units, minimum
863 * duration half the time taken to transmitt a SNRM frame, maximum duration
864 * 1.5 times the time taken to transmit a SNRM frame. So this time should
865 * between 15 msecs and 45 msecs.
866 */
867 irlap_start_backoff_timer(self, msecs_to_jiffies(20 +
868 (jiffies % 30)));
869 } else {
870 /* Always switch state before calling upper layers */
871 irlap_next_state(self, LAP_NDM);
872
873 irlap_disconnect_indication(self, LAP_FOUND_NONE);
874 }
875 break;
876 case BACKOFF_TIMER_EXPIRED:
877 irlap_send_snrm_frame(self, &self->qos_rx);
878 irlap_start_final_timer(self, self->final_timeout);
879 self->retry_count++;
880 break;
881 case RECV_SNRM_CMD:
882 IRDA_DEBUG(4, "%s(), SNRM battle!\n", __FUNCTION__);
883
884 IRDA_ASSERT(skb != NULL, return 0;);
885 IRDA_ASSERT(info != NULL, return 0;);
886
887 /*
888 * The device with the largest device address wins the battle
889 * (both have sent a SNRM command!)
890 */
891 if (info &&(info->daddr > self->saddr)) {
892 del_timer(&self->final_timer);
893 irlap_initiate_connection_state(self);
894
895 IRDA_ASSERT(self->netdev != NULL, return -1;);
896
897 skb_pull(skb, sizeof(struct snrm_frame));
898
899 irlap_qos_negotiate(self, skb);
900
901 /* Send UA frame and then change link settings */
902 irlap_apply_connection_parameters(self, FALSE);
903 irlap_send_ua_response_frame(self, &self->qos_rx);
904
905 irlap_next_state(self, LAP_NRM_S);
906 irlap_connect_confirm(self, skb);
907
908 /*
909 * The WD-timer could be set to the duration of the
910 * P-timer for this case, but it is recommended
911 * to use twice the value (note 3 IrLAP p. 60).
912 */
913 irlap_start_wd_timer(self, self->wd_timeout);
914 } else {
915 /* We just ignore the other device! */
916 irlap_next_state(self, LAP_SETUP);
917 }
918 break;
919 case RECV_UA_RSP:
920 /* Stop F-timer */
921 del_timer(&self->final_timer);
922
923 /* Initiate connection state */
924 irlap_initiate_connection_state(self);
925
926 /* Negotiate connection parameters */
927 IRDA_ASSERT(skb->len > 10, return -1;);
928
929 skb_pull(skb, sizeof(struct ua_frame));
930
931 IRDA_ASSERT(self->netdev != NULL, return -1;);
932
933 irlap_qos_negotiate(self, skb);
934
935 /* Set the new link setting *now* (before the rr frame) */
936 irlap_apply_connection_parameters(self, TRUE);
937 self->retry_count = 0;
938
939 /* Wait for turnaround time to give a chance to the other
940 * device to be ready to receive us.
941 * Note : the time to switch speed is typically larger
942 * than the turnaround time, but as we don't have the other
943 * side speed switch time, that's our best guess...
944 * Jean II */
945 irlap_wait_min_turn_around(self, &self->qos_tx);
946
947 /* This frame will actually be sent at the new speed */
948 irlap_send_rr_frame(self, CMD_FRAME);
949
950 /* The timer is set to half the normal timer to quickly
951 * detect a failure to negociate the new connection
952 * parameters. IrLAP 6.11.3.2, note 3.
953 * Note that currently we don't process this failure
954 * properly, as we should do a quick disconnect.
955 * Jean II */
956 irlap_start_final_timer(self, self->final_timeout/2);
957 irlap_next_state(self, LAP_NRM_P);
958
959 irlap_connect_confirm(self, skb);
960 break;
961 case RECV_DM_RSP: /* FALLTHROUGH */
962 case RECV_DISC_CMD:
963 del_timer(&self->final_timer);
964 irlap_next_state(self, LAP_NDM);
965
966 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
967 break;
968 default:
969 IRDA_DEBUG(1, "%s(), Unknown event %d, %s\n", __FUNCTION__,
970 event, irlap_event[event]);
971
972 ret = -1;
973 break;
974 }
975 return ret;
976}
977
978/*
979 * Function irlap_state_offline (self, event, skb, info)
980 *
981 * OFFLINE state, not used for now!
982 *
983 */
984static int irlap_state_offline(struct irlap_cb *self, IRLAP_EVENT event,
985 struct sk_buff *skb, struct irlap_info *info)
986{
987 IRDA_DEBUG( 0, "%s(), Unknown event\n", __FUNCTION__);
988
989 return -1;
990}
991
992/*
993 * Function irlap_state_xmit_p (self, event, skb, info)
994 *
995 * XMIT, Only the primary station has right to transmit, and we
996 * therefore do not expect to receive any transmissions from other
997 * stations.
998 *
999 */
1000static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event,
1001 struct sk_buff *skb, struct irlap_info *info)
1002{
1003 int ret = 0;
1004
1005 switch (event) {
1006 case SEND_I_CMD:
1007 /*
1008 * Only send frame if send-window > 0.
1009 */
1010 if ((self->window > 0) && (!self->remote_busy)) {
1011 int nextfit;
1012#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
1013 struct sk_buff *skb_next;
1014
1015 /* With DYNAMIC_WINDOW, we keep the window size
1016 * maximum, and adapt on the packets we are sending.
1017 * At 115k, we can send only 2 packets of 2048 bytes
1018 * in a 500 ms turnaround. Without this option, we
1019 * would always limit the window to 2. With this
1020 * option, if we send smaller packets, we can send
1021 * up to 7 of them (always depending on QoS).
1022 * Jean II */
1023
1024 /* Look at the next skb. This is safe, as we are
1025 * the only consumer of the Tx queue (if we are not,
1026 * we have other problems) - Jean II */
1027 skb_next = skb_peek(&self->txq);
1028
1029 /* Check if a subsequent skb exist and would fit in
1030 * the current window (with respect to turnaround
1031 * time).
1032 * This allow us to properly mark the current packet
1033 * with the pf bit, to avoid falling back on the
1034 * second test below, and avoid waiting the
1035 * end of the window and sending a extra RR.
1036 * Note : (skb_next != NULL) <=> (skb_queue_len() > 0)
1037 * Jean II */
1038 nextfit = ((skb_next != NULL) &&
1039 ((skb_next->len + skb->len) <=
1040 self->bytes_left));
1041
1042 /*
1043 * The current packet may not fit ! Because of test
1044 * above, this should not happen any more !!!
1045 * Test if we have transmitted more bytes over the
1046 * link than its possible to do with the current
1047 * speed and turn-around-time.
1048 */
1049 if((!nextfit) && (skb->len > self->bytes_left)) {
1050 IRDA_DEBUG(0, "%s(), Not allowed to transmit"
1051 " more bytes!\n", __FUNCTION__);
1052 /* Requeue the skb */
1053 skb_queue_head(&self->txq, skb_get(skb));
1054 /*
1055 * We should switch state to LAP_NRM_P, but
1056 * that is not possible since we must be sure
1057 * that we poll the other side. Since we have
1058 * used up our time, the poll timer should
1059 * trigger anyway now, so we just wait for it
1060 * DB
1061 */
1062 /*
1063 * Sorry, but that's not totally true. If
1064 * we send 2000B packets, we may wait another
1065 * 1000B until our turnaround expire. That's
1066 * why we need to be proactive in avoiding
1067 * coming here. - Jean II
1068 */
1069 return -EPROTO;
1070 }
1071
1072 /* Substract space used by this skb */
1073 self->bytes_left -= skb->len;
1074#else /* CONFIG_IRDA_DYNAMIC_WINDOW */
1075 /* Window has been adjusted for the max packet
1076 * size, so much simpler... - Jean II */
1077 nextfit = (skb_queue_len(&self->txq) > 0);
1078#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
1079 /*
1080 * Send data with poll bit cleared only if window > 1
1081 * and there is more frames after this one to be sent
1082 */
1083 if ((self->window > 1) && (nextfit)) {
1084 /* More packet to send in current window */
1085 irlap_send_data_primary(self, skb);
1086 irlap_next_state(self, LAP_XMIT_P);
1087 } else {
1088 /* Final packet of window */
1089 irlap_send_data_primary_poll(self, skb);
1090 irlap_next_state(self, LAP_NRM_P);
1091
1092 /*
1093 * Make sure state machine does not try to send
1094 * any more frames
1095 */
1096 ret = -EPROTO;
1097 }
1098#ifdef CONFIG_IRDA_FAST_RR
1099 /* Peer may want to reply immediately */
1100 self->fast_RR = FALSE;
1101#endif /* CONFIG_IRDA_FAST_RR */
1102 } else {
1103 IRDA_DEBUG(4, "%s(), Unable to send! remote busy?\n",
1104 __FUNCTION__);
1105 skb_queue_head(&self->txq, skb_get(skb));
1106
1107 /*
1108 * The next ret is important, because it tells
1109 * irlap_next_state _not_ to deliver more frames
1110 */
1111 ret = -EPROTO;
1112 }
1113 break;
1114 case POLL_TIMER_EXPIRED:
1115 IRDA_DEBUG(3, "%s(), POLL_TIMER_EXPIRED <%ld>\n",
1116 __FUNCTION__, jiffies);
1117 irlap_send_rr_frame(self, CMD_FRAME);
1118 /* Return to NRM properly - Jean II */
1119 self->window = self->window_size;
1120#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
1121 /* Allowed to transmit a maximum number of bytes again. */
1122 self->bytes_left = self->line_capacity;
1123#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
1124 irlap_start_final_timer(self, self->final_timeout);
1125 irlap_next_state(self, LAP_NRM_P);
1126 break;
1127 case DISCONNECT_REQUEST:
1128 del_timer(&self->poll_timer);
1129 irlap_wait_min_turn_around(self, &self->qos_tx);
1130 irlap_send_disc_frame(self);
1131 irlap_flush_all_queues(self);
1132 irlap_start_final_timer(self, self->final_timeout);
1133 self->retry_count = 0;
1134 irlap_next_state(self, LAP_PCLOSE);
1135 break;
1136 case DATA_REQUEST:
1137 /* Nothing to do, irlap_do_event() will send the packet
1138 * when we return... - Jean II */
1139 break;
1140 default:
1141 IRDA_DEBUG(0, "%s(), Unknown event %s\n",
1142 __FUNCTION__, irlap_event[event]);
1143
1144 ret = -EINVAL;
1145 break;
1146 }
1147 return ret;
1148}
1149
1150/*
1151 * Function irlap_state_pclose (event, skb, info)
1152 *
1153 * PCLOSE state
1154 */
1155static int irlap_state_pclose(struct irlap_cb *self, IRLAP_EVENT event,
1156 struct sk_buff *skb, struct irlap_info *info)
1157{
1158 int ret = 0;
1159
1160 IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
1161
1162 IRDA_ASSERT(self != NULL, return -1;);
1163 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
1164
1165 switch (event) {
1166 case RECV_UA_RSP: /* FALLTHROUGH */
1167 case RECV_DM_RSP:
1168 del_timer(&self->final_timer);
1169
1170 /* Set new link parameters */
1171 irlap_apply_default_connection_parameters(self);
1172
1173 /* Always switch state before calling upper layers */
1174 irlap_next_state(self, LAP_NDM);
1175
1176 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
1177 break;
1178 case FINAL_TIMER_EXPIRED:
1179 if (self->retry_count < self->N3) {
1180 irlap_wait_min_turn_around(self, &self->qos_tx);
1181 irlap_send_disc_frame(self);
1182 irlap_start_final_timer(self, self->final_timeout);
1183 self->retry_count++;
1184 /* Keep state */
1185 } else {
1186 irlap_apply_default_connection_parameters(self);
1187
1188 /* Always switch state before calling upper layers */
1189 irlap_next_state(self, LAP_NDM);
1190
1191 irlap_disconnect_indication(self, LAP_NO_RESPONSE);
1192 }
1193 break;
1194 default:
1195 IRDA_DEBUG(1, "%s(), Unknown event %d\n", __FUNCTION__, event);
1196
1197 ret = -1;
1198 break;
1199 }
1200 return ret;
1201}
1202
1203/*
1204 * Function irlap_state_nrm_p (self, event, skb, info)
1205 *
1206 * NRM_P (Normal Response Mode as Primary), The primary station has given
1207 * permissions to a secondary station to transmit IrLAP resonse frames
1208 * (by sending a frame with the P bit set). The primary station will not
1209 * transmit any frames and is expecting to receive frames only from the
1210 * secondary to which transmission permissions has been given.
1211 */
1212static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
1213 struct sk_buff *skb, struct irlap_info *info)
1214{
1215 int ret = 0;
1216 int ns_status;
1217 int nr_status;
1218
1219 switch (event) {
1220 case RECV_I_RSP: /* Optimize for the common case */
1221 /* FIXME: must check for remote_busy below */
1222#ifdef CONFIG_IRDA_FAST_RR
1223 /*
1224 * Reset the fast_RR so we can use the fast RR code with
1225 * full speed the next time since peer may have more frames
1226 * to transmitt
1227 */
1228 self->fast_RR = FALSE;
1229#endif /* CONFIG_IRDA_FAST_RR */
1230 IRDA_ASSERT( info != NULL, return -1;);
1231
1232 ns_status = irlap_validate_ns_received(self, info->ns);
1233 nr_status = irlap_validate_nr_received(self, info->nr);
1234
1235 /*
1236 * Check for expected I(nformation) frame
1237 */
1238 if ((ns_status == NS_EXPECTED) && (nr_status == NR_EXPECTED)) {
1239
1240 /* Update Vr (next frame for us to receive) */
1241 self->vr = (self->vr + 1) % 8;
1242
1243 /* Update Nr received, cleanup our retry queue */
1244 irlap_update_nr_received(self, info->nr);
1245
1246 /*
1247 * Got expected NR, so reset the
1248 * retry_count. This is not done by IrLAP spec,
1249 * which is strange!
1250 */
1251 self->retry_count = 0;
1252 self->ack_required = TRUE;
1253
1254 /* poll bit cleared? */
1255 if (!info->pf) {
1256 /* Keep state, do not move this line */
1257 irlap_next_state(self, LAP_NRM_P);
1258
1259 irlap_data_indication(self, skb, FALSE);
1260 } else {
1261 /* No longer waiting for pf */
1262 del_timer(&self->final_timer);
1263
1264 irlap_wait_min_turn_around(self, &self->qos_tx);
1265
1266 /* Call higher layer *before* changing state
1267 * to give them a chance to send data in the
1268 * next LAP frame.
1269 * Jean II */
1270 irlap_data_indication(self, skb, FALSE);
1271
1272 /* XMIT states are the most dangerous state
1273 * to be in, because user requests are
1274 * processed directly and may change state.
1275 * On the other hand, in NDM_P, those
1276 * requests are queued and we will process
1277 * them when we return to irlap_do_event().
1278 * Jean II
1279 */
1280 irlap_next_state(self, LAP_XMIT_P);
1281
1282 /* This is the last frame.
1283 * Make sure it's always called in XMIT state.
1284 * - Jean II */
1285 irlap_start_poll_timer(self, self->poll_timeout);
1286 }
1287 break;
1288
1289 }
1290 /* Unexpected next to send (Ns) */
1291 if ((ns_status == NS_UNEXPECTED) && (nr_status == NR_EXPECTED))
1292 {
1293 if (!info->pf) {
1294 irlap_update_nr_received(self, info->nr);
1295
1296 /*
1297 * Wait until the last frame before doing
1298 * anything
1299 */
1300
1301 /* Keep state */
1302 irlap_next_state(self, LAP_NRM_P);
1303 } else {
1304 IRDA_DEBUG(4,
1305 "%s(), missing or duplicate frame!\n",
1306 __FUNCTION__);
1307
1308 /* Update Nr received */
1309 irlap_update_nr_received(self, info->nr);
1310
1311 irlap_wait_min_turn_around(self, &self->qos_tx);
1312 irlap_send_rr_frame(self, CMD_FRAME);
1313
1314 self->ack_required = FALSE;
1315
1316 irlap_start_final_timer(self, self->final_timeout);
1317 irlap_next_state(self, LAP_NRM_P);
1318 }
1319 break;
1320 }
1321 /*
1322 * Unexpected next to receive (Nr)
1323 */
1324 if ((ns_status == NS_EXPECTED) && (nr_status == NR_UNEXPECTED))
1325 {
1326 if (info->pf) {
1327 self->vr = (self->vr + 1) % 8;
1328
1329 /* Update Nr received */
1330 irlap_update_nr_received(self, info->nr);
1331
1332 /* Resend rejected frames */
1333 irlap_resend_rejected_frames(self, CMD_FRAME);
1334
1335 self->ack_required = FALSE;
1336
1337 /* Make sure we account for the time
1338 * to transmit our frames. See comemnts
1339 * in irlap_send_data_primary_poll().
1340 * Jean II */
1341 irlap_start_final_timer(self, 2 * self->final_timeout);
1342
1343 /* Keep state, do not move this line */
1344 irlap_next_state(self, LAP_NRM_P);
1345
1346 irlap_data_indication(self, skb, FALSE);
1347 } else {
1348 /*
1349 * Do not resend frames until the last
1350 * frame has arrived from the other
1351 * device. This is not documented in
1352 * IrLAP!!
1353 */
1354 self->vr = (self->vr + 1) % 8;
1355
1356 /* Update Nr received */
1357 irlap_update_nr_received(self, info->nr);
1358
1359 self->ack_required = FALSE;
1360
1361 /* Keep state, do not move this line!*/
1362 irlap_next_state(self, LAP_NRM_P);
1363
1364 irlap_data_indication(self, skb, FALSE);
1365 }
1366 break;
1367 }
1368 /*
1369 * Unexpected next to send (Ns) and next to receive (Nr)
1370 * Not documented by IrLAP!
1371 */
1372 if ((ns_status == NS_UNEXPECTED) &&
1373 (nr_status == NR_UNEXPECTED))
1374 {
1375 IRDA_DEBUG(4, "%s(), unexpected nr and ns!\n",
1376 __FUNCTION__);
1377 if (info->pf) {
1378 /* Resend rejected frames */
1379 irlap_resend_rejected_frames(self, CMD_FRAME);
1380
1381 /* Give peer some time to retransmit!
1382 * But account for our own Tx. */
1383 irlap_start_final_timer(self, 2 * self->final_timeout);
1384
1385 /* Keep state, do not move this line */
1386 irlap_next_state(self, LAP_NRM_P);
1387 } else {
1388 /* Update Nr received */
1389 /* irlap_update_nr_received( info->nr); */
1390
1391 self->ack_required = FALSE;
1392 }
1393 break;
1394 }
1395
1396 /*
1397 * Invalid NR or NS
1398 */
1399 if ((nr_status == NR_INVALID) || (ns_status == NS_INVALID)) {
1400 if (info->pf) {
1401 del_timer(&self->final_timer);
1402
1403 irlap_next_state(self, LAP_RESET_WAIT);
1404
1405 irlap_disconnect_indication(self, LAP_RESET_INDICATION);
1406 self->xmitflag = TRUE;
1407 } else {
1408 del_timer(&self->final_timer);
1409
1410 irlap_disconnect_indication(self, LAP_RESET_INDICATION);
1411
1412 self->xmitflag = FALSE;
1413 }
1414 break;
1415 }
1416 IRDA_DEBUG(1, "%s(), Not implemented!\n", __FUNCTION__);
1417 IRDA_DEBUG(1, "%s(), event=%s, ns_status=%d, nr_status=%d\n",
1418 __FUNCTION__, irlap_event[event], ns_status, nr_status);
1419 break;
1420 case RECV_UI_FRAME:
1421 /* Poll bit cleared? */
1422 if (!info->pf) {
1423 irlap_data_indication(self, skb, TRUE);
1424 irlap_next_state(self, LAP_NRM_P);
1425 } else {
1426 del_timer(&self->final_timer);
1427 irlap_data_indication(self, skb, TRUE);
1428 irlap_next_state(self, LAP_XMIT_P);
1429 IRDA_DEBUG(1, "%s: RECV_UI_FRAME: next state %s\n", __FUNCTION__, irlap_state[self->state]);
1430 irlap_start_poll_timer(self, self->poll_timeout);
1431 }
1432 break;
1433 case RECV_RR_RSP:
1434 /*
1435 * If you get a RR, the remote isn't busy anymore,
1436 * no matter what the NR
1437 */
1438 self->remote_busy = FALSE;
1439
1440 /*
1441 * Nr as expected?
1442 */
1443 ret = irlap_validate_nr_received(self, info->nr);
1444 if (ret == NR_EXPECTED) {
1445 /* Stop final timer */
1446 del_timer(&self->final_timer);
1447
1448 /* Update Nr received */
1449 irlap_update_nr_received(self, info->nr);
1450
1451 /*
1452 * Got expected NR, so reset the retry_count. This
1453 * is not done by the IrLAP standard , which is
1454 * strange! DB.
1455 */
1456 self->retry_count = 0;
1457 irlap_wait_min_turn_around(self, &self->qos_tx);
1458
1459 irlap_next_state(self, LAP_XMIT_P);
1460
1461 /* Start poll timer */
1462 irlap_start_poll_timer(self, self->poll_timeout);
1463 } else if (ret == NR_UNEXPECTED) {
1464 IRDA_ASSERT(info != NULL, return -1;);
1465 /*
1466 * Unexpected nr!
1467 */
1468
1469 /* Update Nr received */
1470 irlap_update_nr_received(self, info->nr);
1471
1472 IRDA_DEBUG(4, "RECV_RR_FRAME: Retrans:%d, nr=%d, va=%d, "
1473 "vs=%d, vr=%d\n",
1474 self->retry_count, info->nr, self->va,
1475 self->vs, self->vr);
1476
1477 /* Resend rejected frames */
1478 irlap_resend_rejected_frames(self, CMD_FRAME);
1479
1480 /* Final timer ??? Jean II */
1481
1482 irlap_next_state(self, LAP_NRM_P);
1483 } else if (ret == NR_INVALID) {
1484 IRDA_DEBUG(1, "%s(), Received RR with "
1485 "invalid nr !\n", __FUNCTION__);
1486 del_timer(&self->final_timer);
1487
1488 irlap_next_state(self, LAP_RESET_WAIT);
1489
1490 irlap_disconnect_indication(self, LAP_RESET_INDICATION);
1491 self->xmitflag = TRUE;
1492 }
1493 break;
1494 case RECV_RNR_RSP:
1495 IRDA_ASSERT(info != NULL, return -1;);
1496
1497 /* Stop final timer */
1498 del_timer(&self->final_timer);
1499 self->remote_busy = TRUE;
1500
1501 /* Update Nr received */
1502 irlap_update_nr_received(self, info->nr);
1503 irlap_next_state(self, LAP_XMIT_P);
1504
1505 /* Start poll timer */
1506 irlap_start_poll_timer(self, self->poll_timeout);
1507 break;
1508 case RECV_FRMR_RSP:
1509 del_timer(&self->final_timer);
1510 self->xmitflag = TRUE;
1511 irlap_next_state(self, LAP_RESET_WAIT);
1512 irlap_reset_indication(self);
1513 break;
1514 case FINAL_TIMER_EXPIRED:
1515 /*
1516 * We are allowed to wait for additional 300 ms if
1517 * final timer expires when we are in the middle
1518 * of receiving a frame (page 45, IrLAP). Check that
1519 * we only do this once for each frame.
1520 */
1521 if (irda_device_is_receiving(self->netdev) && !self->add_wait) {
1522 IRDA_DEBUG(1, "FINAL_TIMER_EXPIRED when receiving a "
1523 "frame! Waiting a little bit more!\n");
1524 irlap_start_final_timer(self, msecs_to_jiffies(300));
1525
1526 /*
1527 * Don't allow this to happen one more time in a row,
1528 * or else we can get a pretty tight loop here if
1529 * if we only receive half a frame. DB.
1530 */
1531 self->add_wait = TRUE;
1532 break;
1533 }
1534 self->add_wait = FALSE;
1535
1536 /* N2 is the disconnect timer. Until we reach it, we retry */
1537 if (self->retry_count < self->N2) {
1538 /* Retry sending the pf bit to the secondary */
1539 irlap_wait_min_turn_around(self, &self->qos_tx);
1540 irlap_send_rr_frame(self, CMD_FRAME);
1541
1542 irlap_start_final_timer(self, self->final_timeout);
1543 self->retry_count++;
1544 IRDA_DEBUG(4, "irlap_state_nrm_p: FINAL_TIMER_EXPIRED:"
1545 " retry_count=%d\n", self->retry_count);
1546
1547 /* Early warning event. I'm using a pretty liberal
1548 * interpretation of the spec and generate an event
1549 * every time the timer is multiple of N1 (and not
1550 * only the first time). This allow application
1551 * to know precisely if connectivity restart...
1552 * Jean II */
1553 if((self->retry_count % self->N1) == 0)
1554 irlap_status_indication(self,
1555 STATUS_NO_ACTIVITY);
1556
1557 /* Keep state */
1558 } else {
1559 irlap_apply_default_connection_parameters(self);
1560
1561 /* Always switch state before calling upper layers */
1562 irlap_next_state(self, LAP_NDM);
1563 irlap_disconnect_indication(self, LAP_NO_RESPONSE);
1564 }
1565 break;
1566 case RECV_REJ_RSP:
1567 irlap_update_nr_received(self, info->nr);
1568 if (self->remote_busy) {
1569 irlap_wait_min_turn_around(self, &self->qos_tx);
1570 irlap_send_rr_frame(self, CMD_FRAME);
1571 } else
1572 irlap_resend_rejected_frames(self, CMD_FRAME);
1573 irlap_start_final_timer(self, 2 * self->final_timeout);
1574 break;
1575 case RECV_SREJ_RSP:
1576 irlap_update_nr_received(self, info->nr);
1577 if (self->remote_busy) {
1578 irlap_wait_min_turn_around(self, &self->qos_tx);
1579 irlap_send_rr_frame(self, CMD_FRAME);
1580 } else
1581 irlap_resend_rejected_frame(self, CMD_FRAME);
1582 irlap_start_final_timer(self, 2 * self->final_timeout);
1583 break;
1584 case RECV_RD_RSP:
1585 IRDA_DEBUG(1, "%s(), RECV_RD_RSP\n", __FUNCTION__);
1586
1587 irlap_flush_all_queues(self);
1588 irlap_next_state(self, LAP_XMIT_P);
1589 /* Call back the LAP state machine to do a proper disconnect */
1590 irlap_disconnect_request(self);
1591 break;
1592 default:
1593 IRDA_DEBUG(1, "%s(), Unknown event %s\n",
1594 __FUNCTION__, irlap_event[event]);
1595
1596 ret = -1;
1597 break;
1598 }
1599 return ret;
1600}
1601
1602/*
1603 * Function irlap_state_reset_wait (event, skb, info)
1604 *
1605 * We have informed the service user of a reset condition, and is
1606 * awaiting reset of disconnect request.
1607 *
1608 */
1609static int irlap_state_reset_wait(struct irlap_cb *self, IRLAP_EVENT event,
1610 struct sk_buff *skb, struct irlap_info *info)
1611{
1612 int ret = 0;
1613
1614 IRDA_DEBUG(3, "%s(), event = %s\n", __FUNCTION__, irlap_event[event]);
1615
1616 IRDA_ASSERT(self != NULL, return -1;);
1617 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
1618
1619 switch (event) {
1620 case RESET_REQUEST:
1621 if (self->xmitflag) {
1622 irlap_wait_min_turn_around(self, &self->qos_tx);
1623 irlap_send_snrm_frame(self, NULL);
1624 irlap_start_final_timer(self, self->final_timeout);
1625 irlap_next_state(self, LAP_RESET);
1626 } else {
1627 irlap_start_final_timer(self, self->final_timeout);
1628 irlap_next_state(self, LAP_RESET);
1629 }
1630 break;
1631 case DISCONNECT_REQUEST:
1632 irlap_wait_min_turn_around( self, &self->qos_tx);
1633 irlap_send_disc_frame( self);
1634 irlap_flush_all_queues( self);
1635 irlap_start_final_timer( self, self->final_timeout);
1636 self->retry_count = 0;
1637 irlap_next_state( self, LAP_PCLOSE);
1638 break;
1639 default:
1640 IRDA_DEBUG(2, "%s(), Unknown event %s\n", __FUNCTION__,
1641 irlap_event[event]);
1642
1643 ret = -1;
1644 break;
1645 }
1646 return ret;
1647}
1648
1649/*
1650 * Function irlap_state_reset (self, event, skb, info)
1651 *
1652 * We have sent a SNRM reset command to the peer layer, and is awaiting
1653 * reply.
1654 *
1655 */
1656static int irlap_state_reset(struct irlap_cb *self, IRLAP_EVENT event,
1657 struct sk_buff *skb, struct irlap_info *info)
1658{
1659 int ret = 0;
1660
1661 IRDA_DEBUG(3, "%s(), event = %s\n", __FUNCTION__, irlap_event[event]);
1662
1663 IRDA_ASSERT(self != NULL, return -1;);
1664 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
1665
1666 switch (event) {
1667 case RECV_DISC_CMD:
1668 del_timer(&self->final_timer);
1669
1670 irlap_apply_default_connection_parameters(self);
1671
1672 /* Always switch state before calling upper layers */
1673 irlap_next_state(self, LAP_NDM);
1674
1675 irlap_disconnect_indication(self, LAP_NO_RESPONSE);
1676
1677 break;
1678 case RECV_UA_RSP:
1679 del_timer(&self->final_timer);
1680
1681 /* Initiate connection state */
1682 irlap_initiate_connection_state(self);
1683
1684 irlap_reset_confirm();
1685
1686 self->remote_busy = FALSE;
1687
1688 irlap_next_state(self, LAP_XMIT_P);
1689
1690 irlap_start_poll_timer(self, self->poll_timeout);
1691
1692 break;
1693 case FINAL_TIMER_EXPIRED:
1694 if (self->retry_count < 3) {
1695 irlap_wait_min_turn_around(self, &self->qos_tx);
1696
1697 IRDA_ASSERT(self->netdev != NULL, return -1;);
1698 irlap_send_snrm_frame(self, self->qos_dev);
1699
1700 self->retry_count++; /* Experimental!! */
1701
1702 irlap_start_final_timer(self, self->final_timeout);
1703 irlap_next_state(self, LAP_RESET);
1704 } else if (self->retry_count >= self->N3) {
1705 irlap_apply_default_connection_parameters(self);
1706
1707 /* Always switch state before calling upper layers */
1708 irlap_next_state(self, LAP_NDM);
1709
1710 irlap_disconnect_indication(self, LAP_NO_RESPONSE);
1711 }
1712 break;
1713 case RECV_SNRM_CMD:
1714 /*
1715 * SNRM frame is not allowed to contain an I-field in this
1716 * state
1717 */
1718 if (!info) {
1719 IRDA_DEBUG(3, "%s(), RECV_SNRM_CMD\n", __FUNCTION__);
1720 irlap_initiate_connection_state(self);
1721 irlap_wait_min_turn_around(self, &self->qos_tx);
1722 irlap_send_ua_response_frame(self, &self->qos_rx);
1723 irlap_reset_confirm();
1724 irlap_start_wd_timer(self, self->wd_timeout);
1725 irlap_next_state(self, LAP_NDM);
1726 } else {
1727 IRDA_DEBUG(0,
1728 "%s(), SNRM frame contained an I field!\n",
1729 __FUNCTION__);
1730 }
1731 break;
1732 default:
1733 IRDA_DEBUG(1, "%s(), Unknown event %s\n",
1734 __FUNCTION__, irlap_event[event]);
1735
1736 ret = -1;
1737 break;
1738 }
1739 return ret;
1740}
1741
1742/*
1743 * Function irlap_state_xmit_s (event, skb, info)
1744 *
1745 * XMIT_S, The secondary station has been given the right to transmit,
1746 * and we therefor do not expect to receive any transmissions from other
1747 * stations.
1748 */
1749static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event,
1750 struct sk_buff *skb, struct irlap_info *info)
1751{
1752 int ret = 0;
1753
1754 IRDA_DEBUG(4, "%s(), event=%s\n", __FUNCTION__, irlap_event[event]);
1755
1756 IRDA_ASSERT(self != NULL, return -ENODEV;);
1757 IRDA_ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
1758
1759 switch (event) {
1760 case SEND_I_CMD:
1761 /*
1762 * Send frame only if send window > 0
1763 */
1764 if ((self->window > 0) && (!self->remote_busy)) {
1765 int nextfit;
1766#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
1767 struct sk_buff *skb_next;
1768
1769 /*
1770 * Same deal as in irlap_state_xmit_p(), so see
1771 * the comments at that point.
1772 * We are the secondary, so there are only subtle
1773 * differences. - Jean II
1774 */
1775
1776 /* Check if a subsequent skb exist and would fit in
1777 * the current window (with respect to turnaround
1778 * time). - Jean II */
1779 skb_next = skb_peek(&self->txq);
1780 nextfit = ((skb_next != NULL) &&
1781 ((skb_next->len + skb->len) <=
1782 self->bytes_left));
1783
1784 /*
1785 * Test if we have transmitted more bytes over the
1786 * link than its possible to do with the current
1787 * speed and turn-around-time.
1788 */
1789 if((!nextfit) && (skb->len > self->bytes_left)) {
1790 IRDA_DEBUG(0, "%s(), Not allowed to transmit"
1791 " more bytes!\n", __FUNCTION__);
1792 /* Requeue the skb */
1793 skb_queue_head(&self->txq, skb_get(skb));
1794
1795 /*
1796 * Switch to NRM_S, this is only possible
1797 * when we are in secondary mode, since we
1798 * must be sure that we don't miss any RR
1799 * frames
1800 */
1801 self->window = self->window_size;
1802 self->bytes_left = self->line_capacity;
1803 irlap_start_wd_timer(self, self->wd_timeout);
1804
1805 irlap_next_state(self, LAP_NRM_S);
1806 /* Slight difference with primary :
1807 * here we would wait for the other side to
1808 * expire the turnaround. - Jean II */
1809
1810 return -EPROTO; /* Try again later */
1811 }
1812 /* Substract space used by this skb */
1813 self->bytes_left -= skb->len;
1814#else /* CONFIG_IRDA_DYNAMIC_WINDOW */
1815 /* Window has been adjusted for the max packet
1816 * size, so much simpler... - Jean II */
1817 nextfit = (skb_queue_len(&self->txq) > 0);
1818#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
1819 /*
1820 * Send data with final bit cleared only if window > 1
1821 * and there is more frames to be sent
1822 */
1823 if ((self->window > 1) && (nextfit)) {
1824 irlap_send_data_secondary(self, skb);
1825 irlap_next_state(self, LAP_XMIT_S);
1826 } else {
1827 irlap_send_data_secondary_final(self, skb);
1828 irlap_next_state(self, LAP_NRM_S);
1829
1830 /*
1831 * Make sure state machine does not try to send
1832 * any more frames
1833 */
1834 ret = -EPROTO;
1835 }
1836 } else {
1837 IRDA_DEBUG(2, "%s(), Unable to send!\n", __FUNCTION__);
1838 skb_queue_head(&self->txq, skb_get(skb));
1839 ret = -EPROTO;
1840 }
1841 break;
1842 case DISCONNECT_REQUEST:
1843 irlap_send_rd_frame(self);
1844 irlap_flush_all_queues(self);
1845 irlap_start_wd_timer(self, self->wd_timeout);
1846 irlap_next_state(self, LAP_SCLOSE);
1847 break;
1848 case DATA_REQUEST:
1849 /* Nothing to do, irlap_do_event() will send the packet
1850 * when we return... - Jean II */
1851 break;
1852 default:
1853 IRDA_DEBUG(2, "%s(), Unknown event %s\n", __FUNCTION__,
1854 irlap_event[event]);
1855
1856 ret = -EINVAL;
1857 break;
1858 }
1859 return ret;
1860}
1861
1862/*
1863 * Function irlap_state_nrm_s (event, skb, info)
1864 *
1865 * NRM_S (Normal Response Mode as Secondary) state, in this state we are
1866 * expecting to receive frames from the primary station
1867 *
1868 */
1869static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event,
1870 struct sk_buff *skb, struct irlap_info *info)
1871{
1872 int ns_status;
1873 int nr_status;
1874 int ret = 0;
1875
1876 IRDA_DEBUG(4, "%s(), event=%s\n", __FUNCTION__, irlap_event[ event]);
1877
1878 IRDA_ASSERT(self != NULL, return -1;);
1879 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
1880
1881 switch (event) {
1882 case RECV_I_CMD: /* Optimize for the common case */
1883 /* FIXME: must check for remote_busy below */
1884 IRDA_DEBUG(4, "%s(), event=%s nr=%d, vs=%d, ns=%d, "
1885 "vr=%d, pf=%d\n", __FUNCTION__,
1886 irlap_event[event], info->nr,
1887 self->vs, info->ns, self->vr, info->pf);
1888
1889 self->retry_count = 0;
1890
1891 ns_status = irlap_validate_ns_received(self, info->ns);
1892 nr_status = irlap_validate_nr_received(self, info->nr);
1893 /*
1894 * Check for expected I(nformation) frame
1895 */
1896 if ((ns_status == NS_EXPECTED) && (nr_status == NR_EXPECTED)) {
1897
1898 /* Update Vr (next frame for us to receive) */
1899 self->vr = (self->vr + 1) % 8;
1900
1901 /* Update Nr received */
1902 irlap_update_nr_received(self, info->nr);
1903
1904 /*
1905 * poll bit cleared?
1906 */
1907 if (!info->pf) {
1908
1909 self->ack_required = TRUE;
1910
1911 /*
1912 * Starting WD-timer here is optional, but
1913 * not recommended. Note 6 IrLAP p. 83
1914 */
1915#if 0
1916 irda_start_timer(WD_TIMER, self->wd_timeout);
1917#endif
1918 /* Keep state, do not move this line */
1919 irlap_next_state(self, LAP_NRM_S);
1920
1921 irlap_data_indication(self, skb, FALSE);
1922 break;
1923 } else {
1924 /*
1925 * We should wait before sending RR, and
1926 * also before changing to XMIT_S
1927 * state. (note 1, IrLAP p. 82)
1928 */
1929 irlap_wait_min_turn_around(self, &self->qos_tx);
1930
1931 /*
1932 * Give higher layers a chance to
1933 * immediately reply with some data before
1934 * we decide if we should send a RR frame
1935 * or not
1936 */
1937 irlap_data_indication(self, skb, FALSE);
1938
1939 /* Any pending data requests? */
1940 if ((skb_queue_len(&self->txq) > 0) &&
1941 (self->window > 0))
1942 {
1943 self->ack_required = TRUE;
1944
1945 del_timer(&self->wd_timer);
1946
1947 irlap_next_state(self, LAP_XMIT_S);
1948 } else {
1949 irlap_send_rr_frame(self, RSP_FRAME);
1950 irlap_start_wd_timer(self,
1951 self->wd_timeout);
1952
1953 /* Keep the state */
1954 irlap_next_state(self, LAP_NRM_S);
1955 }
1956 break;
1957 }
1958 }
1959 /*
1960 * Check for Unexpected next to send (Ns)
1961 */
1962 if ((ns_status == NS_UNEXPECTED) && (nr_status == NR_EXPECTED))
1963 {
1964 /* Unexpected next to send, with final bit cleared */
1965 if (!info->pf) {
1966 irlap_update_nr_received(self, info->nr);
1967
1968 irlap_start_wd_timer(self, self->wd_timeout);
1969 } else {
1970 /* Update Nr received */
1971 irlap_update_nr_received(self, info->nr);
1972
1973 irlap_wait_min_turn_around(self, &self->qos_tx);
1974 irlap_send_rr_frame(self, RSP_FRAME);
1975
1976 irlap_start_wd_timer(self, self->wd_timeout);
1977 }
1978 break;
1979 }
1980
1981 /*
1982 * Unexpected Next to Receive(NR) ?
1983 */
1984 if ((ns_status == NS_EXPECTED) && (nr_status == NR_UNEXPECTED))
1985 {
1986 if (info->pf) {
1987 IRDA_DEBUG(4, "RECV_I_RSP: frame(s) lost\n");
1988
1989 self->vr = (self->vr + 1) % 8;
1990
1991 /* Update Nr received */
1992 irlap_update_nr_received(self, info->nr);
1993
1994 /* Resend rejected frames */
1995 irlap_resend_rejected_frames(self, RSP_FRAME);
1996
1997 /* Keep state, do not move this line */
1998 irlap_next_state(self, LAP_NRM_S);
1999
2000 irlap_data_indication(self, skb, FALSE);
2001 irlap_start_wd_timer(self, self->wd_timeout);
2002 break;
2003 }
2004 /*
2005 * This is not documented in IrLAP!! Unexpected NR
2006 * with poll bit cleared
2007 */
2008 if (!info->pf) {
2009 self->vr = (self->vr + 1) % 8;
2010
2011 /* Update Nr received */
2012 irlap_update_nr_received(self, info->nr);
2013
2014 /* Keep state, do not move this line */
2015 irlap_next_state(self, LAP_NRM_S);
2016
2017 irlap_data_indication(self, skb, FALSE);
2018 irlap_start_wd_timer(self, self->wd_timeout);
2019 }
2020 break;
2021 }
2022
2023 if (ret == NR_INVALID) {
2024 IRDA_DEBUG(0, "NRM_S, NR_INVALID not implemented!\n");
2025 }
2026 if (ret == NS_INVALID) {
2027 IRDA_DEBUG(0, "NRM_S, NS_INVALID not implemented!\n");
2028 }
2029 break;
2030 case RECV_UI_FRAME:
2031 /*
2032 * poll bit cleared?
2033 */
2034 if (!info->pf) {
2035 irlap_data_indication(self, skb, TRUE);
2036 irlap_next_state(self, LAP_NRM_S); /* Keep state */
2037 } else {
2038 /*
2039 * Any pending data requests?
2040 */
2041 if ((skb_queue_len(&self->txq) > 0) &&
2042 (self->window > 0) && !self->remote_busy)
2043 {
2044 irlap_data_indication(self, skb, TRUE);
2045
2046 del_timer(&self->wd_timer);
2047
2048 irlap_next_state(self, LAP_XMIT_S);
2049 } else {
2050 irlap_data_indication(self, skb, TRUE);
2051
2052 irlap_wait_min_turn_around(self, &self->qos_tx);
2053
2054 irlap_send_rr_frame(self, RSP_FRAME);
2055 self->ack_required = FALSE;
2056
2057 irlap_start_wd_timer(self, self->wd_timeout);
2058
2059 /* Keep the state */
2060 irlap_next_state(self, LAP_NRM_S);
2061 }
2062 }
2063 break;
2064 case RECV_RR_CMD:
2065 self->retry_count = 0;
2066
2067 /*
2068 * Nr as expected?
2069 */
2070 nr_status = irlap_validate_nr_received(self, info->nr);
2071 if (nr_status == NR_EXPECTED) {
2072 if ((skb_queue_len( &self->txq) > 0) &&
2073 (self->window > 0)) {
2074 self->remote_busy = FALSE;
2075
2076 /* Update Nr received */
2077 irlap_update_nr_received(self, info->nr);
2078 del_timer(&self->wd_timer);
2079
2080 irlap_wait_min_turn_around(self, &self->qos_tx);
2081 irlap_next_state(self, LAP_XMIT_S);
2082 } else {
2083 self->remote_busy = FALSE;
2084 /* Update Nr received */
2085 irlap_update_nr_received(self, info->nr);
2086 irlap_wait_min_turn_around(self, &self->qos_tx);
2087 irlap_start_wd_timer(self, self->wd_timeout);
2088
2089 /* Note : if the link is idle (this case),
2090 * we never go in XMIT_S, so we never get a
2091 * chance to process any DISCONNECT_REQUEST.
2092 * Do it now ! - Jean II */
2093 if (self->disconnect_pending) {
2094 /* Disconnect */
2095 irlap_send_rd_frame(self);
2096 irlap_flush_all_queues(self);
2097
2098 irlap_next_state(self, LAP_SCLOSE);
2099 } else {
2100 /* Just send back pf bit */
2101 irlap_send_rr_frame(self, RSP_FRAME);
2102
2103 irlap_next_state(self, LAP_NRM_S);
2104 }
2105 }
2106 } else if (nr_status == NR_UNEXPECTED) {
2107 self->remote_busy = FALSE;
2108 irlap_update_nr_received(self, info->nr);
2109 irlap_resend_rejected_frames(self, RSP_FRAME);
2110
2111 irlap_start_wd_timer(self, self->wd_timeout);
2112
2113 /* Keep state */
2114 irlap_next_state(self, LAP_NRM_S);
2115 } else {
2116 IRDA_DEBUG(1, "%s(), invalid nr not implemented!\n",
2117 __FUNCTION__);
2118 }
2119 break;
2120 case RECV_SNRM_CMD:
2121 /* SNRM frame is not allowed to contain an I-field */
2122 if (!info) {
2123 del_timer(&self->wd_timer);
2124 IRDA_DEBUG(1, "%s(), received SNRM cmd\n", __FUNCTION__);
2125 irlap_next_state(self, LAP_RESET_CHECK);
2126
2127 irlap_reset_indication(self);
2128 } else {
2129 IRDA_DEBUG(0,
2130 "%s(), SNRM frame contained an I-field!\n",
2131 __FUNCTION__);
2132
2133 }
2134 break;
2135 case RECV_REJ_CMD:
2136 irlap_update_nr_received(self, info->nr);
2137 if (self->remote_busy) {
2138 irlap_wait_min_turn_around(self, &self->qos_tx);
2139 irlap_send_rr_frame(self, RSP_FRAME);
2140 } else
2141 irlap_resend_rejected_frames(self, RSP_FRAME);
2142 irlap_start_wd_timer(self, self->wd_timeout);
2143 break;
2144 case RECV_SREJ_CMD:
2145 irlap_update_nr_received(self, info->nr);
2146 if (self->remote_busy) {
2147 irlap_wait_min_turn_around(self, &self->qos_tx);
2148 irlap_send_rr_frame(self, RSP_FRAME);
2149 } else
2150 irlap_resend_rejected_frame(self, RSP_FRAME);
2151 irlap_start_wd_timer(self, self->wd_timeout);
2152 break;
2153 case WD_TIMER_EXPIRED:
2154 /*
2155 * Wait until retry_count * n matches negotiated threshold/
2156 * disconnect time (note 2 in IrLAP p. 82)
2157 *
2158 * Similar to irlap_state_nrm_p() -> FINAL_TIMER_EXPIRED
2159 * Note : self->wd_timeout = (self->final_timeout * 2),
2160 * which explain why we use (self->N2 / 2) here !!!
2161 * Jean II
2162 */
2163 IRDA_DEBUG(1, "%s(), retry_count = %d\n", __FUNCTION__,
2164 self->retry_count);
2165
2166 if (self->retry_count < (self->N2 / 2)) {
2167 /* No retry, just wait for primary */
2168 irlap_start_wd_timer(self, self->wd_timeout);
2169 self->retry_count++;
2170
2171 if((self->retry_count % (self->N1 / 2)) == 0)
2172 irlap_status_indication(self,
2173 STATUS_NO_ACTIVITY);
2174 } else {
2175 irlap_apply_default_connection_parameters(self);
2176
2177 /* Always switch state before calling upper layers */
2178 irlap_next_state(self, LAP_NDM);
2179 irlap_disconnect_indication(self, LAP_NO_RESPONSE);
2180 }
2181 break;
2182 case RECV_DISC_CMD:
2183 /* Always switch state before calling upper layers */
2184 irlap_next_state(self, LAP_NDM);
2185
2186 /* Send disconnect response */
2187 irlap_wait_min_turn_around(self, &self->qos_tx);
2188 irlap_send_ua_response_frame(self, NULL);
2189
2190 del_timer(&self->wd_timer);
2191 irlap_flush_all_queues(self);
2192 /* Set default link parameters */
2193 irlap_apply_default_connection_parameters(self);
2194
2195 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
2196 break;
2197 case RECV_DISCOVERY_XID_CMD:
2198 irlap_wait_min_turn_around(self, &self->qos_tx);
2199 irlap_send_rr_frame(self, RSP_FRAME);
2200 self->ack_required = TRUE;
2201 irlap_start_wd_timer(self, self->wd_timeout);
2202 irlap_next_state(self, LAP_NRM_S);
2203
2204 break;
2205 case RECV_TEST_CMD:
2206 /* Remove test frame header (only LAP header in NRM) */
2207 skb_pull(skb, LAP_ADDR_HEADER + LAP_CTRL_HEADER);
2208
2209 irlap_wait_min_turn_around(self, &self->qos_tx);
2210 irlap_start_wd_timer(self, self->wd_timeout);
2211
2212 /* Send response (info will be copied) */
2213 irlap_send_test_frame(self, self->caddr, info->daddr, skb);
2214 break;
2215 default:
2216 IRDA_DEBUG(1, "%s(), Unknown event %d, (%s)\n", __FUNCTION__,
2217 event, irlap_event[event]);
2218
2219 ret = -EINVAL;
2220 break;
2221 }
2222 return ret;
2223}
2224
2225/*
2226 * Function irlap_state_sclose (self, event, skb, info)
2227 */
2228static int irlap_state_sclose(struct irlap_cb *self, IRLAP_EVENT event,
2229 struct sk_buff *skb, struct irlap_info *info)
2230{
2231 int ret = 0;
2232
2233 IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
2234
2235 IRDA_ASSERT(self != NULL, return -ENODEV;);
2236 IRDA_ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
2237
2238 switch (event) {
2239 case RECV_DISC_CMD:
2240 /* Always switch state before calling upper layers */
2241 irlap_next_state(self, LAP_NDM);
2242
2243 /* Send disconnect response */
2244 irlap_wait_min_turn_around(self, &self->qos_tx);
2245 irlap_send_ua_response_frame(self, NULL);
2246
2247 del_timer(&self->wd_timer);
2248 /* Set default link parameters */
2249 irlap_apply_default_connection_parameters(self);
2250
2251 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
2252 break;
2253 case RECV_DM_RSP:
2254 /* IrLAP-1.1 p.82: in SCLOSE, S and I type RSP frames
2255 * shall take us down into default NDM state, like DM_RSP
2256 */
2257 case RECV_RR_RSP:
2258 case RECV_RNR_RSP:
2259 case RECV_REJ_RSP:
2260 case RECV_SREJ_RSP:
2261 case RECV_I_RSP:
2262 /* Always switch state before calling upper layers */
2263 irlap_next_state(self, LAP_NDM);
2264
2265 del_timer(&self->wd_timer);
2266 irlap_apply_default_connection_parameters(self);
2267
2268 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
2269 break;
2270 case WD_TIMER_EXPIRED:
2271 /* Always switch state before calling upper layers */
2272 irlap_next_state(self, LAP_NDM);
2273
2274 irlap_apply_default_connection_parameters(self);
2275
2276 irlap_disconnect_indication(self, LAP_DISC_INDICATION);
2277 break;
2278 default:
2279 /* IrLAP-1.1 p.82: in SCLOSE, basically any received frame
2280 * with pf=1 shall restart the wd-timer and resend the rd:rsp
2281 */
2282 if (info != NULL && info->pf) {
2283 del_timer(&self->wd_timer);
2284 irlap_wait_min_turn_around(self, &self->qos_tx);
2285 irlap_send_rd_frame(self);
2286 irlap_start_wd_timer(self, self->wd_timeout);
2287 break; /* stay in SCLOSE */
2288 }
2289
2290 IRDA_DEBUG(1, "%s(), Unknown event %d, (%s)\n", __FUNCTION__,
2291 event, irlap_event[event]);
2292
2293 ret = -EINVAL;
2294 break;
2295 }
2296
2297 return -1;
2298}
2299
2300static int irlap_state_reset_check( struct irlap_cb *self, IRLAP_EVENT event,
2301 struct sk_buff *skb,
2302 struct irlap_info *info)
2303{
2304 int ret = 0;
2305
2306 IRDA_DEBUG(1, "%s(), event=%s\n", __FUNCTION__, irlap_event[event]);
2307
2308 IRDA_ASSERT(self != NULL, return -ENODEV;);
2309 IRDA_ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
2310
2311 switch (event) {
2312 case RESET_RESPONSE:
2313 irlap_send_ua_response_frame(self, &self->qos_rx);
2314 irlap_initiate_connection_state(self);
2315 irlap_start_wd_timer(self, WD_TIMEOUT);
2316 irlap_flush_all_queues(self);
2317
2318 irlap_next_state(self, LAP_NRM_S);
2319 break;
2320 case DISCONNECT_REQUEST:
2321 irlap_wait_min_turn_around(self, &self->qos_tx);
2322 irlap_send_rd_frame(self);
2323 irlap_start_wd_timer(self, WD_TIMEOUT);
2324 irlap_next_state(self, LAP_SCLOSE);
2325 break;
2326 default:
2327 IRDA_DEBUG(1, "%s(), Unknown event %d, (%s)\n", __FUNCTION__,
2328 event, irlap_event[event]);
2329
2330 ret = -EINVAL;
2331 break;
2332 }
2333 return ret;
2334}
diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c
new file mode 100644
index 00000000000..040abe714aa
--- /dev/null
+++ b/net/irda/irlap_frame.c
@@ -0,0 +1,1437 @@
1/*********************************************************************
2 *
3 * Filename: irlap_frame.c
4 * Version: 1.0
5 * Description: Build and transmit IrLAP frames
6 * Status: Stable
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Tue Aug 19 10:27:26 1997
9 * Modified at: Wed Jan 5 08:59:04 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
13 * All Rights Reserved.
14 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
20 *
21 * Neither Dag Brattli nor University of Tromsø admit liability nor
22 * provide warranty for any of this software. This material is
23 * provided "AS-IS" and at no charge.
24 *
25 ********************************************************************/
26
27#include <linux/skbuff.h>
28#include <linux/if.h>
29#include <linux/if_ether.h>
30#include <linux/netdevice.h>
31#include <linux/irda.h>
32
33#include <net/pkt_sched.h>
34#include <net/sock.h>
35
36#include <asm/byteorder.h>
37
38#include <net/irda/irda.h>
39#include <net/irda/irda_device.h>
40#include <net/irda/irlap.h>
41#include <net/irda/wrapper.h>
42#include <net/irda/timer.h>
43#include <net/irda/irlap_frame.h>
44#include <net/irda/qos.h>
45
46static void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb,
47 int command);
48
49/*
50 * Function irlap_insert_info (self, skb)
51 *
52 * Insert minimum turnaround time and speed information into the skb. We
53 * need to do this since it's per packet relevant information. Safe to
54 * have this function inlined since it's only called from one place
55 */
56static inline void irlap_insert_info(struct irlap_cb *self,
57 struct sk_buff *skb)
58{
59 struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
60
61 /*
62 * Insert MTT (min. turn time) and speed into skb, so that the
63 * device driver knows which settings to use
64 */
65 cb->magic = LAP_MAGIC;
66 cb->mtt = self->mtt_required;
67 cb->next_speed = self->speed;
68
69 /* Reset */
70 self->mtt_required = 0;
71
72 /*
73 * Delay equals negotiated BOFs count, plus the number of BOFs to
74 * force the negotiated minimum turnaround time
75 */
76 cb->xbofs = self->bofs_count;
77 cb->next_xbofs = self->next_bofs;
78 cb->xbofs_delay = self->xbofs_delay;
79
80 /* Reset XBOF's delay (used only for getting min turn time) */
81 self->xbofs_delay = 0;
82 /* Put the correct xbofs value for the next packet */
83 self->bofs_count = self->next_bofs;
84}
85
86/*
87 * Function irlap_queue_xmit (self, skb)
88 *
89 * A little wrapper for dev_queue_xmit, so we can insert some common
90 * code into it.
91 */
92void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb)
93{
94 /* Some common init stuff */
95 skb->dev = self->netdev;
96 skb->h.raw = skb->nh.raw = skb->mac.raw = skb->data;
97 skb->protocol = htons(ETH_P_IRDA);
98 skb->priority = TC_PRIO_BESTEFFORT;
99
100 irlap_insert_info(self, skb);
101
102 dev_queue_xmit(skb);
103}
104
105/*
106 * Function irlap_send_snrm_cmd (void)
107 *
108 * Transmits a connect SNRM command frame
109 */
110void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos)
111{
112 struct sk_buff *tx_skb;
113 struct snrm_frame *frame;
114 int ret;
115
116 IRDA_ASSERT(self != NULL, return;);
117 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
118
119 /* Allocate frame */
120 tx_skb = dev_alloc_skb(64);
121 if (!tx_skb)
122 return;
123
124 frame = (struct snrm_frame *) skb_put(tx_skb, 2);
125
126 /* Insert connection address field */
127 if (qos)
128 frame->caddr = CMD_FRAME | CBROADCAST;
129 else
130 frame->caddr = CMD_FRAME | self->caddr;
131
132 /* Insert control field */
133 frame->control = SNRM_CMD | PF_BIT;
134
135 /*
136 * If we are establishing a connection then insert QoS paramerters
137 */
138 if (qos) {
139 skb_put(tx_skb, 9); /* 21 left */
140 frame->saddr = cpu_to_le32(self->saddr);
141 frame->daddr = cpu_to_le32(self->daddr);
142
143 frame->ncaddr = self->caddr;
144
145 ret = irlap_insert_qos_negotiation_params(self, tx_skb);
146 if (ret < 0) {
147 dev_kfree_skb(tx_skb);
148 return;
149 }
150 }
151 irlap_queue_xmit(self, tx_skb);
152}
153
154/*
155 * Function irlap_recv_snrm_cmd (skb, info)
156 *
157 * Received SNRM (Set Normal Response Mode) command frame
158 *
159 */
160static void irlap_recv_snrm_cmd(struct irlap_cb *self, struct sk_buff *skb,
161 struct irlap_info *info)
162{
163 struct snrm_frame *frame;
164
165 if (pskb_may_pull(skb,sizeof(struct snrm_frame))) {
166 frame = (struct snrm_frame *) skb->data;
167
168 /* Copy the new connection address ignoring the C/R bit */
169 info->caddr = frame->ncaddr & 0xFE;
170
171 /* Check if the new connection address is valid */
172 if ((info->caddr == 0x00) || (info->caddr == 0xfe)) {
173 IRDA_DEBUG(3, "%s(), invalid connection address!\n",
174 __FUNCTION__);
175 return;
176 }
177
178 /* Copy peer device address */
179 info->daddr = le32_to_cpu(frame->saddr);
180 info->saddr = le32_to_cpu(frame->daddr);
181
182 /* Only accept if addressed directly to us */
183 if (info->saddr != self->saddr) {
184 IRDA_DEBUG(2, "%s(), not addressed to us!\n",
185 __FUNCTION__);
186 return;
187 }
188 irlap_do_event(self, RECV_SNRM_CMD, skb, info);
189 } else {
190 /* Signal that this SNRM frame does not contain and I-field */
191 irlap_do_event(self, RECV_SNRM_CMD, skb, NULL);
192 }
193}
194
195/*
196 * Function irlap_send_ua_response_frame (qos)
197 *
198 * Send UA (Unnumbered Acknowledgement) frame
199 *
200 */
201void irlap_send_ua_response_frame(struct irlap_cb *self, struct qos_info *qos)
202{
203 struct sk_buff *tx_skb;
204 struct ua_frame *frame;
205 int ret;
206
207 IRDA_DEBUG(2, "%s() <%ld>\n", __FUNCTION__, jiffies);
208
209 IRDA_ASSERT(self != NULL, return;);
210 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
211
212 /* Allocate frame */
213 tx_skb = dev_alloc_skb(64);
214 if (!tx_skb)
215 return;
216
217 frame = (struct ua_frame *) skb_put(tx_skb, 10);
218
219 /* Build UA response */
220 frame->caddr = self->caddr;
221 frame->control = UA_RSP | PF_BIT;
222
223 frame->saddr = cpu_to_le32(self->saddr);
224 frame->daddr = cpu_to_le32(self->daddr);
225
226 /* Should we send QoS negotiation parameters? */
227 if (qos) {
228 ret = irlap_insert_qos_negotiation_params(self, tx_skb);
229 if (ret < 0) {
230 dev_kfree_skb(tx_skb);
231 return;
232 }
233 }
234
235 irlap_queue_xmit(self, tx_skb);
236}
237
238
239/*
240 * Function irlap_send_dm_frame (void)
241 *
242 * Send disconnected mode (DM) frame
243 *
244 */
245void irlap_send_dm_frame( struct irlap_cb *self)
246{
247 struct sk_buff *tx_skb = NULL;
248 __u8 *frame;
249
250 IRDA_ASSERT(self != NULL, return;);
251 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
252
253 tx_skb = dev_alloc_skb(32);
254 if (!tx_skb)
255 return;
256
257 frame = skb_put(tx_skb, 2);
258
259 if (self->state == LAP_NDM)
260 frame[0] = CBROADCAST;
261 else
262 frame[0] = self->caddr;
263
264 frame[1] = DM_RSP | PF_BIT;
265
266 irlap_queue_xmit(self, tx_skb);
267}
268
269/*
270 * Function irlap_send_disc_frame (void)
271 *
272 * Send disconnect (DISC) frame
273 *
274 */
275void irlap_send_disc_frame(struct irlap_cb *self)
276{
277 struct sk_buff *tx_skb = NULL;
278 __u8 *frame;
279
280 IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
281
282 IRDA_ASSERT(self != NULL, return;);
283 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
284
285 tx_skb = dev_alloc_skb(16);
286 if (!tx_skb)
287 return;
288
289 frame = skb_put(tx_skb, 2);
290
291 frame[0] = self->caddr | CMD_FRAME;
292 frame[1] = DISC_CMD | PF_BIT;
293
294 irlap_queue_xmit(self, tx_skb);
295}
296
297/*
298 * Function irlap_send_discovery_xid_frame (S, s, command)
299 *
300 * Build and transmit a XID (eXchange station IDentifier) discovery
301 * frame.
302 */
303void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s,
304 __u8 command, discovery_t *discovery)
305{
306 struct sk_buff *tx_skb = NULL;
307 struct xid_frame *frame;
308 __u32 bcast = BROADCAST;
309 __u8 *info;
310
311 IRDA_DEBUG(4, "%s(), s=%d, S=%d, command=%d\n", __FUNCTION__,
312 s, S, command);
313
314 IRDA_ASSERT(self != NULL, return;);
315 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
316 IRDA_ASSERT(discovery != NULL, return;);
317
318 tx_skb = dev_alloc_skb(64);
319 if (!tx_skb)
320 return;
321
322 skb_put(tx_skb, 14);
323 frame = (struct xid_frame *) tx_skb->data;
324
325 if (command) {
326 frame->caddr = CBROADCAST | CMD_FRAME;
327 frame->control = XID_CMD | PF_BIT;
328 } else {
329 frame->caddr = CBROADCAST;
330 frame->control = XID_RSP | PF_BIT;
331 }
332 frame->ident = XID_FORMAT;
333
334 frame->saddr = cpu_to_le32(self->saddr);
335
336 if (command)
337 frame->daddr = cpu_to_le32(bcast);
338 else
339 frame->daddr = cpu_to_le32(discovery->data.daddr);
340
341 switch (S) {
342 case 1:
343 frame->flags = 0x00;
344 break;
345 case 6:
346 frame->flags = 0x01;
347 break;
348 case 8:
349 frame->flags = 0x02;
350 break;
351 case 16:
352 frame->flags = 0x03;
353 break;
354 default:
355 frame->flags = 0x02;
356 break;
357 }
358
359 frame->slotnr = s;
360 frame->version = 0x00;
361
362 /*
363 * Provide info for final slot only in commands, and for all
364 * responses. Send the second byte of the hint only if the
365 * EXTENSION bit is set in the first byte.
366 */
367 if (!command || (frame->slotnr == 0xff)) {
368 int len;
369
370 if (discovery->data.hints[0] & HINT_EXTENSION) {
371 info = skb_put(tx_skb, 2);
372 info[0] = discovery->data.hints[0];
373 info[1] = discovery->data.hints[1];
374 } else {
375 info = skb_put(tx_skb, 1);
376 info[0] = discovery->data.hints[0];
377 }
378 info = skb_put(tx_skb, 1);
379 info[0] = discovery->data.charset;
380
381 len = IRDA_MIN(discovery->name_len, skb_tailroom(tx_skb));
382 info = skb_put(tx_skb, len);
383 memcpy(info, discovery->data.info, len);
384 }
385 irlap_queue_xmit(self, tx_skb);
386}
387
388/*
389 * Function irlap_recv_discovery_xid_rsp (skb, info)
390 *
391 * Received a XID discovery response
392 *
393 */
394static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self,
395 struct sk_buff *skb,
396 struct irlap_info *info)
397{
398 struct xid_frame *xid;
399 discovery_t *discovery = NULL;
400 __u8 *discovery_info;
401 char *text;
402
403 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
404
405 IRDA_ASSERT(self != NULL, return;);
406 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
407
408 if (!pskb_may_pull(skb, sizeof(struct xid_frame))) {
409 IRDA_ERROR("%s: frame to short!\n", __FUNCTION__);
410 return;
411 }
412
413 xid = (struct xid_frame *) skb->data;
414
415 info->daddr = le32_to_cpu(xid->saddr);
416 info->saddr = le32_to_cpu(xid->daddr);
417
418 /* Make sure frame is addressed to us */
419 if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
420 IRDA_DEBUG(0, "%s(), frame is not addressed to us!\n",
421 __FUNCTION__);
422 return;
423 }
424
425 if ((discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) {
426 IRDA_WARNING("%s: kmalloc failed!\n", __FUNCTION__);
427 return;
428 }
429 memset(discovery, 0, sizeof(discovery_t));
430
431 discovery->data.daddr = info->daddr;
432 discovery->data.saddr = self->saddr;
433 discovery->timestamp = jiffies;
434
435 IRDA_DEBUG(4, "%s(), daddr=%08x\n", __FUNCTION__,
436 discovery->data.daddr);
437
438 discovery_info = skb_pull(skb, sizeof(struct xid_frame));
439
440 /* Get info returned from peer */
441 discovery->data.hints[0] = discovery_info[0];
442 if (discovery_info[0] & HINT_EXTENSION) {
443 IRDA_DEBUG(4, "EXTENSION\n");
444 discovery->data.hints[1] = discovery_info[1];
445 discovery->data.charset = discovery_info[2];
446 text = (char *) &discovery_info[3];
447 } else {
448 discovery->data.hints[1] = 0;
449 discovery->data.charset = discovery_info[1];
450 text = (char *) &discovery_info[2];
451 }
452 /*
453 * Terminate info string, should be safe since this is where the
454 * FCS bytes resides.
455 */
456 skb->data[skb->len] = '\0';
457 strncpy(discovery->data.info, text, NICKNAME_MAX_LEN);
458 discovery->name_len = strlen(discovery->data.info);
459
460 info->discovery = discovery;
461
462 irlap_do_event(self, RECV_DISCOVERY_XID_RSP, skb, info);
463}
464
465/*
466 * Function irlap_recv_discovery_xid_cmd (skb, info)
467 *
468 * Received a XID discovery command
469 *
470 */
471static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self,
472 struct sk_buff *skb,
473 struct irlap_info *info)
474{
475 struct xid_frame *xid;
476 discovery_t *discovery = NULL;
477 __u8 *discovery_info;
478 char *text;
479
480 if (!pskb_may_pull(skb, sizeof(struct xid_frame))) {
481 IRDA_ERROR("%s: frame to short!\n", __FUNCTION__);
482 return;
483 }
484
485 xid = (struct xid_frame *) skb->data;
486
487 info->daddr = le32_to_cpu(xid->saddr);
488 info->saddr = le32_to_cpu(xid->daddr);
489
490 /* Make sure frame is addressed to us */
491 if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
492 IRDA_DEBUG(0, "%s(), frame is not addressed to us!\n",
493 __FUNCTION__);
494 return;
495 }
496
497 switch (xid->flags & 0x03) {
498 case 0x00:
499 info->S = 1;
500 break;
501 case 0x01:
502 info->S = 6;
503 break;
504 case 0x02:
505 info->S = 8;
506 break;
507 case 0x03:
508 info->S = 16;
509 break;
510 default:
511 /* Error!! */
512 return;
513 }
514 info->s = xid->slotnr;
515
516 discovery_info = skb_pull(skb, sizeof(struct xid_frame));
517
518 /*
519 * Check if last frame
520 */
521 if (info->s == 0xff) {
522 /* Check if things are sane at this point... */
523 if((discovery_info == NULL) ||
524 !pskb_may_pull(skb, 3)) {
525 IRDA_ERROR("%s: discovery frame to short!\n",
526 __FUNCTION__);
527 return;
528 }
529
530 /*
531 * We now have some discovery info to deliver!
532 */
533 discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC);
534 if (!discovery) {
535 IRDA_WARNING("%s: unable to malloc!\n", __FUNCTION__);
536 return;
537 }
538
539 discovery->data.daddr = info->daddr;
540 discovery->data.saddr = self->saddr;
541 discovery->timestamp = jiffies;
542
543 discovery->data.hints[0] = discovery_info[0];
544 if (discovery_info[0] & HINT_EXTENSION) {
545 discovery->data.hints[1] = discovery_info[1];
546 discovery->data.charset = discovery_info[2];
547 text = (char *) &discovery_info[3];
548 } else {
549 discovery->data.hints[1] = 0;
550 discovery->data.charset = discovery_info[1];
551 text = (char *) &discovery_info[2];
552 }
553 /*
554 * Terminate string, should be safe since this is where the
555 * FCS bytes resides.
556 */
557 skb->data[skb->len] = '\0';
558 strncpy(discovery->data.info, text, NICKNAME_MAX_LEN);
559 discovery->name_len = strlen(discovery->data.info);
560
561 info->discovery = discovery;
562 } else
563 info->discovery = NULL;
564
565 irlap_do_event(self, RECV_DISCOVERY_XID_CMD, skb, info);
566}
567
568/*
569 * Function irlap_send_rr_frame (self, command)
570 *
571 * Build and transmit RR (Receive Ready) frame. Notice that it is currently
572 * only possible to send RR frames with the poll bit set.
573 */
574void irlap_send_rr_frame(struct irlap_cb *self, int command)
575{
576 struct sk_buff *tx_skb;
577 __u8 *frame;
578
579 tx_skb = dev_alloc_skb(16);
580 if (!tx_skb)
581 return;
582
583 frame = skb_put(tx_skb, 2);
584
585 frame[0] = self->caddr;
586 frame[0] |= (command) ? CMD_FRAME : 0;
587
588 frame[1] = RR | PF_BIT | (self->vr << 5);
589
590 irlap_queue_xmit(self, tx_skb);
591}
592
593/*
594 * Function irlap_send_rd_frame (self)
595 *
596 * Request disconnect. Used by a secondary station to request the
597 * disconnection of the link.
598 */
599void irlap_send_rd_frame(struct irlap_cb *self)
600{
601 struct sk_buff *tx_skb;
602 __u8 *frame;
603
604 tx_skb = dev_alloc_skb(16);
605 if (!tx_skb)
606 return;
607
608 frame = skb_put(tx_skb, 2);
609
610 frame[0] = self->caddr;
611 frame[1] = RD_RSP | PF_BIT;
612
613 irlap_queue_xmit(self, tx_skb);
614}
615
616/*
617 * Function irlap_recv_rr_frame (skb, info)
618 *
619 * Received RR (Receive Ready) frame from peer station, no harm in
620 * making it inline since its called only from one single place
621 * (irlap_driver_rcv).
622 */
623static inline void irlap_recv_rr_frame(struct irlap_cb *self,
624 struct sk_buff *skb,
625 struct irlap_info *info, int command)
626{
627 info->nr = skb->data[1] >> 5;
628
629 /* Check if this is a command or a response frame */
630 if (command)
631 irlap_do_event(self, RECV_RR_CMD, skb, info);
632 else
633 irlap_do_event(self, RECV_RR_RSP, skb, info);
634}
635
636/*
637 * Function irlap_recv_rnr_frame (self, skb, info)
638 *
639 * Received RNR (Receive Not Ready) frame from peer station
640 *
641 */
642static void irlap_recv_rnr_frame(struct irlap_cb *self, struct sk_buff *skb,
643 struct irlap_info *info, int command)
644{
645 info->nr = skb->data[1] >> 5;
646
647 IRDA_DEBUG(4, "%s(), nr=%d, %ld\n", __FUNCTION__, info->nr, jiffies);
648
649 if (command)
650 irlap_do_event(self, RECV_RNR_CMD, skb, info);
651 else
652 irlap_do_event(self, RECV_RNR_RSP, skb, info);
653}
654
655static void irlap_recv_rej_frame(struct irlap_cb *self, struct sk_buff *skb,
656 struct irlap_info *info, int command)
657{
658 IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
659
660 info->nr = skb->data[1] >> 5;
661
662 /* Check if this is a command or a response frame */
663 if (command)
664 irlap_do_event(self, RECV_REJ_CMD, skb, info);
665 else
666 irlap_do_event(self, RECV_REJ_RSP, skb, info);
667}
668
669static void irlap_recv_srej_frame(struct irlap_cb *self, struct sk_buff *skb,
670 struct irlap_info *info, int command)
671{
672 IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
673
674 info->nr = skb->data[1] >> 5;
675
676 /* Check if this is a command or a response frame */
677 if (command)
678 irlap_do_event(self, RECV_SREJ_CMD, skb, info);
679 else
680 irlap_do_event(self, RECV_SREJ_RSP, skb, info);
681}
682
683static void irlap_recv_disc_frame(struct irlap_cb *self, struct sk_buff *skb,
684 struct irlap_info *info, int command)
685{
686 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
687
688 /* Check if this is a command or a response frame */
689 if (command)
690 irlap_do_event(self, RECV_DISC_CMD, skb, info);
691 else
692 irlap_do_event(self, RECV_RD_RSP, skb, info);
693}
694
695/*
696 * Function irlap_recv_ua_frame (skb, frame)
697 *
698 * Received UA (Unnumbered Acknowledgement) frame
699 *
700 */
701static inline void irlap_recv_ua_frame(struct irlap_cb *self,
702 struct sk_buff *skb,
703 struct irlap_info *info)
704{
705 irlap_do_event(self, RECV_UA_RSP, skb, info);
706}
707
708/*
709 * Function irlap_send_data_primary(self, skb)
710 *
711 * Send I-frames as the primary station but without the poll bit set
712 *
713 */
714void irlap_send_data_primary(struct irlap_cb *self, struct sk_buff *skb)
715{
716 struct sk_buff *tx_skb;
717
718 if (skb->data[1] == I_FRAME) {
719
720 /*
721 * Insert frame sequence number (Vs) in control field before
722 * inserting into transmit window queue.
723 */
724 skb->data[1] = I_FRAME | (self->vs << 1);
725
726 /*
727 * Insert frame in store, in case of retransmissions
728 * Increase skb reference count, see irlap_do_event()
729 */
730 skb_get(skb);
731 skb_queue_tail(&self->wx_list, skb);
732
733 /* Copy buffer */
734 tx_skb = skb_clone(skb, GFP_ATOMIC);
735 if (tx_skb == NULL) {
736 return;
737 }
738
739 self->vs = (self->vs + 1) % 8;
740 self->ack_required = FALSE;
741 self->window -= 1;
742
743 irlap_send_i_frame( self, tx_skb, CMD_FRAME);
744 } else {
745 IRDA_DEBUG(4, "%s(), sending unreliable frame\n", __FUNCTION__);
746 irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
747 self->window -= 1;
748 }
749}
750/*
751 * Function irlap_send_data_primary_poll (self, skb)
752 *
753 * Send I(nformation) frame as primary with poll bit set
754 */
755void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb)
756{
757 struct sk_buff *tx_skb;
758 int transmission_time;
759
760 /* Stop P timer */
761 del_timer(&self->poll_timer);
762
763 /* Is this reliable or unreliable data? */
764 if (skb->data[1] == I_FRAME) {
765
766 /*
767 * Insert frame sequence number (Vs) in control field before
768 * inserting into transmit window queue.
769 */
770 skb->data[1] = I_FRAME | (self->vs << 1);
771
772 /*
773 * Insert frame in store, in case of retransmissions
774 * Increase skb reference count, see irlap_do_event()
775 */
776 skb_get(skb);
777 skb_queue_tail(&self->wx_list, skb);
778
779 /* Copy buffer */
780 tx_skb = skb_clone(skb, GFP_ATOMIC);
781 if (tx_skb == NULL) {
782 return;
783 }
784
785 /*
786 * Set poll bit if necessary. We do this to the copied
787 * skb, since retransmitted need to set or clear the poll
788 * bit depending on when they are sent.
789 */
790 tx_skb->data[1] |= PF_BIT;
791
792 self->vs = (self->vs + 1) % 8;
793 self->ack_required = FALSE;
794
795 irlap_send_i_frame(self, tx_skb, CMD_FRAME);
796 } else {
797 IRDA_DEBUG(4, "%s(), sending unreliable frame\n", __FUNCTION__);
798
799 if (self->ack_required) {
800 irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
801 irlap_send_rr_frame(self, CMD_FRAME);
802 self->ack_required = FALSE;
803 } else {
804 skb->data[1] |= PF_BIT;
805 irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
806 }
807 }
808
809 /* How much time we took for transmission of all frames.
810 * We don't know, so let assume we used the full window. Jean II */
811 transmission_time = self->final_timeout;
812
813 /* Reset parameter so that we can fill next window */
814 self->window = self->window_size;
815
816#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
817 /* Remove what we have not used. Just do a prorata of the
818 * bytes left in window to window capacity.
819 * See max_line_capacities[][] in qos.c for details. Jean II */
820 transmission_time -= (self->final_timeout * self->bytes_left
821 / self->line_capacity);
822 IRDA_DEBUG(4, "%s() adjusting transmission_time : ft=%d, bl=%d, lc=%d -> tt=%d\n", __FUNCTION__, self->final_timeout, self->bytes_left, self->line_capacity, transmission_time);
823
824 /* We are allowed to transmit a maximum number of bytes again. */
825 self->bytes_left = self->line_capacity;
826#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
827
828 /*
829 * The network layer has a intermediate buffer between IrLAP
830 * and the IrDA driver which can contain 8 frames. So, even
831 * though IrLAP is currently sending the *last* frame of the
832 * tx-window, the driver most likely has only just started
833 * sending the *first* frame of the same tx-window.
834 * I.e. we are always at the very begining of or Tx window.
835 * Now, we are supposed to set the final timer from the end
836 * of our tx-window to let the other peer reply. So, we need
837 * to add extra time to compensate for the fact that we
838 * are really at the start of tx-window, otherwise the final timer
839 * might expire before he can answer...
840 * Jean II
841 */
842 irlap_start_final_timer(self, self->final_timeout + transmission_time);
843
844 /*
845 * The clever amongst you might ask why we do this adjustement
846 * only here, and not in all the other cases in irlap_event.c.
847 * In all those other case, we only send a very short management
848 * frame (few bytes), so the adjustement would be lost in the
849 * noise...
850 * The exception of course is irlap_resend_rejected_frame().
851 * Jean II */
852}
853
854/*
855 * Function irlap_send_data_secondary_final (self, skb)
856 *
857 * Send I(nformation) frame as secondary with final bit set
858 *
859 */
860void irlap_send_data_secondary_final(struct irlap_cb *self,
861 struct sk_buff *skb)
862{
863 struct sk_buff *tx_skb = NULL;
864
865 IRDA_ASSERT(self != NULL, return;);
866 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
867 IRDA_ASSERT(skb != NULL, return;);
868
869 /* Is this reliable or unreliable data? */
870 if (skb->data[1] == I_FRAME) {
871
872 /*
873 * Insert frame sequence number (Vs) in control field before
874 * inserting into transmit window queue.
875 */
876 skb->data[1] = I_FRAME | (self->vs << 1);
877
878 /*
879 * Insert frame in store, in case of retransmissions
880 * Increase skb reference count, see irlap_do_event()
881 */
882 skb_get(skb);
883 skb_queue_tail(&self->wx_list, skb);
884
885 tx_skb = skb_clone(skb, GFP_ATOMIC);
886 if (tx_skb == NULL) {
887 return;
888 }
889
890 tx_skb->data[1] |= PF_BIT;
891
892 self->vs = (self->vs + 1) % 8;
893 self->ack_required = FALSE;
894
895 irlap_send_i_frame(self, tx_skb, RSP_FRAME);
896 } else {
897 if (self->ack_required) {
898 irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
899 irlap_send_rr_frame(self, RSP_FRAME);
900 self->ack_required = FALSE;
901 } else {
902 skb->data[1] |= PF_BIT;
903 irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
904 }
905 }
906
907 self->window = self->window_size;
908#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
909 /* We are allowed to transmit a maximum number of bytes again. */
910 self->bytes_left = self->line_capacity;
911#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
912
913 irlap_start_wd_timer(self, self->wd_timeout);
914}
915
916/*
917 * Function irlap_send_data_secondary (self, skb)
918 *
919 * Send I(nformation) frame as secondary without final bit set
920 *
921 */
922void irlap_send_data_secondary(struct irlap_cb *self, struct sk_buff *skb)
923{
924 struct sk_buff *tx_skb = NULL;
925
926 /* Is this reliable or unreliable data? */
927 if (skb->data[1] == I_FRAME) {
928
929 /*
930 * Insert frame sequence number (Vs) in control field before
931 * inserting into transmit window queue.
932 */
933 skb->data[1] = I_FRAME | (self->vs << 1);
934
935 /*
936 * Insert frame in store, in case of retransmissions
937 * Increase skb reference count, see irlap_do_event()
938 */
939 skb_get(skb);
940 skb_queue_tail(&self->wx_list, skb);
941
942 tx_skb = skb_clone(skb, GFP_ATOMIC);
943 if (tx_skb == NULL) {
944 return;
945 }
946
947 self->vs = (self->vs + 1) % 8;
948 self->ack_required = FALSE;
949 self->window -= 1;
950
951 irlap_send_i_frame(self, tx_skb, RSP_FRAME);
952 } else {
953 irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
954 self->window -= 1;
955 }
956}
957
958/*
959 * Function irlap_resend_rejected_frames (nr)
960 *
961 * Resend frames which has not been acknowledged. Should be safe to
962 * traverse the list without locking it since this function will only be
963 * called from interrupt context (BH)
964 */
965void irlap_resend_rejected_frames(struct irlap_cb *self, int command)
966{
967 struct sk_buff *tx_skb;
968 struct sk_buff *skb;
969 int count;
970
971 IRDA_ASSERT(self != NULL, return;);
972 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
973
974 /* Initialize variables */
975 count = skb_queue_len(&self->wx_list);
976
977 /* Resend unacknowledged frame(s) */
978 skb = skb_peek(&self->wx_list);
979 while (skb != NULL) {
980 irlap_wait_min_turn_around(self, &self->qos_tx);
981
982 /* We copy the skb to be retransmitted since we will have to
983 * modify it. Cloning will confuse packet sniffers
984 */
985 /* tx_skb = skb_clone( skb, GFP_ATOMIC); */
986 tx_skb = skb_copy(skb, GFP_ATOMIC);
987 if (!tx_skb) {
988 IRDA_DEBUG(0, "%s(), unable to copy\n", __FUNCTION__);
989 return;
990 }
991 /* Unlink tx_skb from list */
992 tx_skb->next = tx_skb->prev = NULL;
993 tx_skb->list = NULL;
994
995 /* Clear old Nr field + poll bit */
996 tx_skb->data[1] &= 0x0f;
997
998 /*
999 * Set poll bit on the last frame retransmitted
1000 */
1001 if (count-- == 1)
1002 tx_skb->data[1] |= PF_BIT; /* Set p/f bit */
1003 else
1004 tx_skb->data[1] &= ~PF_BIT; /* Clear p/f bit */
1005
1006 irlap_send_i_frame(self, tx_skb, command);
1007
1008 /*
1009 * If our skb is the last buffer in the list, then
1010 * we are finished, if not, move to the next sk-buffer
1011 */
1012 if (skb == skb_peek_tail(&self->wx_list))
1013 skb = NULL;
1014 else
1015 skb = skb->next;
1016 }
1017#if 0 /* Not yet */
1018 /*
1019 * We can now fill the window with additional data frames
1020 */
1021 while (skb_queue_len( &self->txq) > 0) {
1022
1023 IRDA_DEBUG(0, "%s(), sending additional frames!\n", __FUNCTION__);
1024 if ((skb_queue_len( &self->txq) > 0) &&
1025 (self->window > 0)) {
1026 skb = skb_dequeue( &self->txq);
1027 IRDA_ASSERT(skb != NULL, return;);
1028
1029 /*
1030 * If send window > 1 then send frame with pf
1031 * bit cleared
1032 */
1033 if ((self->window > 1) &&
1034 skb_queue_len(&self->txq) > 0)
1035 {
1036 irlap_send_data_primary(self, skb);
1037 } else {
1038 irlap_send_data_primary_poll(self, skb);
1039 }
1040 kfree_skb(skb);
1041 }
1042 }
1043#endif
1044}
1045
1046void irlap_resend_rejected_frame(struct irlap_cb *self, int command)
1047{
1048 struct sk_buff *tx_skb;
1049 struct sk_buff *skb;
1050
1051 IRDA_ASSERT(self != NULL, return;);
1052 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
1053
1054 /* Resend unacknowledged frame(s) */
1055 skb = skb_peek(&self->wx_list);
1056 if (skb != NULL) {
1057 irlap_wait_min_turn_around(self, &self->qos_tx);
1058
1059 /* We copy the skb to be retransmitted since we will have to
1060 * modify it. Cloning will confuse packet sniffers
1061 */
1062 /* tx_skb = skb_clone( skb, GFP_ATOMIC); */
1063 tx_skb = skb_copy(skb, GFP_ATOMIC);
1064 if (!tx_skb) {
1065 IRDA_DEBUG(0, "%s(), unable to copy\n", __FUNCTION__);
1066 return;
1067 }
1068 /* Unlink tx_skb from list */
1069 tx_skb->next = tx_skb->prev = NULL;
1070 tx_skb->list = NULL;
1071
1072 /* Clear old Nr field + poll bit */
1073 tx_skb->data[1] &= 0x0f;
1074
1075 /* Set poll/final bit */
1076 tx_skb->data[1] |= PF_BIT; /* Set p/f bit */
1077
1078 irlap_send_i_frame(self, tx_skb, command);
1079 }
1080}
1081
1082/*
1083 * Function irlap_send_ui_frame (self, skb, command)
1084 *
1085 * Contruct and transmit an Unnumbered Information (UI) frame
1086 *
1087 */
1088void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
1089 __u8 caddr, int command)
1090{
1091 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1092
1093 IRDA_ASSERT(self != NULL, return;);
1094 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
1095 IRDA_ASSERT(skb != NULL, return;);
1096
1097 /* Insert connection address */
1098 skb->data[0] = caddr | ((command) ? CMD_FRAME : 0);
1099
1100 irlap_queue_xmit(self, skb);
1101}
1102
1103/*
1104 * Function irlap_send_i_frame (skb)
1105 *
1106 * Contruct and transmit Information (I) frame
1107 */
1108static void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb,
1109 int command)
1110{
1111 /* Insert connection address */
1112 skb->data[0] = self->caddr;
1113 skb->data[0] |= (command) ? CMD_FRAME : 0;
1114
1115 /* Insert next to receive (Vr) */
1116 skb->data[1] |= (self->vr << 5); /* insert nr */
1117
1118 irlap_queue_xmit(self, skb);
1119}
1120
1121/*
1122 * Function irlap_recv_i_frame (skb, frame)
1123 *
1124 * Receive and parse an I (Information) frame, no harm in making it inline
1125 * since it's called only from one single place (irlap_driver_rcv).
1126 */
1127static inline void irlap_recv_i_frame(struct irlap_cb *self,
1128 struct sk_buff *skb,
1129 struct irlap_info *info, int command)
1130{
1131 info->nr = skb->data[1] >> 5; /* Next to receive */
1132 info->pf = skb->data[1] & PF_BIT; /* Final bit */
1133 info->ns = (skb->data[1] >> 1) & 0x07; /* Next to send */
1134
1135 /* Check if this is a command or a response frame */
1136 if (command)
1137 irlap_do_event(self, RECV_I_CMD, skb, info);
1138 else
1139 irlap_do_event(self, RECV_I_RSP, skb, info);
1140}
1141
1142/*
1143 * Function irlap_recv_ui_frame (self, skb, info)
1144 *
1145 * Receive and parse an Unnumbered Information (UI) frame
1146 *
1147 */
1148static void irlap_recv_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
1149 struct irlap_info *info)
1150{
1151 IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
1152
1153 info->pf = skb->data[1] & PF_BIT; /* Final bit */
1154
1155 irlap_do_event(self, RECV_UI_FRAME, skb, info);
1156}
1157
1158/*
1159 * Function irlap_recv_frmr_frame (skb, frame)
1160 *
1161 * Received Frame Reject response.
1162 *
1163 */
1164static void irlap_recv_frmr_frame(struct irlap_cb *self, struct sk_buff *skb,
1165 struct irlap_info *info)
1166{
1167 __u8 *frame;
1168 int w, x, y, z;
1169
1170 IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
1171
1172 IRDA_ASSERT(self != NULL, return;);
1173 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
1174 IRDA_ASSERT(skb != NULL, return;);
1175 IRDA_ASSERT(info != NULL, return;);
1176
1177 if (!pskb_may_pull(skb, 4)) {
1178 IRDA_ERROR("%s: frame to short!\n", __FUNCTION__);
1179 return;
1180 }
1181
1182 frame = skb->data;
1183
1184 info->nr = frame[2] >> 5; /* Next to receive */
1185 info->pf = frame[2] & PF_BIT; /* Final bit */
1186 info->ns = (frame[2] >> 1) & 0x07; /* Next to send */
1187
1188 w = frame[3] & 0x01;
1189 x = frame[3] & 0x02;
1190 y = frame[3] & 0x04;
1191 z = frame[3] & 0x08;
1192
1193 if (w) {
1194 IRDA_DEBUG(0, "Rejected control field is undefined or not "
1195 "implemented.\n");
1196 }
1197 if (x) {
1198 IRDA_DEBUG(0, "Rejected control field was invalid because it "
1199 "contained a non permitted I field.\n");
1200 }
1201 if (y) {
1202 IRDA_DEBUG(0, "Received I field exceeded the maximum negotiated "
1203 "for the existing connection or exceeded the maximum "
1204 "this station supports if no connection exists.\n");
1205 }
1206 if (z) {
1207 IRDA_DEBUG(0, "Rejected control field control field contained an "
1208 "invalid Nr count.\n");
1209 }
1210 irlap_do_event(self, RECV_FRMR_RSP, skb, info);
1211}
1212
1213/*
1214 * Function irlap_send_test_frame (self, daddr)
1215 *
1216 * Send a test frame response
1217 *
1218 */
1219void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr,
1220 struct sk_buff *cmd)
1221{
1222 struct sk_buff *tx_skb;
1223 struct test_frame *frame;
1224 __u8 *info;
1225
1226 tx_skb = dev_alloc_skb(cmd->len+sizeof(struct test_frame));
1227 if (!tx_skb)
1228 return;
1229
1230 /* Broadcast frames must include saddr and daddr fields */
1231 if (caddr == CBROADCAST) {
1232 frame = (struct test_frame *)
1233 skb_put(tx_skb, sizeof(struct test_frame));
1234
1235 /* Insert the swapped addresses */
1236 frame->saddr = cpu_to_le32(self->saddr);
1237 frame->daddr = cpu_to_le32(daddr);
1238 } else
1239 frame = (struct test_frame *) skb_put(tx_skb, LAP_ADDR_HEADER + LAP_CTRL_HEADER);
1240
1241 frame->caddr = caddr;
1242 frame->control = TEST_RSP | PF_BIT;
1243
1244 /* Copy info */
1245 info = skb_put(tx_skb, cmd->len);
1246 memcpy(info, cmd->data, cmd->len);
1247
1248 /* Return to sender */
1249 irlap_wait_min_turn_around(self, &self->qos_tx);
1250 irlap_queue_xmit(self, tx_skb);
1251}
1252
1253/*
1254 * Function irlap_recv_test_frame (self, skb)
1255 *
1256 * Receive a test frame
1257 *
1258 */
1259static void irlap_recv_test_frame(struct irlap_cb *self, struct sk_buff *skb,
1260 struct irlap_info *info, int command)
1261{
1262 struct test_frame *frame;
1263
1264 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
1265
1266 if (!pskb_may_pull(skb, sizeof(*frame))) {
1267 IRDA_ERROR("%s: frame to short!\n", __FUNCTION__);
1268 return;
1269 }
1270 frame = (struct test_frame *) skb->data;
1271
1272 /* Broadcast frames must carry saddr and daddr fields */
1273 if (info->caddr == CBROADCAST) {
1274 if (skb->len < sizeof(struct test_frame)) {
1275 IRDA_DEBUG(0, "%s() test frame to short!\n",
1276 __FUNCTION__);
1277 return;
1278 }
1279
1280 /* Read and swap addresses */
1281 info->daddr = le32_to_cpu(frame->saddr);
1282 info->saddr = le32_to_cpu(frame->daddr);
1283
1284 /* Make sure frame is addressed to us */
1285 if ((info->saddr != self->saddr) &&
1286 (info->saddr != BROADCAST)) {
1287 return;
1288 }
1289 }
1290
1291 if (command)
1292 irlap_do_event(self, RECV_TEST_CMD, skb, info);
1293 else
1294 irlap_do_event(self, RECV_TEST_RSP, skb, info);
1295}
1296
1297/*
1298 * Function irlap_driver_rcv (skb, netdev, ptype)
1299 *
1300 * Called when a frame is received. Dispatches the right receive function
1301 * for processing of the frame.
1302 *
1303 * Note on skb management :
1304 * After calling the higher layers of the IrDA stack, we always
1305 * kfree() the skb, which drop the reference count (and potentially
1306 * destroy it).
1307 * If a higher layer of the stack want to keep the skb around (to put
1308 * in a queue or pass it to the higher layer), it will need to use
1309 * skb_get() to keep a reference on it. This is usually done at the
1310 * LMP level in irlmp.c.
1311 * Jean II
1312 */
1313int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev,
1314 struct packet_type *ptype)
1315{
1316 struct irlap_info info;
1317 struct irlap_cb *self;
1318 int command;
1319 __u8 control;
1320
1321 /* FIXME: should we get our own field? */
1322 self = (struct irlap_cb *) dev->atalk_ptr;
1323
1324 /* If the net device is down, then IrLAP is gone! */
1325 if (!self || self->magic != LAP_MAGIC) {
1326 dev_kfree_skb(skb);
1327 return -1;
1328 }
1329
1330 /* We are no longer an "old" protocol, so we need to handle
1331 * share and non linear skbs. This should never happen, so
1332 * we don't need to be clever about it. Jean II */
1333 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
1334 IRDA_ERROR("%s: can't clone shared skb!\n", __FUNCTION__);
1335 dev_kfree_skb(skb);
1336 return -1;
1337 }
1338
1339 /* Check if frame is large enough for parsing */
1340 if (!pskb_may_pull(skb, 2)) {
1341 IRDA_ERROR("%s: frame to short!\n", __FUNCTION__);
1342 dev_kfree_skb(skb);
1343 return -1;
1344 }
1345
1346 command = skb->data[0] & CMD_FRAME;
1347 info.caddr = skb->data[0] & CBROADCAST;
1348
1349 info.pf = skb->data[1] & PF_BIT;
1350 info.control = skb->data[1] & ~PF_BIT; /* Mask away poll/final bit */
1351
1352 control = info.control;
1353
1354 /* First we check if this frame has a valid connection address */
1355 if ((info.caddr != self->caddr) && (info.caddr != CBROADCAST)) {
1356 IRDA_DEBUG(0, "%s(), wrong connection address!\n",
1357 __FUNCTION__);
1358 goto out;
1359 }
1360 /*
1361 * Optimize for the common case and check if the frame is an
1362 * I(nformation) frame. Only I-frames have bit 0 set to 0
1363 */
1364 if (~control & 0x01) {
1365 irlap_recv_i_frame(self, skb, &info, command);
1366 goto out;
1367 }
1368 /*
1369 * We now check is the frame is an S(upervisory) frame. Only
1370 * S-frames have bit 0 set to 1 and bit 1 set to 0
1371 */
1372 if (~control & 0x02) {
1373 /*
1374 * Received S(upervisory) frame, check which frame type it is
1375 * only the first nibble is of interest
1376 */
1377 switch (control & 0x0f) {
1378 case RR:
1379 irlap_recv_rr_frame(self, skb, &info, command);
1380 break;
1381 case RNR:
1382 irlap_recv_rnr_frame(self, skb, &info, command);
1383 break;
1384 case REJ:
1385 irlap_recv_rej_frame(self, skb, &info, command);
1386 break;
1387 case SREJ:
1388 irlap_recv_srej_frame(self, skb, &info, command);
1389 break;
1390 default:
1391 IRDA_WARNING("%s: Unknown S-frame %02x received!\n",
1392 __FUNCTION__, info.control);
1393 break;
1394 }
1395 goto out;
1396 }
1397 /*
1398 * This must be a C(ontrol) frame
1399 */
1400 switch (control) {
1401 case XID_RSP:
1402 irlap_recv_discovery_xid_rsp(self, skb, &info);
1403 break;
1404 case XID_CMD:
1405 irlap_recv_discovery_xid_cmd(self, skb, &info);
1406 break;
1407 case SNRM_CMD:
1408 irlap_recv_snrm_cmd(self, skb, &info);
1409 break;
1410 case DM_RSP:
1411 irlap_do_event(self, RECV_DM_RSP, skb, &info);
1412 break;
1413 case DISC_CMD: /* And RD_RSP since they have the same value */
1414 irlap_recv_disc_frame(self, skb, &info, command);
1415 break;
1416 case TEST_CMD:
1417 irlap_recv_test_frame(self, skb, &info, command);
1418 break;
1419 case UA_RSP:
1420 irlap_recv_ua_frame(self, skb, &info);
1421 break;
1422 case FRMR_RSP:
1423 irlap_recv_frmr_frame(self, skb, &info);
1424 break;
1425 case UI_FRAME:
1426 irlap_recv_ui_frame(self, skb, &info);
1427 break;
1428 default:
1429 IRDA_WARNING("%s: Unknown frame %02x received!\n",
1430 __FUNCTION__, info.control);
1431 break;
1432 }
1433out:
1434 /* Always drop our reference on the skb */
1435 dev_kfree_skb(skb);
1436 return 0;
1437}
diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c
new file mode 100644
index 00000000000..7a4a4d7fbe6
--- /dev/null
+++ b/net/irda/irlmp.c
@@ -0,0 +1,2041 @@
1/*********************************************************************
2 *
3 * Filename: irlmp.c
4 * Version: 1.0
5 * Description: IrDA Link Management Protocol (LMP) layer
6 * Status: Stable.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Aug 17 20:54:32 1997
9 * Modified at: Wed Jan 5 11:26:03 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
13 * All Rights Reserved.
14 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
20 *
21 * Neither Dag Brattli nor University of Tromsø admit liability nor
22 * provide warranty for any of this software. This material is
23 * provided "AS-IS" and at no charge.
24 *
25 ********************************************************************/
26
27#include <linux/config.h>
28#include <linux/module.h>
29#include <linux/slab.h>
30#include <linux/string.h>
31#include <linux/skbuff.h>
32#include <linux/types.h>
33#include <linux/proc_fs.h>
34#include <linux/init.h>
35#include <linux/kmod.h>
36#include <linux/random.h>
37#include <linux/seq_file.h>
38
39#include <net/irda/irda.h>
40#include <net/irda/timer.h>
41#include <net/irda/qos.h>
42#include <net/irda/irlap.h>
43#include <net/irda/iriap.h>
44#include <net/irda/irlmp.h>
45#include <net/irda/irlmp_frame.h>
46
47static __u8 irlmp_find_free_slsap(void);
48static int irlmp_slsap_inuse(__u8 slsap_sel);
49
50/* Master structure */
51struct irlmp_cb *irlmp = NULL;
52
53/* These can be altered by the sysctl interface */
54int sysctl_discovery = 0;
55int sysctl_discovery_timeout = 3; /* 3 seconds by default */
56EXPORT_SYMBOL(sysctl_discovery_timeout);
57int sysctl_discovery_slots = 6; /* 6 slots by default */
58int sysctl_lap_keepalive_time = LM_IDLE_TIMEOUT * 1000 / HZ;
59char sysctl_devname[65];
60
61const char *irlmp_reasons[] = {
62 "ERROR, NOT USED",
63 "LM_USER_REQUEST",
64 "LM_LAP_DISCONNECT",
65 "LM_CONNECT_FAILURE",
66 "LM_LAP_RESET",
67 "LM_INIT_DISCONNECT",
68 "ERROR, NOT USED",
69};
70EXPORT_SYMBOL(irlmp_reasons);
71
72/*
73 * Function irlmp_init (void)
74 *
75 * Create (allocate) the main IrLMP structure
76 *
77 */
78int __init irlmp_init(void)
79{
80 IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
81 /* Initialize the irlmp structure. */
82 irlmp = kmalloc( sizeof(struct irlmp_cb), GFP_KERNEL);
83 if (irlmp == NULL)
84 return -ENOMEM;
85 memset(irlmp, 0, sizeof(struct irlmp_cb));
86
87 irlmp->magic = LMP_MAGIC;
88
89 irlmp->clients = hashbin_new(HB_LOCK);
90 irlmp->services = hashbin_new(HB_LOCK);
91 irlmp->links = hashbin_new(HB_LOCK);
92 irlmp->unconnected_lsaps = hashbin_new(HB_LOCK);
93 irlmp->cachelog = hashbin_new(HB_NOLOCK);
94
95 if ((irlmp->clients == NULL) ||
96 (irlmp->services == NULL) ||
97 (irlmp->links == NULL) ||
98 (irlmp->unconnected_lsaps == NULL) ||
99 (irlmp->cachelog == NULL)) {
100 return -ENOMEM;
101 }
102
103 spin_lock_init(&irlmp->cachelog->hb_spinlock);
104
105 irlmp->last_lsap_sel = 0x0f; /* Reserved 0x00-0x0f */
106 strcpy(sysctl_devname, "Linux");
107
108 /* Do discovery every 3 seconds */
109 init_timer(&irlmp->discovery_timer);
110 irlmp_start_discovery_timer(irlmp, sysctl_discovery_timeout*HZ);
111
112 return 0;
113}
114
115/*
116 * Function irlmp_cleanup (void)
117 *
118 * Remove IrLMP layer
119 *
120 */
121void __exit irlmp_cleanup(void)
122{
123 /* Check for main structure */
124 IRDA_ASSERT(irlmp != NULL, return;);
125 IRDA_ASSERT(irlmp->magic == LMP_MAGIC, return;);
126
127 del_timer(&irlmp->discovery_timer);
128
129 hashbin_delete(irlmp->links, (FREE_FUNC) kfree);
130 hashbin_delete(irlmp->unconnected_lsaps, (FREE_FUNC) kfree);
131 hashbin_delete(irlmp->clients, (FREE_FUNC) kfree);
132 hashbin_delete(irlmp->services, (FREE_FUNC) kfree);
133 hashbin_delete(irlmp->cachelog, (FREE_FUNC) kfree);
134
135 /* De-allocate main structure */
136 kfree(irlmp);
137 irlmp = NULL;
138}
139
140/*
141 * Function irlmp_open_lsap (slsap, notify)
142 *
143 * Register with IrLMP and create a local LSAP,
144 * returns handle to LSAP.
145 */
146struct lsap_cb *irlmp_open_lsap(__u8 slsap_sel, notify_t *notify, __u8 pid)
147{
148 struct lsap_cb *self;
149
150 IRDA_ASSERT(notify != NULL, return NULL;);
151 IRDA_ASSERT(irlmp != NULL, return NULL;);
152 IRDA_ASSERT(irlmp->magic == LMP_MAGIC, return NULL;);
153 IRDA_ASSERT(notify->instance != NULL, return NULL;);
154
155 /* Does the client care which Source LSAP selector it gets? */
156 if (slsap_sel == LSAP_ANY) {
157 slsap_sel = irlmp_find_free_slsap();
158 if (!slsap_sel)
159 return NULL;
160 } else if (irlmp_slsap_inuse(slsap_sel))
161 return NULL;
162
163 /* Allocate new instance of a LSAP connection */
164 self = kmalloc(sizeof(struct lsap_cb), GFP_ATOMIC);
165 if (self == NULL) {
166 IRDA_ERROR("%s: can't allocate memory\n", __FUNCTION__);
167 return NULL;
168 }
169 memset(self, 0, sizeof(struct lsap_cb));
170
171 self->magic = LMP_LSAP_MAGIC;
172 self->slsap_sel = slsap_sel;
173
174 /* Fix connectionless LSAP's */
175 if (slsap_sel == LSAP_CONNLESS) {
176#ifdef CONFIG_IRDA_ULTRA
177 self->dlsap_sel = LSAP_CONNLESS;
178 self->pid = pid;
179#endif /* CONFIG_IRDA_ULTRA */
180 } else
181 self->dlsap_sel = LSAP_ANY;
182 /* self->connected = FALSE; -> already NULL via memset() */
183
184 init_timer(&self->watchdog_timer);
185
186 self->notify = *notify;
187
188 self->lsap_state = LSAP_DISCONNECTED;
189
190 /* Insert into queue of unconnected LSAPs */
191 hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self,
192 (long) self, NULL);
193
194 return self;
195}
196EXPORT_SYMBOL(irlmp_open_lsap);
197
198/*
199 * Function __irlmp_close_lsap (self)
200 *
201 * Remove an instance of LSAP
202 */
203static void __irlmp_close_lsap(struct lsap_cb *self)
204{
205 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
206
207 IRDA_ASSERT(self != NULL, return;);
208 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
209
210 /*
211 * Set some of the variables to preset values
212 */
213 self->magic = 0;
214 del_timer(&self->watchdog_timer); /* Important! */
215
216 if (self->conn_skb)
217 dev_kfree_skb(self->conn_skb);
218
219 kfree(self);
220}
221
222/*
223 * Function irlmp_close_lsap (self)
224 *
225 * Close and remove LSAP
226 *
227 */
228void irlmp_close_lsap(struct lsap_cb *self)
229{
230 struct lap_cb *lap;
231 struct lsap_cb *lsap = NULL;
232
233 IRDA_ASSERT(self != NULL, return;);
234 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
235
236 /*
237 * Find out if we should remove this LSAP from a link or from the
238 * list of unconnected lsaps (not associated with a link)
239 */
240 lap = self->lap;
241 if (lap) {
242 IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, return;);
243 /* We might close a LSAP before it has completed the
244 * connection setup. In those case, higher layers won't
245 * send a proper disconnect request. Harmless, except
246 * that we will forget to close LAP... - Jean II */
247 if(self->lsap_state != LSAP_DISCONNECTED) {
248 self->lsap_state = LSAP_DISCONNECTED;
249 irlmp_do_lap_event(self->lap,
250 LM_LAP_DISCONNECT_REQUEST, NULL);
251 }
252 /* Now, remove from the link */
253 lsap = hashbin_remove(lap->lsaps, (long) self, NULL);
254#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
255 lap->cache.valid = FALSE;
256#endif
257 }
258 self->lap = NULL;
259 /* Check if we found the LSAP! If not then try the unconnected lsaps */
260 if (!lsap) {
261 lsap = hashbin_remove(irlmp->unconnected_lsaps, (long) self,
262 NULL);
263 }
264 if (!lsap) {
265 IRDA_DEBUG(0,
266 "%s(), Looks like somebody has removed me already!\n",
267 __FUNCTION__);
268 return;
269 }
270 __irlmp_close_lsap(self);
271}
272EXPORT_SYMBOL(irlmp_close_lsap);
273
274/*
275 * Function irlmp_register_irlap (saddr, notify)
276 *
277 * Register IrLAP layer with IrLMP. There is possible to have multiple
278 * instances of the IrLAP layer, each connected to different IrDA ports
279 *
280 */
281void irlmp_register_link(struct irlap_cb *irlap, __u32 saddr, notify_t *notify)
282{
283 struct lap_cb *lap;
284
285 IRDA_ASSERT(irlmp != NULL, return;);
286 IRDA_ASSERT(irlmp->magic == LMP_MAGIC, return;);
287 IRDA_ASSERT(notify != NULL, return;);
288
289 /*
290 * Allocate new instance of a LSAP connection
291 */
292 lap = kmalloc(sizeof(struct lap_cb), GFP_KERNEL);
293 if (lap == NULL) {
294 IRDA_ERROR("%s: unable to kmalloc\n", __FUNCTION__);
295 return;
296 }
297 memset(lap, 0, sizeof(struct lap_cb));
298
299 lap->irlap = irlap;
300 lap->magic = LMP_LAP_MAGIC;
301 lap->saddr = saddr;
302 lap->daddr = DEV_ADDR_ANY;
303#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
304 lap->cache.valid = FALSE;
305#endif
306 lap->lsaps = hashbin_new(HB_LOCK);
307 if (lap->lsaps == NULL) {
308 IRDA_WARNING("%s(), unable to kmalloc lsaps\n", __FUNCTION__);
309 kfree(lap);
310 return;
311 }
312
313 lap->lap_state = LAP_STANDBY;
314
315 init_timer(&lap->idle_timer);
316
317 /*
318 * Insert into queue of LMP links
319 */
320 hashbin_insert(irlmp->links, (irda_queue_t *) lap, lap->saddr, NULL);
321
322 /*
323 * We set only this variable so IrLAP can tell us on which link the
324 * different events happened on
325 */
326 irda_notify_init(notify);
327 notify->instance = lap;
328}
329
330/*
331 * Function irlmp_unregister_irlap (saddr)
332 *
333 * IrLAP layer has been removed!
334 *
335 */
336void irlmp_unregister_link(__u32 saddr)
337{
338 struct lap_cb *link;
339
340 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
341
342 /* We must remove ourselves from the hashbin *first*. This ensure
343 * that no more LSAPs will be open on this link and no discovery
344 * will be triggered anymore. Jean II */
345 link = hashbin_remove(irlmp->links, saddr, NULL);
346 if (link) {
347 IRDA_ASSERT(link->magic == LMP_LAP_MAGIC, return;);
348
349 /* Kill all the LSAPs on this link. Jean II */
350 link->reason = LAP_DISC_INDICATION;
351 link->daddr = DEV_ADDR_ANY;
352 irlmp_do_lap_event(link, LM_LAP_DISCONNECT_INDICATION, NULL);
353
354 /* Remove all discoveries discovered at this link */
355 irlmp_expire_discoveries(irlmp->cachelog, link->saddr, TRUE);
356
357 /* Final cleanup */
358 del_timer(&link->idle_timer);
359 link->magic = 0;
360 kfree(link);
361 }
362}
363
364/*
365 * Function irlmp_connect_request (handle, dlsap, userdata)
366 *
367 * Connect with a peer LSAP
368 *
369 */
370int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
371 __u32 saddr, __u32 daddr,
372 struct qos_info *qos, struct sk_buff *userdata)
373{
374 struct sk_buff *tx_skb = userdata;
375 struct lap_cb *lap;
376 struct lsap_cb *lsap;
377 int ret;
378
379 IRDA_ASSERT(self != NULL, return -EBADR;);
380 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -EBADR;);
381
382 IRDA_DEBUG(2,
383 "%s(), slsap_sel=%02x, dlsap_sel=%02x, saddr=%08x, daddr=%08x\n",
384 __FUNCTION__, self->slsap_sel, dlsap_sel, saddr, daddr);
385
386 if (test_bit(0, &self->connected)) {
387 ret = -EISCONN;
388 goto err;
389 }
390
391 /* Client must supply destination device address */
392 if (!daddr) {
393 ret = -EINVAL;
394 goto err;
395 }
396
397 /* Any userdata? */
398 if (tx_skb == NULL) {
399 tx_skb = dev_alloc_skb(64);
400 if (!tx_skb)
401 return -ENOMEM;
402
403 skb_reserve(tx_skb, LMP_MAX_HEADER);
404 }
405
406 /* Make room for MUX control header (3 bytes) */
407 IRDA_ASSERT(skb_headroom(tx_skb) >= LMP_CONTROL_HEADER, return -1;);
408 skb_push(tx_skb, LMP_CONTROL_HEADER);
409
410 self->dlsap_sel = dlsap_sel;
411
412 /*
413 * Find the link to where we should try to connect since there may
414 * be more than one IrDA port on this machine. If the client has
415 * passed us the saddr (and already knows which link to use), then
416 * we use that to find the link, if not then we have to look in the
417 * discovery log and check if any of the links has discovered a
418 * device with the given daddr
419 */
420 if ((!saddr) || (saddr == DEV_ADDR_ANY)) {
421 discovery_t *discovery;
422 unsigned long flags;
423
424 spin_lock_irqsave(&irlmp->cachelog->hb_spinlock, flags);
425 if (daddr != DEV_ADDR_ANY)
426 discovery = hashbin_find(irlmp->cachelog, daddr, NULL);
427 else {
428 IRDA_DEBUG(2, "%s(), no daddr\n", __FUNCTION__);
429 discovery = (discovery_t *)
430 hashbin_get_first(irlmp->cachelog);
431 }
432
433 if (discovery) {
434 saddr = discovery->data.saddr;
435 daddr = discovery->data.daddr;
436 }
437 spin_unlock_irqrestore(&irlmp->cachelog->hb_spinlock, flags);
438 }
439 lap = hashbin_lock_find(irlmp->links, saddr, NULL);
440 if (lap == NULL) {
441 IRDA_DEBUG(1, "%s(), Unable to find a usable link!\n", __FUNCTION__);
442 ret = -EHOSTUNREACH;
443 goto err;
444 }
445
446 /* Check if LAP is disconnected or already connected */
447 if (lap->daddr == DEV_ADDR_ANY)
448 lap->daddr = daddr;
449 else if (lap->daddr != daddr) {
450 /* Check if some LSAPs are active on this LAP */
451 if (HASHBIN_GET_SIZE(lap->lsaps) == 0) {
452 /* No active connection, but LAP hasn't been
453 * disconnected yet (waiting for timeout in LAP).
454 * Maybe we could give LAP a bit of help in this case.
455 */
456 IRDA_DEBUG(0, "%s(), sorry, but I'm waiting for LAP to timeout!\n", __FUNCTION__);
457 ret = -EAGAIN;
458 goto err;
459 }
460
461 /* LAP is already connected to a different node, and LAP
462 * can only talk to one node at a time */
463 IRDA_DEBUG(0, "%s(), sorry, but link is busy!\n", __FUNCTION__);
464 ret = -EBUSY;
465 goto err;
466 }
467
468 self->lap = lap;
469
470 /*
471 * Remove LSAP from list of unconnected LSAPs and insert it into the
472 * list of connected LSAPs for the particular link
473 */
474 lsap = hashbin_remove(irlmp->unconnected_lsaps, (long) self, NULL);
475
476 IRDA_ASSERT(lsap != NULL, return -1;);
477 IRDA_ASSERT(lsap->magic == LMP_LSAP_MAGIC, return -1;);
478 IRDA_ASSERT(lsap->lap != NULL, return -1;);
479 IRDA_ASSERT(lsap->lap->magic == LMP_LAP_MAGIC, return -1;);
480
481 hashbin_insert(self->lap->lsaps, (irda_queue_t *) self, (long) self,
482 NULL);
483
484 set_bit(0, &self->connected); /* TRUE */
485
486 /*
487 * User supplied qos specifications?
488 */
489 if (qos)
490 self->qos = *qos;
491
492 irlmp_do_lsap_event(self, LM_CONNECT_REQUEST, tx_skb);
493
494 /* Drop reference count - see irlap_data_request(). */
495 dev_kfree_skb(tx_skb);
496
497 return 0;
498
499err:
500 /* Cleanup */
501 if(tx_skb)
502 dev_kfree_skb(tx_skb);
503 return ret;
504}
505EXPORT_SYMBOL(irlmp_connect_request);
506
507/*
508 * Function irlmp_connect_indication (self)
509 *
510 * Incoming connection
511 *
512 */
513void irlmp_connect_indication(struct lsap_cb *self, struct sk_buff *skb)
514{
515 int max_seg_size;
516 int lap_header_size;
517 int max_header_size;
518
519 IRDA_ASSERT(self != NULL, return;);
520 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
521 IRDA_ASSERT(skb != NULL, return;);
522 IRDA_ASSERT(self->lap != NULL, return;);
523
524 IRDA_DEBUG(2, "%s(), slsap_sel=%02x, dlsap_sel=%02x\n",
525 __FUNCTION__, self->slsap_sel, self->dlsap_sel);
526
527 /* Note : self->lap is set in irlmp_link_data_indication(),
528 * (case CONNECT_CMD:) because we have no way to set it here.
529 * Similarly, self->dlsap_sel is usually set in irlmp_find_lsap().
530 * Jean II */
531
532 self->qos = *self->lap->qos;
533
534 max_seg_size = self->lap->qos->data_size.value-LMP_HEADER;
535 lap_header_size = IRLAP_GET_HEADER_SIZE(self->lap->irlap);
536 max_header_size = LMP_HEADER + lap_header_size;
537
538 /* Hide LMP_CONTROL_HEADER header from layer above */
539 skb_pull(skb, LMP_CONTROL_HEADER);
540
541 if (self->notify.connect_indication) {
542 /* Don't forget to refcount it - see irlap_driver_rcv(). */
543 skb_get(skb);
544 self->notify.connect_indication(self->notify.instance, self,
545 &self->qos, max_seg_size,
546 max_header_size, skb);
547 }
548}
549
550/*
551 * Function irlmp_connect_response (handle, userdata)
552 *
553 * Service user is accepting connection
554 *
555 */
556int irlmp_connect_response(struct lsap_cb *self, struct sk_buff *userdata)
557{
558 IRDA_ASSERT(self != NULL, return -1;);
559 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
560 IRDA_ASSERT(userdata != NULL, return -1;);
561
562 /* We set the connected bit and move the lsap to the connected list
563 * in the state machine itself. Jean II */
564
565 IRDA_DEBUG(2, "%s(), slsap_sel=%02x, dlsap_sel=%02x\n",
566 __FUNCTION__, self->slsap_sel, self->dlsap_sel);
567
568 /* Make room for MUX control header (3 bytes) */
569 IRDA_ASSERT(skb_headroom(userdata) >= LMP_CONTROL_HEADER, return -1;);
570 skb_push(userdata, LMP_CONTROL_HEADER);
571
572 irlmp_do_lsap_event(self, LM_CONNECT_RESPONSE, userdata);
573
574 /* Drop reference count - see irlap_data_request(). */
575 dev_kfree_skb(userdata);
576
577 return 0;
578}
579EXPORT_SYMBOL(irlmp_connect_response);
580
581/*
582 * Function irlmp_connect_confirm (handle, skb)
583 *
584 * LSAP connection confirmed peer device!
585 */
586void irlmp_connect_confirm(struct lsap_cb *self, struct sk_buff *skb)
587{
588 int max_header_size;
589 int lap_header_size;
590 int max_seg_size;
591
592 IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
593
594 IRDA_ASSERT(skb != NULL, return;);
595 IRDA_ASSERT(self != NULL, return;);
596 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
597 IRDA_ASSERT(self->lap != NULL, return;);
598
599 self->qos = *self->lap->qos;
600
601 max_seg_size = self->lap->qos->data_size.value-LMP_HEADER;
602 lap_header_size = IRLAP_GET_HEADER_SIZE(self->lap->irlap);
603 max_header_size = LMP_HEADER + lap_header_size;
604
605 IRDA_DEBUG(2, "%s(), max_header_size=%d\n",
606 __FUNCTION__, max_header_size);
607
608 /* Hide LMP_CONTROL_HEADER header from layer above */
609 skb_pull(skb, LMP_CONTROL_HEADER);
610
611 if (self->notify.connect_confirm) {
612 /* Don't forget to refcount it - see irlap_driver_rcv() */
613 skb_get(skb);
614 self->notify.connect_confirm(self->notify.instance, self,
615 &self->qos, max_seg_size,
616 max_header_size, skb);
617 }
618}
619
620/*
621 * Function irlmp_dup (orig, instance)
622 *
623 * Duplicate LSAP, can be used by servers to confirm a connection on a
624 * new LSAP so it can keep listening on the old one.
625 *
626 */
627struct lsap_cb *irlmp_dup(struct lsap_cb *orig, void *instance)
628{
629 struct lsap_cb *new;
630 unsigned long flags;
631
632 IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
633
634 spin_lock_irqsave(&irlmp->unconnected_lsaps->hb_spinlock, flags);
635
636 /* Only allowed to duplicate unconnected LSAP's, and only LSAPs
637 * that have received a connect indication. Jean II */
638 if ((!hashbin_find(irlmp->unconnected_lsaps, (long) orig, NULL)) ||
639 (orig->lap == NULL)) {
640 IRDA_DEBUG(0, "%s(), invalid LSAP (wrong state)\n",
641 __FUNCTION__);
642 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock,
643 flags);
644 return NULL;
645 }
646
647 /* Allocate a new instance */
648 new = kmalloc(sizeof(struct lsap_cb), GFP_ATOMIC);
649 if (!new) {
650 IRDA_DEBUG(0, "%s(), unable to kmalloc\n", __FUNCTION__);
651 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock,
652 flags);
653 return NULL;
654 }
655 /* Dup */
656 memcpy(new, orig, sizeof(struct lsap_cb));
657 /* new->lap = orig->lap; => done in the memcpy() */
658 /* new->slsap_sel = orig->slsap_sel; => done in the memcpy() */
659 new->conn_skb = NULL;
660
661 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, flags);
662
663 /* Not everything is the same */
664 new->notify.instance = instance;
665
666 init_timer(&new->watchdog_timer);
667
668 hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) new,
669 (long) new, NULL);
670
671#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
672 /* Make sure that we invalidate the LSAP cache */
673 new->lap->cache.valid = FALSE;
674#endif /* CONFIG_IRDA_CACHE_LAST_LSAP */
675
676 return new;
677}
678EXPORT_SYMBOL(irlmp_dup);
679
680/*
681 * Function irlmp_disconnect_request (handle, userdata)
682 *
683 * The service user is requesting disconnection, this will not remove the
684 * LSAP, but only mark it as disconnected
685 */
686int irlmp_disconnect_request(struct lsap_cb *self, struct sk_buff *userdata)
687{
688 struct lsap_cb *lsap;
689
690 IRDA_ASSERT(self != NULL, return -1;);
691 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
692 IRDA_ASSERT(userdata != NULL, return -1;);
693
694 /* Already disconnected ?
695 * There is a race condition between irlmp_disconnect_indication()
696 * and us that might mess up the hashbins below. This fixes it.
697 * Jean II */
698 if (! test_and_clear_bit(0, &self->connected)) {
699 IRDA_DEBUG(0, "%s(), already disconnected!\n", __FUNCTION__);
700 dev_kfree_skb(userdata);
701 return -1;
702 }
703
704 skb_push(userdata, LMP_CONTROL_HEADER);
705
706 /*
707 * Do the event before the other stuff since we must know
708 * which lap layer that the frame should be transmitted on
709 */
710 irlmp_do_lsap_event(self, LM_DISCONNECT_REQUEST, userdata);
711
712 /* Drop reference count - see irlap_data_request(). */
713 dev_kfree_skb(userdata);
714
715 /*
716 * Remove LSAP from list of connected LSAPs for the particular link
717 * and insert it into the list of unconnected LSAPs
718 */
719 IRDA_ASSERT(self->lap != NULL, return -1;);
720 IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
721 IRDA_ASSERT(self->lap->lsaps != NULL, return -1;);
722
723 lsap = hashbin_remove(self->lap->lsaps, (long) self, NULL);
724#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
725 self->lap->cache.valid = FALSE;
726#endif
727
728 IRDA_ASSERT(lsap != NULL, return -1;);
729 IRDA_ASSERT(lsap->magic == LMP_LSAP_MAGIC, return -1;);
730 IRDA_ASSERT(lsap == self, return -1;);
731
732 hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) self,
733 (long) self, NULL);
734
735 /* Reset some values */
736 self->dlsap_sel = LSAP_ANY;
737 self->lap = NULL;
738
739 return 0;
740}
741EXPORT_SYMBOL(irlmp_disconnect_request);
742
743/*
744 * Function irlmp_disconnect_indication (reason, userdata)
745 *
746 * LSAP is being closed!
747 */
748void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason,
749 struct sk_buff *skb)
750{
751 struct lsap_cb *lsap;
752
753 IRDA_DEBUG(1, "%s(), reason=%s\n", __FUNCTION__, irlmp_reasons[reason]);
754 IRDA_ASSERT(self != NULL, return;);
755 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
756
757 IRDA_DEBUG(3, "%s(), slsap_sel=%02x, dlsap_sel=%02x\n",
758 __FUNCTION__, self->slsap_sel, self->dlsap_sel);
759
760 /* Already disconnected ?
761 * There is a race condition between irlmp_disconnect_request()
762 * and us that might mess up the hashbins below. This fixes it.
763 * Jean II */
764 if (! test_and_clear_bit(0, &self->connected)) {
765 IRDA_DEBUG(0, "%s(), already disconnected!\n", __FUNCTION__);
766 return;
767 }
768
769 /*
770 * Remove association between this LSAP and the link it used
771 */
772 IRDA_ASSERT(self->lap != NULL, return;);
773 IRDA_ASSERT(self->lap->lsaps != NULL, return;);
774
775 lsap = hashbin_remove(self->lap->lsaps, (long) self, NULL);
776#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
777 self->lap->cache.valid = FALSE;
778#endif
779
780 IRDA_ASSERT(lsap != NULL, return;);
781 IRDA_ASSERT(lsap == self, return;);
782 hashbin_insert(irlmp->unconnected_lsaps, (irda_queue_t *) lsap,
783 (long) lsap, NULL);
784
785 self->dlsap_sel = LSAP_ANY;
786 self->lap = NULL;
787
788 /*
789 * Inform service user
790 */
791 if (self->notify.disconnect_indication) {
792 /* Don't forget to refcount it - see irlap_driver_rcv(). */
793 if(skb)
794 skb_get(skb);
795 self->notify.disconnect_indication(self->notify.instance,
796 self, reason, skb);
797 } else {
798 IRDA_DEBUG(0, "%s(), no handler\n", __FUNCTION__);
799 }
800}
801
802/*
803 * Function irlmp_do_expiry (void)
804 *
805 * Do a cleanup of the discovery log (remove old entries)
806 *
807 * Note : separate from irlmp_do_discovery() so that we can handle
808 * passive discovery properly.
809 */
810void irlmp_do_expiry(void)
811{
812 struct lap_cb *lap;
813
814 /*
815 * Expire discovery on all links which are *not* connected.
816 * On links which are connected, we can't do discovery
817 * anymore and can't refresh the log, so we freeze the
818 * discovery log to keep info about the device we are
819 * connected to.
820 * This info is mandatory if we want irlmp_connect_request()
821 * to work properly. - Jean II
822 */
823 lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
824 while (lap != NULL) {
825 IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, return;);
826
827 if (lap->lap_state == LAP_STANDBY) {
828 /* Expire discoveries discovered on this link */
829 irlmp_expire_discoveries(irlmp->cachelog, lap->saddr,
830 FALSE);
831 }
832 lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
833 }
834}
835
836/*
837 * Function irlmp_do_discovery (nslots)
838 *
839 * Do some discovery on all links
840 *
841 * Note : log expiry is done above.
842 */
843void irlmp_do_discovery(int nslots)
844{
845 struct lap_cb *lap;
846
847 /* Make sure the value is sane */
848 if ((nslots != 1) && (nslots != 6) && (nslots != 8) && (nslots != 16)){
849 IRDA_WARNING("%s: invalid value for number of slots!\n",
850 __FUNCTION__);
851 nslots = sysctl_discovery_slots = 8;
852 }
853
854 /* Construct new discovery info to be used by IrLAP, */
855 u16ho(irlmp->discovery_cmd.data.hints) = irlmp->hints.word;
856
857 /*
858 * Set character set for device name (we use ASCII), and
859 * copy device name. Remember to make room for a \0 at the
860 * end
861 */
862 irlmp->discovery_cmd.data.charset = CS_ASCII;
863 strncpy(irlmp->discovery_cmd.data.info, sysctl_devname,
864 NICKNAME_MAX_LEN);
865 irlmp->discovery_cmd.name_len = strlen(irlmp->discovery_cmd.data.info);
866 irlmp->discovery_cmd.nslots = nslots;
867
868 /*
869 * Try to send discovery packets on all links
870 */
871 lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
872 while (lap != NULL) {
873 IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, return;);
874
875 if (lap->lap_state == LAP_STANDBY) {
876 /* Try to discover */
877 irlmp_do_lap_event(lap, LM_LAP_DISCOVERY_REQUEST,
878 NULL);
879 }
880 lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
881 }
882}
883
884/*
885 * Function irlmp_discovery_request (nslots)
886 *
887 * Do a discovery of devices in front of the computer
888 *
889 * If the caller has registered a client discovery callback, this
890 * allow him to receive the full content of the discovery log through
891 * this callback (as normally he will receive only new discoveries).
892 */
893void irlmp_discovery_request(int nslots)
894{
895 /* Return current cached discovery log (in full) */
896 irlmp_discovery_confirm(irlmp->cachelog, DISCOVERY_LOG);
897
898 /*
899 * Start a single discovery operation if discovery is not already
900 * running
901 */
902 if (!sysctl_discovery) {
903 /* Check if user wants to override the default */
904 if (nslots == DISCOVERY_DEFAULT_SLOTS)
905 nslots = sysctl_discovery_slots;
906
907 irlmp_do_discovery(nslots);
908 /* Note : we never do expiry here. Expiry will run on the
909 * discovery timer regardless of the state of sysctl_discovery
910 * Jean II */
911 }
912}
913EXPORT_SYMBOL(irlmp_discovery_request);
914
915/*
916 * Function irlmp_get_discoveries (pn, mask, slots)
917 *
918 * Return the current discovery log
919 *
920 * If discovery is not enabled, you should call this function again
921 * after 1 or 2 seconds (i.e. after discovery has been done).
922 */
923struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask, int nslots)
924{
925 /* If discovery is not enabled, it's likely that the discovery log
926 * will be empty. So, we trigger a single discovery, so that next
927 * time the user call us there might be some results in the log.
928 * Jean II
929 */
930 if (!sysctl_discovery) {
931 /* Check if user wants to override the default */
932 if (nslots == DISCOVERY_DEFAULT_SLOTS)
933 nslots = sysctl_discovery_slots;
934
935 /* Start discovery - will complete sometime later */
936 irlmp_do_discovery(nslots);
937 /* Note : we never do expiry here. Expiry will run on the
938 * discovery timer regardless of the state of sysctl_discovery
939 * Jean II */
940 }
941
942 /* Return current cached discovery log */
943 return(irlmp_copy_discoveries(irlmp->cachelog, pn, mask, TRUE));
944}
945EXPORT_SYMBOL(irlmp_get_discoveries);
946
947/*
948 * Function irlmp_notify_client (log)
949 *
950 * Notify all about discovered devices
951 *
952 * Clients registered with IrLMP are :
953 * o IrComm
954 * o IrLAN
955 * o Any socket (in any state - ouch, that may be a lot !)
956 * The client may have defined a callback to be notified in case of
957 * partial/selective discovery based on the hints that it passed to IrLMP.
958 */
959static inline void
960irlmp_notify_client(irlmp_client_t *client,
961 hashbin_t *log, DISCOVERY_MODE mode)
962{
963 discinfo_t *discoveries; /* Copy of the discovery log */
964 int number; /* Number of nodes in the log */
965 int i;
966
967 IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
968
969 /* Check if client wants or not partial/selective log (optimisation) */
970 if (!client->disco_callback)
971 return;
972
973 /*
974 * Locking notes :
975 * the old code was manipulating the log directly, which was
976 * very racy. Now, we use copy_discoveries, that protects
977 * itself while dumping the log for us.
978 * The overhead of the copy is compensated by the fact that
979 * we only pass new discoveries in normal mode and don't
980 * pass the same old entry every 3s to the caller as we used
981 * to do (virtual function calling is expensive).
982 * Jean II
983 */
984
985 /*
986 * Now, check all discovered devices (if any), and notify client
987 * only about the services that the client is interested in
988 * We also notify only about the new devices unless the caller
989 * explicitly request a dump of the log. Jean II
990 */
991 discoveries = irlmp_copy_discoveries(log, &number,
992 client->hint_mask.word,
993 (mode == DISCOVERY_LOG));
994 /* Check if the we got some results */
995 if (discoveries == NULL)
996 return; /* No nodes discovered */
997
998 /* Pass all entries to the listener */
999 for(i = 0; i < number; i++)
1000 client->disco_callback(&(discoveries[i]), mode, client->priv);
1001
1002 /* Free up our buffer */
1003 kfree(discoveries);
1004}
1005
1006/*
1007 * Function irlmp_discovery_confirm ( self, log)
1008 *
1009 * Some device(s) answered to our discovery request! Check to see which
1010 * device it is, and give indication to the client(s)
1011 *
1012 */
1013void irlmp_discovery_confirm(hashbin_t *log, DISCOVERY_MODE mode)
1014{
1015 irlmp_client_t *client;
1016 irlmp_client_t *client_next;
1017
1018 IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
1019
1020 IRDA_ASSERT(log != NULL, return;);
1021
1022 if (!(HASHBIN_GET_SIZE(log)))
1023 return;
1024
1025 /* For each client - notify callback may touch client list */
1026 client = (irlmp_client_t *) hashbin_get_first(irlmp->clients);
1027 while (NULL != hashbin_find_next(irlmp->clients, (long) client, NULL,
1028 (void *) &client_next) ) {
1029 /* Check if we should notify client */
1030 irlmp_notify_client(client, log, mode);
1031
1032 client = client_next;
1033 }
1034}
1035
1036/*
1037 * Function irlmp_discovery_expiry (expiry)
1038 *
1039 * This device is no longer been discovered, and therefore it is being
1040 * purged from the discovery log. Inform all clients who have
1041 * registered for this event...
1042 *
1043 * Note : called exclusively from discovery.c
1044 * Note : this is no longer called under discovery spinlock, so the
1045 * client can do whatever he wants in the callback.
1046 */
1047void irlmp_discovery_expiry(discinfo_t *expiries, int number)
1048{
1049 irlmp_client_t *client;
1050 irlmp_client_t *client_next;
1051 int i;
1052
1053 IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
1054
1055 IRDA_ASSERT(expiries != NULL, return;);
1056
1057 /* For each client - notify callback may touch client list */
1058 client = (irlmp_client_t *) hashbin_get_first(irlmp->clients);
1059 while (NULL != hashbin_find_next(irlmp->clients, (long) client, NULL,
1060 (void *) &client_next) ) {
1061
1062 /* Pass all entries to the listener */
1063 for(i = 0; i < number; i++) {
1064 /* Check if we should notify client */
1065 if ((client->expir_callback) &&
1066 (client->hint_mask.word & u16ho(expiries[i].hints)
1067 & 0x7f7f) )
1068 client->expir_callback(&(expiries[i]),
1069 EXPIRY_TIMEOUT,
1070 client->priv);
1071 }
1072
1073 /* Next client */
1074 client = client_next;
1075 }
1076}
1077
1078/*
1079 * Function irlmp_get_discovery_response ()
1080 *
1081 * Used by IrLAP to get the discovery info it needs when answering
1082 * discovery requests by other devices.
1083 */
1084discovery_t *irlmp_get_discovery_response(void)
1085{
1086 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1087
1088 IRDA_ASSERT(irlmp != NULL, return NULL;);
1089
1090 u16ho(irlmp->discovery_rsp.data.hints) = irlmp->hints.word;
1091
1092 /*
1093 * Set character set for device name (we use ASCII), and
1094 * copy device name. Remember to make room for a \0 at the
1095 * end
1096 */
1097 irlmp->discovery_rsp.data.charset = CS_ASCII;
1098
1099 strncpy(irlmp->discovery_rsp.data.info, sysctl_devname,
1100 NICKNAME_MAX_LEN);
1101 irlmp->discovery_rsp.name_len = strlen(irlmp->discovery_rsp.data.info);
1102
1103 return &irlmp->discovery_rsp;
1104}
1105
1106/*
1107 * Function irlmp_data_request (self, skb)
1108 *
1109 * Send some data to peer device
1110 *
1111 * Note on skb management :
1112 * After calling the lower layers of the IrDA stack, we always
1113 * kfree() the skb, which drop the reference count (and potentially
1114 * destroy it).
1115 * IrLMP and IrLAP may queue the packet, and in those cases will need
1116 * to use skb_get() to keep it around.
1117 * Jean II
1118 */
1119int irlmp_data_request(struct lsap_cb *self, struct sk_buff *userdata)
1120{
1121 int ret;
1122
1123 IRDA_ASSERT(self != NULL, return -1;);
1124 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
1125
1126 /* Make room for MUX header */
1127 IRDA_ASSERT(skb_headroom(userdata) >= LMP_HEADER, return -1;);
1128 skb_push(userdata, LMP_HEADER);
1129
1130 ret = irlmp_do_lsap_event(self, LM_DATA_REQUEST, userdata);
1131
1132 /* Drop reference count - see irlap_data_request(). */
1133 dev_kfree_skb(userdata);
1134
1135 return ret;
1136}
1137EXPORT_SYMBOL(irlmp_data_request);
1138
1139/*
1140 * Function irlmp_data_indication (handle, skb)
1141 *
1142 * Got data from LAP layer so pass it up to upper layer
1143 *
1144 */
1145void irlmp_data_indication(struct lsap_cb *self, struct sk_buff *skb)
1146{
1147 /* Hide LMP header from layer above */
1148 skb_pull(skb, LMP_HEADER);
1149
1150 if (self->notify.data_indication) {
1151 /* Don't forget to refcount it - see irlap_driver_rcv(). */
1152 skb_get(skb);
1153 self->notify.data_indication(self->notify.instance, self, skb);
1154 }
1155}
1156
1157/*
1158 * Function irlmp_udata_request (self, skb)
1159 */
1160int irlmp_udata_request(struct lsap_cb *self, struct sk_buff *userdata)
1161{
1162 int ret;
1163
1164 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1165
1166 IRDA_ASSERT(userdata != NULL, return -1;);
1167
1168 /* Make room for MUX header */
1169 IRDA_ASSERT(skb_headroom(userdata) >= LMP_HEADER, return -1;);
1170 skb_push(userdata, LMP_HEADER);
1171
1172 ret = irlmp_do_lsap_event(self, LM_UDATA_REQUEST, userdata);
1173
1174 /* Drop reference count - see irlap_data_request(). */
1175 dev_kfree_skb(userdata);
1176
1177 return ret;
1178}
1179
1180/*
1181 * Function irlmp_udata_indication (self, skb)
1182 *
1183 * Send unreliable data (but still within the connection)
1184 *
1185 */
1186void irlmp_udata_indication(struct lsap_cb *self, struct sk_buff *skb)
1187{
1188 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1189
1190 IRDA_ASSERT(self != NULL, return;);
1191 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
1192 IRDA_ASSERT(skb != NULL, return;);
1193
1194 /* Hide LMP header from layer above */
1195 skb_pull(skb, LMP_HEADER);
1196
1197 if (self->notify.udata_indication) {
1198 /* Don't forget to refcount it - see irlap_driver_rcv(). */
1199 skb_get(skb);
1200 self->notify.udata_indication(self->notify.instance, self,
1201 skb);
1202 }
1203}
1204
1205/*
1206 * Function irlmp_connless_data_request (self, skb)
1207 */
1208#ifdef CONFIG_IRDA_ULTRA
1209int irlmp_connless_data_request(struct lsap_cb *self, struct sk_buff *userdata,
1210 __u8 pid)
1211{
1212 struct sk_buff *clone_skb;
1213 struct lap_cb *lap;
1214
1215 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1216
1217 IRDA_ASSERT(userdata != NULL, return -1;);
1218
1219 /* Make room for MUX and PID header */
1220 IRDA_ASSERT(skb_headroom(userdata) >= LMP_HEADER+LMP_PID_HEADER,
1221 return -1;);
1222
1223 /* Insert protocol identifier */
1224 skb_push(userdata, LMP_PID_HEADER);
1225 if(self != NULL)
1226 userdata->data[0] = self->pid;
1227 else
1228 userdata->data[0] = pid;
1229
1230 /* Connectionless sockets must use 0x70 */
1231 skb_push(userdata, LMP_HEADER);
1232 userdata->data[0] = userdata->data[1] = LSAP_CONNLESS;
1233
1234 /* Try to send Connectionless packets out on all links */
1235 lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
1236 while (lap != NULL) {
1237 IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, return -1;);
1238
1239 clone_skb = skb_clone(userdata, GFP_ATOMIC);
1240 if (!clone_skb) {
1241 dev_kfree_skb(userdata);
1242 return -ENOMEM;
1243 }
1244
1245 irlap_unitdata_request(lap->irlap, clone_skb);
1246 /* irlap_unitdata_request() don't increase refcount,
1247 * so no dev_kfree_skb() - Jean II */
1248
1249 lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
1250 }
1251 dev_kfree_skb(userdata);
1252
1253 return 0;
1254}
1255#endif /* CONFIG_IRDA_ULTRA */
1256
1257/*
1258 * Function irlmp_connless_data_indication (self, skb)
1259 *
1260 * Receive unreliable data outside any connection. Mostly used by Ultra
1261 *
1262 */
1263#ifdef CONFIG_IRDA_ULTRA
1264void irlmp_connless_data_indication(struct lsap_cb *self, struct sk_buff *skb)
1265{
1266 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1267
1268 IRDA_ASSERT(self != NULL, return;);
1269 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
1270 IRDA_ASSERT(skb != NULL, return;);
1271
1272 /* Hide LMP and PID header from layer above */
1273 skb_pull(skb, LMP_HEADER+LMP_PID_HEADER);
1274
1275 if (self->notify.udata_indication) {
1276 /* Don't forget to refcount it - see irlap_driver_rcv(). */
1277 skb_get(skb);
1278 self->notify.udata_indication(self->notify.instance, self,
1279 skb);
1280 }
1281}
1282#endif /* CONFIG_IRDA_ULTRA */
1283
1284/*
1285 * Propagate status indication from LAP to LSAPs (via LMP)
1286 * This don't trigger any change of state in lap_cb, lmp_cb or lsap_cb,
1287 * and the event is stateless, therefore we can bypass both state machines
1288 * and send the event direct to the LSAP user.
1289 * Jean II
1290 */
1291void irlmp_status_indication(struct lap_cb *self,
1292 LINK_STATUS link, LOCK_STATUS lock)
1293{
1294 struct lsap_cb *next;
1295 struct lsap_cb *curr;
1296
1297 /* Send status_indication to all LSAPs using this link */
1298 curr = (struct lsap_cb *) hashbin_get_first( self->lsaps);
1299 while (NULL != hashbin_find_next(self->lsaps, (long) curr, NULL,
1300 (void *) &next) ) {
1301 IRDA_ASSERT(curr->magic == LMP_LSAP_MAGIC, return;);
1302 /*
1303 * Inform service user if he has requested it
1304 */
1305 if (curr->notify.status_indication != NULL)
1306 curr->notify.status_indication(curr->notify.instance,
1307 link, lock);
1308 else
1309 IRDA_DEBUG(2, "%s(), no handler\n", __FUNCTION__);
1310
1311 curr = next;
1312 }
1313}
1314
1315/*
1316 * Receive flow control indication from LAP.
1317 * LAP want us to send it one more frame. We implement a simple round
1318 * robin scheduler between the active sockets so that we get a bit of
1319 * fairness. Note that the round robin is far from perfect, but it's
1320 * better than nothing.
1321 * We then poll the selected socket so that we can do synchronous
1322 * refilling of IrLAP (which allow to minimise the number of buffers).
1323 * Jean II
1324 */
1325void irlmp_flow_indication(struct lap_cb *self, LOCAL_FLOW flow)
1326{
1327 struct lsap_cb *next;
1328 struct lsap_cb *curr;
1329 int lsap_todo;
1330
1331 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
1332 IRDA_ASSERT(flow == FLOW_START, return;);
1333
1334 /* Get the number of lsap. That's the only safe way to know
1335 * that we have looped around... - Jean II */
1336 lsap_todo = HASHBIN_GET_SIZE(self->lsaps);
1337 IRDA_DEBUG(4, "%s() : %d lsaps to scan\n", __FUNCTION__, lsap_todo);
1338
1339 /* Poll lsap in order until the queue is full or until we
1340 * tried them all.
1341 * Most often, the current LSAP will have something to send,
1342 * so we will go through this loop only once. - Jean II */
1343 while((lsap_todo--) &&
1344 (IRLAP_GET_TX_QUEUE_LEN(self->irlap) < LAP_HIGH_THRESHOLD)) {
1345 /* Try to find the next lsap we should poll. */
1346 next = self->flow_next;
1347 /* If we have no lsap, restart from first one */
1348 if(next == NULL)
1349 next = (struct lsap_cb *) hashbin_get_first(self->lsaps);
1350 /* Verify current one and find the next one */
1351 curr = hashbin_find_next(self->lsaps, (long) next, NULL,
1352 (void *) &self->flow_next);
1353 /* Uh-oh... Paranoia */
1354 if(curr == NULL)
1355 break;
1356 IRDA_DEBUG(4, "%s() : curr is %p, next was %p and is now %p, still %d to go - queue len = %d\n", __FUNCTION__, curr, next, self->flow_next, lsap_todo, IRLAP_GET_TX_QUEUE_LEN(self->irlap));
1357
1358 /* Inform lsap user that it can send one more packet. */
1359 if (curr->notify.flow_indication != NULL)
1360 curr->notify.flow_indication(curr->notify.instance,
1361 curr, flow);
1362 else
1363 IRDA_DEBUG(1, "%s(), no handler\n", __FUNCTION__);
1364 }
1365}
1366
1367#if 0
1368/*
1369 * Function irlmp_hint_to_service (hint)
1370 *
1371 * Returns a list of all servics contained in the given hint bits. This
1372 * function assumes that the hint bits have the size of two bytes only
1373 */
1374__u8 *irlmp_hint_to_service(__u8 *hint)
1375{
1376 __u8 *service;
1377 int i = 0;
1378
1379 /*
1380 * Allocate array to store services in. 16 entries should be safe
1381 * since we currently only support 2 hint bytes
1382 */
1383 service = kmalloc(16, GFP_ATOMIC);
1384 if (!service) {
1385 IRDA_DEBUG(1, "%s(), Unable to kmalloc!\n", __FUNCTION__);
1386 return NULL;
1387 }
1388
1389 if (!hint[0]) {
1390 IRDA_DEBUG(1, "<None>\n");
1391 kfree(service);
1392 return NULL;
1393 }
1394 if (hint[0] & HINT_PNP)
1395 IRDA_DEBUG(1, "PnP Compatible ");
1396 if (hint[0] & HINT_PDA)
1397 IRDA_DEBUG(1, "PDA/Palmtop ");
1398 if (hint[0] & HINT_COMPUTER)
1399 IRDA_DEBUG(1, "Computer ");
1400 if (hint[0] & HINT_PRINTER) {
1401 IRDA_DEBUG(1, "Printer ");
1402 service[i++] = S_PRINTER;
1403 }
1404 if (hint[0] & HINT_MODEM)
1405 IRDA_DEBUG(1, "Modem ");
1406 if (hint[0] & HINT_FAX)
1407 IRDA_DEBUG(1, "Fax ");
1408 if (hint[0] & HINT_LAN) {
1409 IRDA_DEBUG(1, "LAN Access ");
1410 service[i++] = S_LAN;
1411 }
1412 /*
1413 * Test if extension byte exists. This byte will usually be
1414 * there, but this is not really required by the standard.
1415 * (IrLMP p. 29)
1416 */
1417 if (hint[0] & HINT_EXTENSION) {
1418 if (hint[1] & HINT_TELEPHONY) {
1419 IRDA_DEBUG(1, "Telephony ");
1420 service[i++] = S_TELEPHONY;
1421 } if (hint[1] & HINT_FILE_SERVER)
1422 IRDA_DEBUG(1, "File Server ");
1423
1424 if (hint[1] & HINT_COMM) {
1425 IRDA_DEBUG(1, "IrCOMM ");
1426 service[i++] = S_COMM;
1427 }
1428 if (hint[1] & HINT_OBEX) {
1429 IRDA_DEBUG(1, "IrOBEX ");
1430 service[i++] = S_OBEX;
1431 }
1432 }
1433 IRDA_DEBUG(1, "\n");
1434
1435 /* So that client can be notified about any discovery */
1436 service[i++] = S_ANY;
1437
1438 service[i] = S_END;
1439
1440 return service;
1441}
1442#endif
1443
1444static const __u16 service_hint_mapping[S_END][2] = {
1445 { HINT_PNP, 0 }, /* S_PNP */
1446 { HINT_PDA, 0 }, /* S_PDA */
1447 { HINT_COMPUTER, 0 }, /* S_COMPUTER */
1448 { HINT_PRINTER, 0 }, /* S_PRINTER */
1449 { HINT_MODEM, 0 }, /* S_MODEM */
1450 { HINT_FAX, 0 }, /* S_FAX */
1451 { HINT_LAN, 0 }, /* S_LAN */
1452 { HINT_EXTENSION, HINT_TELEPHONY }, /* S_TELEPHONY */
1453 { HINT_EXTENSION, HINT_COMM }, /* S_COMM */
1454 { HINT_EXTENSION, HINT_OBEX }, /* S_OBEX */
1455 { 0xFF, 0xFF }, /* S_ANY */
1456};
1457
1458/*
1459 * Function irlmp_service_to_hint (service)
1460 *
1461 * Converts a service type, to a hint bit
1462 *
1463 * Returns: a 16 bit hint value, with the service bit set
1464 */
1465__u16 irlmp_service_to_hint(int service)
1466{
1467 __u16_host_order hint;
1468
1469 hint.byte[0] = service_hint_mapping[service][0];
1470 hint.byte[1] = service_hint_mapping[service][1];
1471
1472 return hint.word;
1473}
1474EXPORT_SYMBOL(irlmp_service_to_hint);
1475
1476/*
1477 * Function irlmp_register_service (service)
1478 *
1479 * Register local service with IrLMP
1480 *
1481 */
1482void *irlmp_register_service(__u16 hints)
1483{
1484 irlmp_service_t *service;
1485
1486 IRDA_DEBUG(4, "%s(), hints = %04x\n", __FUNCTION__, hints);
1487
1488 /* Make a new registration */
1489 service = kmalloc(sizeof(irlmp_service_t), GFP_ATOMIC);
1490 if (!service) {
1491 IRDA_DEBUG(1, "%s(), Unable to kmalloc!\n", __FUNCTION__);
1492 return NULL;
1493 }
1494 service->hints.word = hints;
1495 hashbin_insert(irlmp->services, (irda_queue_t *) service,
1496 (long) service, NULL);
1497
1498 irlmp->hints.word |= hints;
1499
1500 return (void *)service;
1501}
1502EXPORT_SYMBOL(irlmp_register_service);
1503
1504/*
1505 * Function irlmp_unregister_service (handle)
1506 *
1507 * Unregister service with IrLMP.
1508 *
1509 * Returns: 0 on success, -1 on error
1510 */
1511int irlmp_unregister_service(void *handle)
1512{
1513 irlmp_service_t *service;
1514 unsigned long flags;
1515
1516 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1517
1518 if (!handle)
1519 return -1;
1520
1521 /* Caller may call with invalid handle (it's legal) - Jean II */
1522 service = hashbin_lock_find(irlmp->services, (long) handle, NULL);
1523 if (!service) {
1524 IRDA_DEBUG(1, "%s(), Unknown service!\n", __FUNCTION__);
1525 return -1;
1526 }
1527
1528 hashbin_remove_this(irlmp->services, (irda_queue_t *) service);
1529 kfree(service);
1530
1531 /* Remove old hint bits */
1532 irlmp->hints.word = 0;
1533
1534 /* Refresh current hint bits */
1535 spin_lock_irqsave(&irlmp->services->hb_spinlock, flags);
1536 service = (irlmp_service_t *) hashbin_get_first(irlmp->services);
1537 while (service) {
1538 irlmp->hints.word |= service->hints.word;
1539
1540 service = (irlmp_service_t *)hashbin_get_next(irlmp->services);
1541 }
1542 spin_unlock_irqrestore(&irlmp->services->hb_spinlock, flags);
1543 return 0;
1544}
1545EXPORT_SYMBOL(irlmp_unregister_service);
1546
1547/*
1548 * Function irlmp_register_client (hint_mask, callback1, callback2)
1549 *
1550 * Register a local client with IrLMP
1551 * First callback is selective discovery (based on hints)
1552 * Second callback is for selective discovery expiries
1553 *
1554 * Returns: handle > 0 on success, 0 on error
1555 */
1556void *irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb,
1557 DISCOVERY_CALLBACK2 expir_clb, void *priv)
1558{
1559 irlmp_client_t *client;
1560
1561 IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
1562 IRDA_ASSERT(irlmp != NULL, return NULL;);
1563
1564 /* Make a new registration */
1565 client = kmalloc(sizeof(irlmp_client_t), GFP_ATOMIC);
1566 if (!client) {
1567 IRDA_DEBUG( 1, "%s(), Unable to kmalloc!\n", __FUNCTION__);
1568 return NULL;
1569 }
1570
1571 /* Register the details */
1572 client->hint_mask.word = hint_mask;
1573 client->disco_callback = disco_clb;
1574 client->expir_callback = expir_clb;
1575 client->priv = priv;
1576
1577 hashbin_insert(irlmp->clients, (irda_queue_t *) client,
1578 (long) client, NULL);
1579
1580 return (void *) client;
1581}
1582EXPORT_SYMBOL(irlmp_register_client);
1583
1584/*
1585 * Function irlmp_update_client (handle, hint_mask, callback1, callback2)
1586 *
1587 * Updates specified client (handle) with possibly new hint_mask and
1588 * callback
1589 *
1590 * Returns: 0 on success, -1 on error
1591 */
1592int irlmp_update_client(void *handle, __u16 hint_mask,
1593 DISCOVERY_CALLBACK1 disco_clb,
1594 DISCOVERY_CALLBACK2 expir_clb, void *priv)
1595{
1596 irlmp_client_t *client;
1597
1598 if (!handle)
1599 return -1;
1600
1601 client = hashbin_lock_find(irlmp->clients, (long) handle, NULL);
1602 if (!client) {
1603 IRDA_DEBUG(1, "%s(), Unknown client!\n", __FUNCTION__);
1604 return -1;
1605 }
1606
1607 client->hint_mask.word = hint_mask;
1608 client->disco_callback = disco_clb;
1609 client->expir_callback = expir_clb;
1610 client->priv = priv;
1611
1612 return 0;
1613}
1614EXPORT_SYMBOL(irlmp_update_client);
1615
1616/*
1617 * Function irlmp_unregister_client (handle)
1618 *
1619 * Returns: 0 on success, -1 on error
1620 *
1621 */
1622int irlmp_unregister_client(void *handle)
1623{
1624 struct irlmp_client *client;
1625
1626 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1627
1628 if (!handle)
1629 return -1;
1630
1631 /* Caller may call with invalid handle (it's legal) - Jean II */
1632 client = hashbin_lock_find(irlmp->clients, (long) handle, NULL);
1633 if (!client) {
1634 IRDA_DEBUG(1, "%s(), Unknown client!\n", __FUNCTION__);
1635 return -1;
1636 }
1637
1638 IRDA_DEBUG(4, "%s(), removing client!\n", __FUNCTION__);
1639 hashbin_remove_this(irlmp->clients, (irda_queue_t *) client);
1640 kfree(client);
1641
1642 return 0;
1643}
1644EXPORT_SYMBOL(irlmp_unregister_client);
1645
1646/*
1647 * Function irlmp_slsap_inuse (slsap)
1648 *
1649 * Check if the given source LSAP selector is in use
1650 *
1651 * This function is clearly not very efficient. On the mitigating side, the
1652 * stack make sure that in 99% of the cases, we are called only once
1653 * for each socket allocation. We could probably keep a bitmap
1654 * of the allocated LSAP, but I'm not sure the complexity is worth it.
1655 * Jean II
1656 */
1657static int irlmp_slsap_inuse(__u8 slsap_sel)
1658{
1659 struct lsap_cb *self;
1660 struct lap_cb *lap;
1661 unsigned long flags;
1662
1663 IRDA_ASSERT(irlmp != NULL, return TRUE;);
1664 IRDA_ASSERT(irlmp->magic == LMP_MAGIC, return TRUE;);
1665 IRDA_ASSERT(slsap_sel != LSAP_ANY, return TRUE;);
1666
1667 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1668
1669#ifdef CONFIG_IRDA_ULTRA
1670 /* Accept all bindings to the connectionless LSAP */
1671 if (slsap_sel == LSAP_CONNLESS)
1672 return FALSE;
1673#endif /* CONFIG_IRDA_ULTRA */
1674
1675 /* Valid values are between 0 and 127 (0x0-0x6F) */
1676 if (slsap_sel > LSAP_MAX)
1677 return TRUE;
1678
1679 /*
1680 * Check if slsap is already in use. To do this we have to loop over
1681 * every IrLAP connection and check every LSAP associated with each
1682 * the connection.
1683 */
1684 spin_lock_irqsave(&irlmp->links->hb_spinlock, flags);
1685 lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
1686 while (lap != NULL) {
1687 IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, goto errlap;);
1688
1689 /* Careful for priority inversions here !
1690 * irlmp->links is never taken while another IrDA
1691 * spinlock is held, so we are safe. Jean II */
1692 spin_lock(&lap->lsaps->hb_spinlock);
1693
1694 /* For this IrLAP, check all the LSAPs */
1695 self = (struct lsap_cb *) hashbin_get_first(lap->lsaps);
1696 while (self != NULL) {
1697 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC,
1698 goto errlsap;);
1699
1700 if ((self->slsap_sel == slsap_sel)) {
1701 IRDA_DEBUG(4, "Source LSAP selector=%02x in use\n",
1702 self->slsap_sel);
1703 goto errlsap;
1704 }
1705 self = (struct lsap_cb*) hashbin_get_next(lap->lsaps);
1706 }
1707 spin_unlock(&lap->lsaps->hb_spinlock);
1708
1709 /* Next LAP */
1710 lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
1711 }
1712 spin_unlock_irqrestore(&irlmp->links->hb_spinlock, flags);
1713
1714 /*
1715 * Server sockets are typically waiting for connections and
1716 * therefore reside in the unconnected list. We don't want
1717 * to give out their LSAPs for obvious reasons...
1718 * Jean II
1719 */
1720 spin_lock_irqsave(&irlmp->unconnected_lsaps->hb_spinlock, flags);
1721
1722 self = (struct lsap_cb *) hashbin_get_first(irlmp->unconnected_lsaps);
1723 while (self != NULL) {
1724 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, goto erruncon;);
1725 if ((self->slsap_sel == slsap_sel)) {
1726 IRDA_DEBUG(4, "Source LSAP selector=%02x in use (unconnected)\n",
1727 self->slsap_sel);
1728 goto erruncon;
1729 }
1730 self = (struct lsap_cb*) hashbin_get_next(irlmp->unconnected_lsaps);
1731 }
1732 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, flags);
1733
1734 return FALSE;
1735
1736 /* Error exit from within one of the two nested loops.
1737 * Make sure we release the right spinlock in the righ order.
1738 * Jean II */
1739errlsap:
1740 spin_unlock(&lap->lsaps->hb_spinlock);
1741IRDA_ASSERT_LABEL(errlap:)
1742 spin_unlock_irqrestore(&irlmp->links->hb_spinlock, flags);
1743 return TRUE;
1744
1745 /* Error exit from within the unconnected loop.
1746 * Just one spinlock to release... Jean II */
1747erruncon:
1748 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, flags);
1749 return TRUE;
1750}
1751
1752/*
1753 * Function irlmp_find_free_slsap ()
1754 *
1755 * Find a free source LSAP to use. This function is called if the service
1756 * user has requested a source LSAP equal to LM_ANY
1757 */
1758static __u8 irlmp_find_free_slsap(void)
1759{
1760 __u8 lsap_sel;
1761 int wrapped = 0;
1762
1763 IRDA_ASSERT(irlmp != NULL, return -1;);
1764 IRDA_ASSERT(irlmp->magic == LMP_MAGIC, return -1;);
1765
1766 /* Most users don't really care which LSAPs they are given,
1767 * and therefore we automatically give them a free LSAP.
1768 * This function try to find a suitable LSAP, i.e. which is
1769 * not in use and is within the acceptable range. Jean II */
1770
1771 do {
1772 /* Always increment to LSAP number before using it.
1773 * In theory, we could reuse the last LSAP number, as long
1774 * as it is no longer in use. Some IrDA stack do that.
1775 * However, the previous socket may be half closed, i.e.
1776 * we closed it, we think it's no longer in use, but the
1777 * other side did not receive our close and think it's
1778 * active and still send data on it.
1779 * This is similar to what is done with PIDs and TCP ports.
1780 * Also, this reduce the number of calls to irlmp_slsap_inuse()
1781 * which is an expensive function to call.
1782 * Jean II */
1783 irlmp->last_lsap_sel++;
1784
1785 /* Check if we need to wraparound (0x70-0x7f are reserved) */
1786 if (irlmp->last_lsap_sel > LSAP_MAX) {
1787 /* 0x00-0x10 are also reserved for well know ports */
1788 irlmp->last_lsap_sel = 0x10;
1789
1790 /* Make sure we terminate the loop */
1791 if (wrapped++) {
1792 IRDA_ERROR("%s: no more free LSAPs !\n",
1793 __FUNCTION__);
1794 return 0;
1795 }
1796 }
1797
1798 /* If the LSAP is in use, try the next one.
1799 * Despite the autoincrement, we need to check if the lsap
1800 * is really in use or not, first because LSAP may be
1801 * directly allocated in irlmp_open_lsap(), and also because
1802 * we may wraparound on old sockets. Jean II */
1803 } while (irlmp_slsap_inuse(irlmp->last_lsap_sel));
1804
1805 /* Got it ! */
1806 lsap_sel = irlmp->last_lsap_sel;
1807 IRDA_DEBUG(4, "%s(), found free lsap_sel=%02x\n",
1808 __FUNCTION__, lsap_sel);
1809
1810 return lsap_sel;
1811}
1812
1813/*
1814 * Function irlmp_convert_lap_reason (lap_reason)
1815 *
1816 * Converts IrLAP disconnect reason codes to IrLMP disconnect reason
1817 * codes
1818 *
1819 */
1820LM_REASON irlmp_convert_lap_reason( LAP_REASON lap_reason)
1821{
1822 int reason = LM_LAP_DISCONNECT;
1823
1824 switch (lap_reason) {
1825 case LAP_DISC_INDICATION: /* Received a disconnect request from peer */
1826 IRDA_DEBUG( 1, "%s(), LAP_DISC_INDICATION\n", __FUNCTION__);
1827 reason = LM_USER_REQUEST;
1828 break;
1829 case LAP_NO_RESPONSE: /* To many retransmits without response */
1830 IRDA_DEBUG( 1, "%s(), LAP_NO_RESPONSE\n", __FUNCTION__);
1831 reason = LM_LAP_DISCONNECT;
1832 break;
1833 case LAP_RESET_INDICATION:
1834 IRDA_DEBUG( 1, "%s(), LAP_RESET_INDICATION\n", __FUNCTION__);
1835 reason = LM_LAP_RESET;
1836 break;
1837 case LAP_FOUND_NONE:
1838 case LAP_MEDIA_BUSY:
1839 case LAP_PRIMARY_CONFLICT:
1840 IRDA_DEBUG(1, "%s(), LAP_FOUND_NONE, LAP_MEDIA_BUSY or LAP_PRIMARY_CONFLICT\n", __FUNCTION__);
1841 reason = LM_CONNECT_FAILURE;
1842 break;
1843 default:
1844 IRDA_DEBUG(1, "%s(), Unknow IrLAP disconnect reason %d!\n",
1845 __FUNCTION__, lap_reason);
1846 reason = LM_LAP_DISCONNECT;
1847 break;
1848 }
1849
1850 return reason;
1851}
1852
1853#ifdef CONFIG_PROC_FS
1854
1855struct irlmp_iter_state {
1856 hashbin_t *hashbin;
1857};
1858
1859#define LSAP_START_TOKEN ((void *)1)
1860#define LINK_START_TOKEN ((void *)2)
1861
1862static void *irlmp_seq_hb_idx(struct irlmp_iter_state *iter, loff_t *off)
1863{
1864 void *element;
1865
1866 spin_lock_irq(&iter->hashbin->hb_spinlock);
1867 for (element = hashbin_get_first(iter->hashbin);
1868 element != NULL;
1869 element = hashbin_get_next(iter->hashbin)) {
1870 if (!off || *off-- == 0) {
1871 /* NB: hashbin left locked */
1872 return element;
1873 }
1874 }
1875 spin_unlock_irq(&iter->hashbin->hb_spinlock);
1876 iter->hashbin = NULL;
1877 return NULL;
1878}
1879
1880
1881static void *irlmp_seq_start(struct seq_file *seq, loff_t *pos)
1882{
1883 struct irlmp_iter_state *iter = seq->private;
1884 void *v;
1885 loff_t off = *pos;
1886
1887 iter->hashbin = NULL;
1888 if (off-- == 0)
1889 return LSAP_START_TOKEN;
1890
1891 iter->hashbin = irlmp->unconnected_lsaps;
1892 v = irlmp_seq_hb_idx(iter, &off);
1893 if (v)
1894 return v;
1895
1896 if (off-- == 0)
1897 return LINK_START_TOKEN;
1898
1899 iter->hashbin = irlmp->links;
1900 return irlmp_seq_hb_idx(iter, &off);
1901}
1902
1903static void *irlmp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1904{
1905 struct irlmp_iter_state *iter = seq->private;
1906
1907 ++*pos;
1908
1909 if (v == LSAP_START_TOKEN) { /* start of list of lsaps */
1910 iter->hashbin = irlmp->unconnected_lsaps;
1911 v = irlmp_seq_hb_idx(iter, NULL);
1912 return v ? v : LINK_START_TOKEN;
1913 }
1914
1915 if (v == LINK_START_TOKEN) { /* start of list of links */
1916 iter->hashbin = irlmp->links;
1917 return irlmp_seq_hb_idx(iter, NULL);
1918 }
1919
1920 v = hashbin_get_next(iter->hashbin);
1921
1922 if (v == NULL) { /* no more in this hash bin */
1923 spin_unlock_irq(&iter->hashbin->hb_spinlock);
1924
1925 if (iter->hashbin == irlmp->unconnected_lsaps)
1926 v = LINK_START_TOKEN;
1927
1928 iter->hashbin = NULL;
1929 }
1930 return v;
1931}
1932
1933static void irlmp_seq_stop(struct seq_file *seq, void *v)
1934{
1935 struct irlmp_iter_state *iter = seq->private;
1936
1937 if (iter->hashbin)
1938 spin_unlock_irq(&iter->hashbin->hb_spinlock);
1939}
1940
1941static int irlmp_seq_show(struct seq_file *seq, void *v)
1942{
1943 const struct irlmp_iter_state *iter = seq->private;
1944 struct lsap_cb *self = v;
1945
1946 if (v == LSAP_START_TOKEN)
1947 seq_puts(seq, "Unconnected LSAPs:\n");
1948 else if (v == LINK_START_TOKEN)
1949 seq_puts(seq, "\nRegistered Link Layers:\n");
1950 else if (iter->hashbin == irlmp->unconnected_lsaps) {
1951 self = v;
1952 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -EINVAL; );
1953 seq_printf(seq, "lsap state: %s, ",
1954 irlsap_state[ self->lsap_state]);
1955 seq_printf(seq,
1956 "slsap_sel: %#02x, dlsap_sel: %#02x, ",
1957 self->slsap_sel, self->dlsap_sel);
1958 seq_printf(seq, "(%s)", self->notify.name);
1959 seq_printf(seq, "\n");
1960 } else if (iter->hashbin == irlmp->links) {
1961 struct lap_cb *lap = v;
1962
1963 seq_printf(seq, "lap state: %s, ",
1964 irlmp_state[lap->lap_state]);
1965
1966 seq_printf(seq, "saddr: %#08x, daddr: %#08x, ",
1967 lap->saddr, lap->daddr);
1968 seq_printf(seq, "num lsaps: %d",
1969 HASHBIN_GET_SIZE(lap->lsaps));
1970 seq_printf(seq, "\n");
1971
1972 /* Careful for priority inversions here !
1973 * All other uses of attrib spinlock are independent of
1974 * the object spinlock, so we are safe. Jean II */
1975 spin_lock(&lap->lsaps->hb_spinlock);
1976
1977 seq_printf(seq, "\n Connected LSAPs:\n");
1978 for (self = (struct lsap_cb *) hashbin_get_first(lap->lsaps);
1979 self != NULL;
1980 self = (struct lsap_cb *)hashbin_get_next(lap->lsaps)) {
1981 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC,
1982 goto outloop;);
1983 seq_printf(seq, " lsap state: %s, ",
1984 irlsap_state[ self->lsap_state]);
1985 seq_printf(seq,
1986 "slsap_sel: %#02x, dlsap_sel: %#02x, ",
1987 self->slsap_sel, self->dlsap_sel);
1988 seq_printf(seq, "(%s)", self->notify.name);
1989 seq_putc(seq, '\n');
1990
1991 }
1992 IRDA_ASSERT_LABEL(outloop:)
1993 spin_unlock(&lap->lsaps->hb_spinlock);
1994 seq_putc(seq, '\n');
1995 } else
1996 return -EINVAL;
1997
1998 return 0;
1999}
2000
2001static struct seq_operations irlmp_seq_ops = {
2002 .start = irlmp_seq_start,
2003 .next = irlmp_seq_next,
2004 .stop = irlmp_seq_stop,
2005 .show = irlmp_seq_show,
2006};
2007
2008static int irlmp_seq_open(struct inode *inode, struct file *file)
2009{
2010 struct seq_file *seq;
2011 int rc = -ENOMEM;
2012 struct irlmp_iter_state *s;
2013
2014 IRDA_ASSERT(irlmp != NULL, return -EINVAL;);
2015
2016 s = kmalloc(sizeof(*s), GFP_KERNEL);
2017 if (!s)
2018 goto out;
2019
2020 rc = seq_open(file, &irlmp_seq_ops);
2021 if (rc)
2022 goto out_kfree;
2023
2024 seq = file->private_data;
2025 seq->private = s;
2026out:
2027 return rc;
2028out_kfree:
2029 kfree(s);
2030 goto out;
2031}
2032
2033struct file_operations irlmp_seq_fops = {
2034 .owner = THIS_MODULE,
2035 .open = irlmp_seq_open,
2036 .read = seq_read,
2037 .llseek = seq_lseek,
2038 .release = seq_release_private,
2039};
2040
2041#endif /* PROC_FS */
diff --git a/net/irda/irlmp_event.c b/net/irda/irlmp_event.c
new file mode 100644
index 00000000000..26649f6528e
--- /dev/null
+++ b/net/irda/irlmp_event.c
@@ -0,0 +1,912 @@
1/*********************************************************************
2 *
3 * Filename: irlmp_event.c
4 * Version: 0.8
5 * Description: An IrDA LMP event driver for Linux
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Mon Aug 4 20:40:53 1997
9 * Modified at: Tue Dec 14 23:04:16 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
13 * All Rights Reserved.
14 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
20 *
21 * Neither Dag Brattli nor University of Tromsø admit liability nor
22 * provide warranty for any of this software. This material is
23 * provided "AS-IS" and at no charge.
24 *
25 ********************************************************************/
26
27#include <linux/config.h>
28#include <linux/kernel.h>
29
30#include <net/irda/irda.h>
31#include <net/irda/timer.h>
32#include <net/irda/irlap.h>
33#include <net/irda/irlmp.h>
34#include <net/irda/irlmp_frame.h>
35#include <net/irda/irlmp_event.h>
36
37const char *irlmp_state[] = {
38 "LAP_STANDBY",
39 "LAP_U_CONNECT",
40 "LAP_ACTIVE",
41};
42
43const char *irlsap_state[] = {
44 "LSAP_DISCONNECTED",
45 "LSAP_CONNECT",
46 "LSAP_CONNECT_PEND",
47 "LSAP_DATA_TRANSFER_READY",
48 "LSAP_SETUP",
49 "LSAP_SETUP_PEND",
50};
51
52#ifdef CONFIG_IRDA_DEBUG
53static const char *irlmp_event[] = {
54 "LM_CONNECT_REQUEST",
55 "LM_CONNECT_CONFIRM",
56 "LM_CONNECT_RESPONSE",
57 "LM_CONNECT_INDICATION",
58
59 "LM_DISCONNECT_INDICATION",
60 "LM_DISCONNECT_REQUEST",
61
62 "LM_DATA_REQUEST",
63 "LM_UDATA_REQUEST",
64 "LM_DATA_INDICATION",
65 "LM_UDATA_INDICATION",
66
67 "LM_WATCHDOG_TIMEOUT",
68
69 /* IrLAP events */
70 "LM_LAP_CONNECT_REQUEST",
71 "LM_LAP_CONNECT_INDICATION",
72 "LM_LAP_CONNECT_CONFIRM",
73 "LM_LAP_DISCONNECT_INDICATION",
74 "LM_LAP_DISCONNECT_REQUEST",
75 "LM_LAP_DISCOVERY_REQUEST",
76 "LM_LAP_DISCOVERY_CONFIRM",
77 "LM_LAP_IDLE_TIMEOUT",
78};
79#endif /* CONFIG_IRDA_DEBUG */
80
81/* LAP Connection control proto declarations */
82static void irlmp_state_standby (struct lap_cb *, IRLMP_EVENT,
83 struct sk_buff *);
84static void irlmp_state_u_connect(struct lap_cb *, IRLMP_EVENT,
85 struct sk_buff *);
86static void irlmp_state_active (struct lap_cb *, IRLMP_EVENT,
87 struct sk_buff *);
88
89/* LSAP Connection control proto declarations */
90static int irlmp_state_disconnected(struct lsap_cb *, IRLMP_EVENT,
91 struct sk_buff *);
92static int irlmp_state_connect (struct lsap_cb *, IRLMP_EVENT,
93 struct sk_buff *);
94static int irlmp_state_connect_pend(struct lsap_cb *, IRLMP_EVENT,
95 struct sk_buff *);
96static int irlmp_state_dtr (struct lsap_cb *, IRLMP_EVENT,
97 struct sk_buff *);
98static int irlmp_state_setup (struct lsap_cb *, IRLMP_EVENT,
99 struct sk_buff *);
100static int irlmp_state_setup_pend (struct lsap_cb *, IRLMP_EVENT,
101 struct sk_buff *);
102
103static void (*lap_state[]) (struct lap_cb *, IRLMP_EVENT, struct sk_buff *) =
104{
105 irlmp_state_standby,
106 irlmp_state_u_connect,
107 irlmp_state_active,
108};
109
110static int (*lsap_state[])( struct lsap_cb *, IRLMP_EVENT, struct sk_buff *) =
111{
112 irlmp_state_disconnected,
113 irlmp_state_connect,
114 irlmp_state_connect_pend,
115 irlmp_state_dtr,
116 irlmp_state_setup,
117 irlmp_state_setup_pend
118};
119
120static inline void irlmp_next_lap_state(struct lap_cb *self,
121 IRLMP_STATE state)
122{
123 /*
124 IRDA_DEBUG(4, "%s(), LMP LAP = %s\n", __FUNCTION__, irlmp_state[state]);
125 */
126 self->lap_state = state;
127}
128
129static inline void irlmp_next_lsap_state(struct lsap_cb *self,
130 LSAP_STATE state)
131{
132 /*
133 IRDA_ASSERT(self != NULL, return;);
134 IRDA_DEBUG(4, "%s(), LMP LSAP = %s\n", __FUNCTION__, irlsap_state[state]);
135 */
136 self->lsap_state = state;
137}
138
139/* Do connection control events */
140int irlmp_do_lsap_event(struct lsap_cb *self, IRLMP_EVENT event,
141 struct sk_buff *skb)
142{
143 IRDA_ASSERT(self != NULL, return -1;);
144 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
145
146 IRDA_DEBUG(4, "%s(), EVENT = %s, STATE = %s\n",
147 __FUNCTION__, irlmp_event[event], irlsap_state[ self->lsap_state]);
148
149 return (*lsap_state[self->lsap_state]) (self, event, skb);
150}
151
152/*
153 * Function do_lap_event (event, skb, info)
154 *
155 * Do IrLAP control events
156 *
157 */
158void irlmp_do_lap_event(struct lap_cb *self, IRLMP_EVENT event,
159 struct sk_buff *skb)
160{
161 IRDA_ASSERT(self != NULL, return;);
162 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
163
164 IRDA_DEBUG(4, "%s(), EVENT = %s, STATE = %s\n", __FUNCTION__,
165 irlmp_event[event],
166 irlmp_state[self->lap_state]);
167
168 (*lap_state[self->lap_state]) (self, event, skb);
169}
170
171void irlmp_discovery_timer_expired(void *data)
172{
173 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
174
175 /* We always cleanup the log (active & passive discovery) */
176 irlmp_do_expiry();
177
178 /* Active discovery is conditional */
179 if (sysctl_discovery)
180 irlmp_do_discovery(sysctl_discovery_slots);
181
182 /* Restart timer */
183 irlmp_start_discovery_timer(irlmp, sysctl_discovery_timeout * HZ);
184}
185
186void irlmp_watchdog_timer_expired(void *data)
187{
188 struct lsap_cb *self = (struct lsap_cb *) data;
189
190 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
191
192 IRDA_ASSERT(self != NULL, return;);
193 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
194
195 irlmp_do_lsap_event(self, LM_WATCHDOG_TIMEOUT, NULL);
196}
197
198void irlmp_idle_timer_expired(void *data)
199{
200 struct lap_cb *self = (struct lap_cb *) data;
201
202 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
203
204 IRDA_ASSERT(self != NULL, return;);
205 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
206
207 irlmp_do_lap_event(self, LM_LAP_IDLE_TIMEOUT, NULL);
208}
209
210/*
211 * Send an event on all LSAPs attached to this LAP.
212 */
213static inline void
214irlmp_do_all_lsap_event(hashbin_t * lsap_hashbin,
215 IRLMP_EVENT event)
216{
217 struct lsap_cb *lsap;
218 struct lsap_cb *lsap_next;
219
220 /* Note : this function use the new hashbin_find_next()
221 * function, instead of the old hashbin_get_next().
222 * This make sure that we are always pointing one lsap
223 * ahead, so that if the current lsap is removed as the
224 * result of sending the event, we don't care.
225 * Also, as we store the context ourselves, if an enumeration
226 * of the same lsap hashbin happens as the result of sending the
227 * event, we don't care.
228 * The only problem is if the next lsap is removed. In that case,
229 * hashbin_find_next() will return NULL and we will abort the
230 * enumeration. - Jean II */
231
232 /* Also : we don't accept any skb in input. We can *NOT* pass
233 * the same skb to multiple clients safely, we would need to
234 * skb_clone() it. - Jean II */
235
236 lsap = (struct lsap_cb *) hashbin_get_first(lsap_hashbin);
237
238 while (NULL != hashbin_find_next(lsap_hashbin,
239 (long) lsap,
240 NULL,
241 (void *) &lsap_next) ) {
242 irlmp_do_lsap_event(lsap, event, NULL);
243 lsap = lsap_next;
244 }
245}
246
247/*********************************************************************
248 *
249 * LAP connection control states
250 *
251 ********************************************************************/
252
253/*
254 * Function irlmp_state_standby (event, skb, info)
255 *
256 * STANDBY, The IrLAP connection does not exist.
257 *
258 */
259static void irlmp_state_standby(struct lap_cb *self, IRLMP_EVENT event,
260 struct sk_buff *skb)
261{
262 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
263 IRDA_ASSERT(self->irlap != NULL, return;);
264
265 switch (event) {
266 case LM_LAP_DISCOVERY_REQUEST:
267 /* irlmp_next_station_state( LMP_DISCOVER); */
268
269 irlap_discovery_request(self->irlap, &irlmp->discovery_cmd);
270 break;
271 case LM_LAP_CONNECT_INDICATION:
272 /* It's important to switch state first, to avoid IrLMP to
273 * think that the link is free since IrLMP may then start
274 * discovery before the connection is properly set up. DB.
275 */
276 irlmp_next_lap_state(self, LAP_ACTIVE);
277
278 /* Just accept connection TODO, this should be fixed */
279 irlap_connect_response(self->irlap, skb);
280 break;
281 case LM_LAP_CONNECT_REQUEST:
282 IRDA_DEBUG(4, "%s() LS_CONNECT_REQUEST\n", __FUNCTION__);
283
284 irlmp_next_lap_state(self, LAP_U_CONNECT);
285
286 /* FIXME: need to set users requested QoS */
287 irlap_connect_request(self->irlap, self->daddr, NULL, 0);
288 break;
289 case LM_LAP_DISCONNECT_INDICATION:
290 IRDA_DEBUG(4, "%s(), Error LM_LAP_DISCONNECT_INDICATION\n",
291 __FUNCTION__);
292
293 irlmp_next_lap_state(self, LAP_STANDBY);
294 break;
295 default:
296 IRDA_DEBUG(0, "%s(), Unknown event %s\n",
297 __FUNCTION__, irlmp_event[event]);
298 break;
299 }
300}
301
302/*
303 * Function irlmp_state_u_connect (event, skb, info)
304 *
305 * U_CONNECT, The layer above has tried to open an LSAP connection but
306 * since the IrLAP connection does not exist, we must first start an
307 * IrLAP connection. We are now waiting response from IrLAP.
308 * */
309static void irlmp_state_u_connect(struct lap_cb *self, IRLMP_EVENT event,
310 struct sk_buff *skb)
311{
312 IRDA_DEBUG(2, "%s(), event=%s\n", __FUNCTION__, irlmp_event[event]);
313
314 switch (event) {
315 case LM_LAP_CONNECT_INDICATION:
316 /* It's important to switch state first, to avoid IrLMP to
317 * think that the link is free since IrLMP may then start
318 * discovery before the connection is properly set up. DB.
319 */
320 irlmp_next_lap_state(self, LAP_ACTIVE);
321
322 /* Just accept connection TODO, this should be fixed */
323 irlap_connect_response(self->irlap, skb);
324
325 /* Tell LSAPs that they can start sending data */
326 irlmp_do_all_lsap_event(self->lsaps, LM_LAP_CONNECT_CONFIRM);
327
328 /* Note : by the time we get there (LAP retries and co),
329 * the lsaps may already have gone. This avoid getting stuck
330 * forever in LAP_ACTIVE state - Jean II */
331 if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
332 IRDA_DEBUG(0, "%s() NO LSAPs !\n", __FUNCTION__);
333 irlmp_start_idle_timer(self, LM_IDLE_TIMEOUT);
334 }
335 break;
336 case LM_LAP_CONNECT_REQUEST:
337 /* Already trying to connect */
338 break;
339 case LM_LAP_CONNECT_CONFIRM:
340 /* For all lsap_ce E Associated do LS_Connect_confirm */
341 irlmp_next_lap_state(self, LAP_ACTIVE);
342
343 /* Tell LSAPs that they can start sending data */
344 irlmp_do_all_lsap_event(self->lsaps, LM_LAP_CONNECT_CONFIRM);
345
346 /* Note : by the time we get there (LAP retries and co),
347 * the lsaps may already have gone. This avoid getting stuck
348 * forever in LAP_ACTIVE state - Jean II */
349 if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
350 IRDA_DEBUG(0, "%s() NO LSAPs !\n", __FUNCTION__);
351 irlmp_start_idle_timer(self, LM_IDLE_TIMEOUT);
352 }
353 break;
354 case LM_LAP_DISCONNECT_INDICATION:
355 IRDA_DEBUG(4, "%s(), LM_LAP_DISCONNECT_INDICATION\n", __FUNCTION__);
356 irlmp_next_lap_state(self, LAP_STANDBY);
357
358 /* Send disconnect event to all LSAPs using this link */
359 irlmp_do_all_lsap_event(self->lsaps,
360 LM_LAP_DISCONNECT_INDICATION);
361 break;
362 case LM_LAP_DISCONNECT_REQUEST:
363 IRDA_DEBUG(4, "%s(), LM_LAP_DISCONNECT_REQUEST\n", __FUNCTION__);
364
365 /* One of the LSAP did timeout or was closed, if it was
366 * the last one, try to get out of here - Jean II */
367 if (HASHBIN_GET_SIZE(self->lsaps) <= 1) {
368 irlap_disconnect_request(self->irlap);
369 }
370 break;
371 default:
372 IRDA_DEBUG(0, "%s(), Unknown event %s\n",
373 __FUNCTION__, irlmp_event[event]);
374 break;
375 }
376}
377
378/*
379 * Function irlmp_state_active (event, skb, info)
380 *
381 * ACTIVE, IrLAP connection is active
382 *
383 */
384static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event,
385 struct sk_buff *skb)
386{
387 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
388
389 switch (event) {
390 case LM_LAP_CONNECT_REQUEST:
391 IRDA_DEBUG(4, "%s(), LS_CONNECT_REQUEST\n", __FUNCTION__);
392
393 /*
394 * IrLAP may have a pending disconnect. We tried to close
395 * IrLAP, but it was postponed because the link was
396 * busy or we were still sending packets. As we now
397 * need it, make sure it stays on. Jean II
398 */
399 irlap_clear_disconnect(self->irlap);
400
401 /*
402 * LAP connection already active, just bounce back! Since we
403 * don't know which LSAP that tried to do this, we have to
404 * notify all LSAPs using this LAP, but that should be safe to
405 * do anyway.
406 */
407 irlmp_do_all_lsap_event(self->lsaps, LM_LAP_CONNECT_CONFIRM);
408
409 /* Needed by connect indication */
410 irlmp_do_all_lsap_event(irlmp->unconnected_lsaps,
411 LM_LAP_CONNECT_CONFIRM);
412 /* Keep state */
413 break;
414 case LM_LAP_DISCONNECT_REQUEST:
415 /*
416 * Need to find out if we should close IrLAP or not. If there
417 * is only one LSAP connection left on this link, that LSAP
418 * must be the one that tries to close IrLAP. It will be
419 * removed later and moved to the list of unconnected LSAPs
420 */
421 if (HASHBIN_GET_SIZE(self->lsaps) > 0) {
422 /* Timer value is checked in irsysctl - Jean II */
423 irlmp_start_idle_timer(self, sysctl_lap_keepalive_time * HZ / 1000);
424 } else {
425 /* No more connections, so close IrLAP */
426
427 /* We don't want to change state just yet, because
428 * we want to reflect accurately the real state of
429 * the LAP, not the state we wish it was in,
430 * so that we don't lose LM_LAP_CONNECT_REQUEST.
431 * In some cases, IrLAP won't close the LAP
432 * immediately. For example, it might still be
433 * retrying packets or waiting for the pf bit.
434 * As the LAP always send a DISCONNECT_INDICATION
435 * in PCLOSE or SCLOSE, just change state on that.
436 * Jean II */
437 irlap_disconnect_request(self->irlap);
438 }
439 break;
440 case LM_LAP_IDLE_TIMEOUT:
441 if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
442 /* Same reasoning as above - keep state */
443 irlap_disconnect_request(self->irlap);
444 }
445 break;
446 case LM_LAP_DISCONNECT_INDICATION:
447 irlmp_next_lap_state(self, LAP_STANDBY);
448
449 /* In some case, at this point our side has already closed
450 * all lsaps, and we are waiting for the idle_timer to
451 * expire. If another device reconnect immediately, the
452 * idle timer will expire in the midle of the connection
453 * initialisation, screwing up things a lot...
454 * Therefore, we must stop the timer... */
455 irlmp_stop_idle_timer(self);
456
457 /*
458 * Inform all connected LSAP's using this link
459 */
460 irlmp_do_all_lsap_event(self->lsaps,
461 LM_LAP_DISCONNECT_INDICATION);
462
463 /* Force an expiry of the discovery log.
464 * Now that the LAP is free, the system may attempt to
465 * connect to another device. Unfortunately, our entries
466 * are stale. There is a small window (<3s) before the
467 * normal discovery will run and where irlmp_connect_request()
468 * can get the wrong info, so make sure things get
469 * cleaned *NOW* ;-) - Jean II */
470 irlmp_do_expiry();
471 break;
472 default:
473 IRDA_DEBUG(0, "%s(), Unknown event %s\n",
474 __FUNCTION__, irlmp_event[event]);
475 break;
476 }
477}
478
479/*********************************************************************
480 *
481 * LSAP connection control states
482 *
483 ********************************************************************/
484
485/*
486 * Function irlmp_state_disconnected (event, skb, info)
487 *
488 * DISCONNECTED
489 *
490 */
491static int irlmp_state_disconnected(struct lsap_cb *self, IRLMP_EVENT event,
492 struct sk_buff *skb)
493{
494 int ret = 0;
495
496 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
497
498 IRDA_ASSERT(self != NULL, return -1;);
499 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
500
501 switch (event) {
502#ifdef CONFIG_IRDA_ULTRA
503 case LM_UDATA_INDICATION:
504 /* This is most bizzare. Those packets are aka unreliable
505 * connected, aka IrLPT or SOCK_DGRAM/IRDAPROTO_UNITDATA.
506 * Why do we pass them as Ultra ??? Jean II */
507 irlmp_connless_data_indication(self, skb);
508 break;
509#endif /* CONFIG_IRDA_ULTRA */
510 case LM_CONNECT_REQUEST:
511 IRDA_DEBUG(4, "%s(), LM_CONNECT_REQUEST\n", __FUNCTION__);
512
513 if (self->conn_skb) {
514 IRDA_WARNING("%s: busy with another request!\n",
515 __FUNCTION__);
516 return -EBUSY;
517 }
518 /* Don't forget to refcount it (see irlmp_connect_request()) */
519 skb_get(skb);
520 self->conn_skb = skb;
521
522 irlmp_next_lsap_state(self, LSAP_SETUP_PEND);
523
524 /* Start watchdog timer (5 secs for now) */
525 irlmp_start_watchdog_timer(self, 5*HZ);
526
527 irlmp_do_lap_event(self->lap, LM_LAP_CONNECT_REQUEST, NULL);
528 break;
529 case LM_CONNECT_INDICATION:
530 if (self->conn_skb) {
531 IRDA_WARNING("%s: busy with another request!\n",
532 __FUNCTION__);
533 return -EBUSY;
534 }
535 /* Don't forget to refcount it (see irlap_driver_rcv()) */
536 skb_get(skb);
537 self->conn_skb = skb;
538
539 irlmp_next_lsap_state(self, LSAP_CONNECT_PEND);
540
541 /* Start watchdog timer
542 * This is not mentionned in the spec, but there is a rare
543 * race condition that can get the socket stuck.
544 * If we receive this event while our LAP is closing down,
545 * the LM_LAP_CONNECT_REQUEST get lost and we get stuck in
546 * CONNECT_PEND state forever.
547 * The other cause of getting stuck down there is if the
548 * higher layer never reply to the CONNECT_INDICATION.
549 * Anyway, it make sense to make sure that we always have
550 * a backup plan. 1 second is plenty (should be immediate).
551 * Jean II */
552 irlmp_start_watchdog_timer(self, 1*HZ);
553
554 irlmp_do_lap_event(self->lap, LM_LAP_CONNECT_REQUEST, NULL);
555 break;
556 default:
557 IRDA_DEBUG(1, "%s(), Unknown event %s on LSAP %#02x\n",
558 __FUNCTION__, irlmp_event[event], self->slsap_sel);
559 break;
560 }
561 return ret;
562}
563
564/*
565 * Function irlmp_state_connect (self, event, skb)
566 *
567 * CONNECT
568 *
569 */
570static int irlmp_state_connect(struct lsap_cb *self, IRLMP_EVENT event,
571 struct sk_buff *skb)
572{
573 struct lsap_cb *lsap;
574 int ret = 0;
575
576 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
577
578 IRDA_ASSERT(self != NULL, return -1;);
579 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
580
581 switch (event) {
582 case LM_CONNECT_RESPONSE:
583 /*
584 * Bind this LSAP to the IrLAP link where the connect was
585 * received
586 */
587 lsap = hashbin_remove(irlmp->unconnected_lsaps, (long) self,
588 NULL);
589
590 IRDA_ASSERT(lsap == self, return -1;);
591 IRDA_ASSERT(self->lap != NULL, return -1;);
592 IRDA_ASSERT(self->lap->lsaps != NULL, return -1;);
593
594 hashbin_insert(self->lap->lsaps, (irda_queue_t *) self,
595 (long) self, NULL);
596
597 set_bit(0, &self->connected); /* TRUE */
598
599 irlmp_send_lcf_pdu(self->lap, self->dlsap_sel,
600 self->slsap_sel, CONNECT_CNF, skb);
601
602 del_timer(&self->watchdog_timer);
603
604 irlmp_next_lsap_state(self, LSAP_DATA_TRANSFER_READY);
605 break;
606 case LM_WATCHDOG_TIMEOUT:
607 /* May happen, who knows...
608 * Jean II */
609 IRDA_DEBUG(0, "%s() WATCHDOG_TIMEOUT!\n", __FUNCTION__);
610
611 /* Disconnect, get out... - Jean II */
612 self->lap = NULL;
613 self->dlsap_sel = LSAP_ANY;
614 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
615 break;
616 default:
617 /* LM_LAP_DISCONNECT_INDICATION : Should never happen, we
618 * are *not* yet bound to the IrLAP link. Jean II */
619 IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",
620 __FUNCTION__, irlmp_event[event], self->slsap_sel);
621 break;
622 }
623 return ret;
624}
625
626/*
627 * Function irlmp_state_connect_pend (event, skb, info)
628 *
629 * CONNECT_PEND
630 *
631 */
632static int irlmp_state_connect_pend(struct lsap_cb *self, IRLMP_EVENT event,
633 struct sk_buff *skb)
634{
635 struct sk_buff *tx_skb;
636 int ret = 0;
637
638 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
639
640 IRDA_ASSERT(self != NULL, return -1;);
641 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
642
643 switch (event) {
644 case LM_CONNECT_REQUEST:
645 /* Keep state */
646 break;
647 case LM_CONNECT_RESPONSE:
648 IRDA_DEBUG(0, "%s(), LM_CONNECT_RESPONSE, "
649 "no indication issued yet\n", __FUNCTION__);
650 /* Keep state */
651 break;
652 case LM_DISCONNECT_REQUEST:
653 IRDA_DEBUG(0, "%s(), LM_DISCONNECT_REQUEST, "
654 "not yet bound to IrLAP connection\n", __FUNCTION__);
655 /* Keep state */
656 break;
657 case LM_LAP_CONNECT_CONFIRM:
658 IRDA_DEBUG(4, "%s(), LS_CONNECT_CONFIRM\n", __FUNCTION__);
659 irlmp_next_lsap_state(self, LSAP_CONNECT);
660
661 tx_skb = self->conn_skb;
662 self->conn_skb = NULL;
663
664 irlmp_connect_indication(self, tx_skb);
665 /* Drop reference count - see irlmp_connect_indication(). */
666 dev_kfree_skb(tx_skb);
667 break;
668 case LM_WATCHDOG_TIMEOUT:
669 /* Will happen in some rare cases because of a race condition.
670 * Just make sure we don't stay there forever...
671 * Jean II */
672 IRDA_DEBUG(0, "%s() WATCHDOG_TIMEOUT!\n", __FUNCTION__);
673
674 /* Go back to disconnected mode, keep the socket waiting */
675 self->lap = NULL;
676 self->dlsap_sel = LSAP_ANY;
677 if(self->conn_skb)
678 dev_kfree_skb(self->conn_skb);
679 self->conn_skb = NULL;
680 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
681 break;
682 default:
683 /* LM_LAP_DISCONNECT_INDICATION : Should never happen, we
684 * are *not* yet bound to the IrLAP link. Jean II */
685 IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",
686 __FUNCTION__, irlmp_event[event], self->slsap_sel);
687 break;
688 }
689 return ret;
690}
691
692/*
693 * Function irlmp_state_dtr (self, event, skb)
694 *
695 * DATA_TRANSFER_READY
696 *
697 */
698static int irlmp_state_dtr(struct lsap_cb *self, IRLMP_EVENT event,
699 struct sk_buff *skb)
700{
701 LM_REASON reason;
702 int ret = 0;
703
704 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
705
706 IRDA_ASSERT(self != NULL, return -1;);
707 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
708 IRDA_ASSERT(self->lap != NULL, return -1;);
709
710 switch (event) {
711 case LM_DATA_REQUEST: /* Optimize for the common case */
712 irlmp_send_data_pdu(self->lap, self->dlsap_sel,
713 self->slsap_sel, FALSE, skb);
714 break;
715 case LM_DATA_INDICATION: /* Optimize for the common case */
716 irlmp_data_indication(self, skb);
717 break;
718 case LM_UDATA_REQUEST:
719 IRDA_ASSERT(skb != NULL, return -1;);
720 irlmp_send_data_pdu(self->lap, self->dlsap_sel,
721 self->slsap_sel, TRUE, skb);
722 break;
723 case LM_UDATA_INDICATION:
724 irlmp_udata_indication(self, skb);
725 break;
726 case LM_CONNECT_REQUEST:
727 IRDA_DEBUG(0, "%s(), LM_CONNECT_REQUEST, "
728 "error, LSAP already connected\n", __FUNCTION__);
729 /* Keep state */
730 break;
731 case LM_CONNECT_RESPONSE:
732 IRDA_DEBUG(0, "%s(), LM_CONNECT_RESPONSE, "
733 "error, LSAP already connected\n", __FUNCTION__);
734 /* Keep state */
735 break;
736 case LM_DISCONNECT_REQUEST:
737 irlmp_send_lcf_pdu(self->lap, self->dlsap_sel, self->slsap_sel,
738 DISCONNECT, skb);
739 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
740 /* Called only from irlmp_disconnect_request(), will
741 * unbind from LAP over there. Jean II */
742
743 /* Try to close the LAP connection if its still there */
744 if (self->lap) {
745 IRDA_DEBUG(4, "%s(), trying to close IrLAP\n",
746 __FUNCTION__);
747 irlmp_do_lap_event(self->lap,
748 LM_LAP_DISCONNECT_REQUEST,
749 NULL);
750 }
751 break;
752 case LM_LAP_DISCONNECT_INDICATION:
753 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
754
755 reason = irlmp_convert_lap_reason(self->lap->reason);
756
757 irlmp_disconnect_indication(self, reason, NULL);
758 break;
759 case LM_DISCONNECT_INDICATION:
760 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
761
762 IRDA_ASSERT(self->lap != NULL, return -1;);
763 IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
764
765 IRDA_ASSERT(skb != NULL, return -1;);
766 IRDA_ASSERT(skb->len > 3, return -1;);
767 reason = skb->data[3];
768
769 /* Try to close the LAP connection */
770 IRDA_DEBUG(4, "%s(), trying to close IrLAP\n", __FUNCTION__);
771 irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
772
773 irlmp_disconnect_indication(self, reason, skb);
774 break;
775 default:
776 IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",
777 __FUNCTION__, irlmp_event[event], self->slsap_sel);
778 break;
779 }
780 return ret;
781}
782
783/*
784 * Function irlmp_state_setup (event, skb, info)
785 *
786 * SETUP, Station Control has set up the underlying IrLAP connection.
787 * An LSAP connection request has been transmitted to the peer
788 * LSAP-Connection Control FSM and we are awaiting reply.
789 */
790static int irlmp_state_setup(struct lsap_cb *self, IRLMP_EVENT event,
791 struct sk_buff *skb)
792{
793 LM_REASON reason;
794 int ret = 0;
795
796 IRDA_ASSERT(self != NULL, return -1;);
797 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
798
799 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
800
801 switch (event) {
802 case LM_CONNECT_CONFIRM:
803 irlmp_next_lsap_state(self, LSAP_DATA_TRANSFER_READY);
804
805 del_timer(&self->watchdog_timer);
806
807 irlmp_connect_confirm(self, skb);
808 break;
809 case LM_DISCONNECT_INDICATION:
810 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
811
812 IRDA_ASSERT(self->lap != NULL, return -1;);
813 IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
814
815 IRDA_ASSERT(skb != NULL, return -1;);
816 IRDA_ASSERT(skb->len > 3, return -1;);
817 reason = skb->data[3];
818
819 /* Try to close the LAP connection */
820 IRDA_DEBUG(4, "%s(), trying to close IrLAP\n", __FUNCTION__);
821 irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
822
823 irlmp_disconnect_indication(self, reason, skb);
824 break;
825 case LM_LAP_DISCONNECT_INDICATION:
826 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
827
828 del_timer(&self->watchdog_timer);
829
830 IRDA_ASSERT(self->lap != NULL, return -1;);
831 IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
832
833 reason = irlmp_convert_lap_reason(self->lap->reason);
834
835 irlmp_disconnect_indication(self, reason, skb);
836 break;
837 case LM_WATCHDOG_TIMEOUT:
838 IRDA_DEBUG(0, "%s() WATCHDOG_TIMEOUT!\n", __FUNCTION__);
839
840 IRDA_ASSERT(self->lap != NULL, return -1;);
841 irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
842 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
843
844 irlmp_disconnect_indication(self, LM_CONNECT_FAILURE, NULL);
845 break;
846 default:
847 IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",
848 __FUNCTION__, irlmp_event[event], self->slsap_sel);
849 break;
850 }
851 return ret;
852}
853
854/*
855 * Function irlmp_state_setup_pend (event, skb, info)
856 *
857 * SETUP_PEND, An LM_CONNECT_REQUEST has been received from the service
858 * user to set up an LSAP connection. A request has been sent to the
859 * LAP FSM to set up the underlying IrLAP connection, and we
860 * are awaiting confirm.
861 */
862static int irlmp_state_setup_pend(struct lsap_cb *self, IRLMP_EVENT event,
863 struct sk_buff *skb)
864{
865 struct sk_buff *tx_skb;
866 LM_REASON reason;
867 int ret = 0;
868
869 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
870
871 IRDA_ASSERT(self != NULL, return -1;);
872 IRDA_ASSERT(irlmp != NULL, return -1;);
873
874 switch (event) {
875 case LM_LAP_CONNECT_CONFIRM:
876 IRDA_ASSERT(self->conn_skb != NULL, return -1;);
877
878 tx_skb = self->conn_skb;
879 self->conn_skb = NULL;
880
881 irlmp_send_lcf_pdu(self->lap, self->dlsap_sel,
882 self->slsap_sel, CONNECT_CMD, tx_skb);
883 /* Drop reference count - see irlap_data_request(). */
884 dev_kfree_skb(tx_skb);
885
886 irlmp_next_lsap_state(self, LSAP_SETUP);
887 break;
888 case LM_WATCHDOG_TIMEOUT:
889 IRDA_DEBUG(0, "%s() : WATCHDOG_TIMEOUT !\n", __FUNCTION__);
890
891 IRDA_ASSERT(self->lap != NULL, return -1;);
892 irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
893 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
894
895 irlmp_disconnect_indication(self, LM_CONNECT_FAILURE, NULL);
896 break;
897 case LM_LAP_DISCONNECT_INDICATION: /* LS_Disconnect.indication */
898 del_timer( &self->watchdog_timer);
899
900 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
901
902 reason = irlmp_convert_lap_reason(self->lap->reason);
903
904 irlmp_disconnect_indication(self, reason, NULL);
905 break;
906 default:
907 IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",
908 __FUNCTION__, irlmp_event[event], self->slsap_sel);
909 break;
910 }
911 return ret;
912}
diff --git a/net/irda/irlmp_frame.c b/net/irda/irlmp_frame.c
new file mode 100644
index 00000000000..91cd268172f
--- /dev/null
+++ b/net/irda/irlmp_frame.c
@@ -0,0 +1,491 @@
1/*********************************************************************
2 *
3 * Filename: irlmp_frame.c
4 * Version: 0.9
5 * Description: IrLMP frame implementation
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Tue Aug 19 02:09:59 1997
9 * Modified at: Mon Dec 13 13:41:12 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>
13 * All Rights Reserved.
14 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
20 *
21 * Neither Dag Brattli nor University of Tromsø admit liability nor
22 * provide warranty for any of this software. This material is
23 * provided "AS-IS" and at no charge.
24 *
25 ********************************************************************/
26
27#include <linux/config.h>
28#include <linux/skbuff.h>
29#include <linux/kernel.h>
30
31#include <net/irda/irda.h>
32#include <net/irda/irlap.h>
33#include <net/irda/timer.h>
34#include <net/irda/irlmp.h>
35#include <net/irda/irlmp_frame.h>
36#include <net/irda/discovery.h>
37
38static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap,
39 __u8 slsap, int status, hashbin_t *);
40
41inline void irlmp_send_data_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap,
42 int expedited, struct sk_buff *skb)
43{
44 skb->data[0] = dlsap;
45 skb->data[1] = slsap;
46
47 if (expedited) {
48 IRDA_DEBUG(4, "%s(), sending expedited data\n", __FUNCTION__);
49 irlap_data_request(self->irlap, skb, TRUE);
50 } else
51 irlap_data_request(self->irlap, skb, FALSE);
52}
53
54/*
55 * Function irlmp_send_lcf_pdu (dlsap, slsap, opcode,skb)
56 *
57 * Send Link Control Frame to IrLAP
58 */
59void irlmp_send_lcf_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap,
60 __u8 opcode, struct sk_buff *skb)
61{
62 __u8 *frame;
63
64 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
65
66 IRDA_ASSERT(self != NULL, return;);
67 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
68 IRDA_ASSERT(skb != NULL, return;);
69
70 frame = skb->data;
71
72 frame[0] = dlsap | CONTROL_BIT;
73 frame[1] = slsap;
74
75 frame[2] = opcode;
76
77 if (opcode == DISCONNECT)
78 frame[3] = 0x01; /* Service user request */
79 else
80 frame[3] = 0x00; /* rsvd */
81
82 irlap_data_request(self->irlap, skb, FALSE);
83}
84
85/*
86 * Function irlmp_input (skb)
87 *
88 * Used by IrLAP to pass received data frames to IrLMP layer
89 *
90 */
91void irlmp_link_data_indication(struct lap_cb *self, struct sk_buff *skb,
92 int unreliable)
93{
94 struct lsap_cb *lsap;
95 __u8 slsap_sel; /* Source (this) LSAP address */
96 __u8 dlsap_sel; /* Destination LSAP address */
97 __u8 *fp;
98
99 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
100
101 IRDA_ASSERT(self != NULL, return;);
102 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
103 IRDA_ASSERT(skb->len > 2, return;);
104
105 fp = skb->data;
106
107 /*
108 * The next statements may be confusing, but we do this so that
109 * destination LSAP of received frame is source LSAP in our view
110 */
111 slsap_sel = fp[0] & LSAP_MASK;
112 dlsap_sel = fp[1];
113
114 /*
115 * Check if this is an incoming connection, since we must deal with
116 * it in a different way than other established connections.
117 */
118 if ((fp[0] & CONTROL_BIT) && (fp[2] == CONNECT_CMD)) {
119 IRDA_DEBUG(3, "%s(), incoming connection, "
120 "source LSAP=%d, dest LSAP=%d\n",
121 __FUNCTION__, slsap_sel, dlsap_sel);
122
123 /* Try to find LSAP among the unconnected LSAPs */
124 lsap = irlmp_find_lsap(self, dlsap_sel, slsap_sel, CONNECT_CMD,
125 irlmp->unconnected_lsaps);
126
127 /* Maybe LSAP was already connected, so try one more time */
128 if (!lsap) {
129 IRDA_DEBUG(1, "%s(), incoming connection for LSAP already connected\n", __FUNCTION__);
130 lsap = irlmp_find_lsap(self, dlsap_sel, slsap_sel, 0,
131 self->lsaps);
132 }
133 } else
134 lsap = irlmp_find_lsap(self, dlsap_sel, slsap_sel, 0,
135 self->lsaps);
136
137 if (lsap == NULL) {
138 IRDA_DEBUG(2, "IrLMP, Sorry, no LSAP for received frame!\n");
139 IRDA_DEBUG(2, "%s(), slsap_sel = %02x, dlsap_sel = %02x\n",
140 __FUNCTION__, slsap_sel, dlsap_sel);
141 if (fp[0] & CONTROL_BIT) {
142 IRDA_DEBUG(2, "%s(), received control frame %02x\n",
143 __FUNCTION__, fp[2]);
144 } else {
145 IRDA_DEBUG(2, "%s(), received data frame\n", __FUNCTION__);
146 }
147 return;
148 }
149
150 /*
151 * Check if we received a control frame?
152 */
153 if (fp[0] & CONTROL_BIT) {
154 switch (fp[2]) {
155 case CONNECT_CMD:
156 lsap->lap = self;
157 irlmp_do_lsap_event(lsap, LM_CONNECT_INDICATION, skb);
158 break;
159 case CONNECT_CNF:
160 irlmp_do_lsap_event(lsap, LM_CONNECT_CONFIRM, skb);
161 break;
162 case DISCONNECT:
163 IRDA_DEBUG(4, "%s(), Disconnect indication!\n",
164 __FUNCTION__);
165 irlmp_do_lsap_event(lsap, LM_DISCONNECT_INDICATION,
166 skb);
167 break;
168 case ACCESSMODE_CMD:
169 IRDA_DEBUG(0, "Access mode cmd not implemented!\n");
170 break;
171 case ACCESSMODE_CNF:
172 IRDA_DEBUG(0, "Access mode cnf not implemented!\n");
173 break;
174 default:
175 IRDA_DEBUG(0, "%s(), Unknown control frame %02x\n",
176 __FUNCTION__, fp[2]);
177 break;
178 }
179 } else if (unreliable) {
180 /* Optimize and bypass the state machine if possible */
181 if (lsap->lsap_state == LSAP_DATA_TRANSFER_READY)
182 irlmp_udata_indication(lsap, skb);
183 else
184 irlmp_do_lsap_event(lsap, LM_UDATA_INDICATION, skb);
185 } else {
186 /* Optimize and bypass the state machine if possible */
187 if (lsap->lsap_state == LSAP_DATA_TRANSFER_READY)
188 irlmp_data_indication(lsap, skb);
189 else
190 irlmp_do_lsap_event(lsap, LM_DATA_INDICATION, skb);
191 }
192}
193
194/*
195 * Function irlmp_link_unitdata_indication (self, skb)
196 *
197 *
198 *
199 */
200#ifdef CONFIG_IRDA_ULTRA
201void irlmp_link_unitdata_indication(struct lap_cb *self, struct sk_buff *skb)
202{
203 struct lsap_cb *lsap;
204 __u8 slsap_sel; /* Source (this) LSAP address */
205 __u8 dlsap_sel; /* Destination LSAP address */
206 __u8 pid; /* Protocol identifier */
207 __u8 *fp;
208 unsigned long flags;
209
210 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
211
212 IRDA_ASSERT(self != NULL, return;);
213 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
214 IRDA_ASSERT(skb->len > 2, return;);
215
216 fp = skb->data;
217
218 /*
219 * The next statements may be confusing, but we do this so that
220 * destination LSAP of received frame is source LSAP in our view
221 */
222 slsap_sel = fp[0] & LSAP_MASK;
223 dlsap_sel = fp[1];
224 pid = fp[2];
225
226 if (pid & 0x80) {
227 IRDA_DEBUG(0, "%s(), extension in PID not supp!\n",
228 __FUNCTION__);
229 return;
230 }
231
232 /* Check if frame is addressed to the connectionless LSAP */
233 if ((slsap_sel != LSAP_CONNLESS) || (dlsap_sel != LSAP_CONNLESS)) {
234 IRDA_DEBUG(0, "%s(), dropping frame!\n", __FUNCTION__);
235 return;
236 }
237
238 /* Search the connectionless LSAP */
239 spin_lock_irqsave(&irlmp->unconnected_lsaps->hb_spinlock, flags);
240 lsap = (struct lsap_cb *) hashbin_get_first(irlmp->unconnected_lsaps);
241 while (lsap != NULL) {
242 /*
243 * Check if source LSAP and dest LSAP selectors and PID match.
244 */
245 if ((lsap->slsap_sel == slsap_sel) &&
246 (lsap->dlsap_sel == dlsap_sel) &&
247 (lsap->pid == pid))
248 {
249 break;
250 }
251 lsap = (struct lsap_cb *) hashbin_get_next(irlmp->unconnected_lsaps);
252 }
253 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, flags);
254
255 if (lsap)
256 irlmp_connless_data_indication(lsap, skb);
257 else {
258 IRDA_DEBUG(0, "%s(), found no matching LSAP!\n", __FUNCTION__);
259 }
260}
261#endif /* CONFIG_IRDA_ULTRA */
262
263/*
264 * Function irlmp_link_disconnect_indication (reason, userdata)
265 *
266 * IrLAP has disconnected
267 *
268 */
269void irlmp_link_disconnect_indication(struct lap_cb *lap,
270 struct irlap_cb *irlap,
271 LAP_REASON reason,
272 struct sk_buff *skb)
273{
274 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
275
276 IRDA_ASSERT(lap != NULL, return;);
277 IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, return;);
278
279 lap->reason = reason;
280 lap->daddr = DEV_ADDR_ANY;
281
282 /* FIXME: must do something with the skb if any */
283
284 /*
285 * Inform station state machine
286 */
287 irlmp_do_lap_event(lap, LM_LAP_DISCONNECT_INDICATION, NULL);
288}
289
290/*
291 * Function irlmp_link_connect_indication (qos)
292 *
293 * Incoming LAP connection!
294 *
295 */
296void irlmp_link_connect_indication(struct lap_cb *self, __u32 saddr,
297 __u32 daddr, struct qos_info *qos,
298 struct sk_buff *skb)
299{
300 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
301
302 /* Copy QoS settings for this session */
303 self->qos = qos;
304
305 /* Update destination device address */
306 self->daddr = daddr;
307 IRDA_ASSERT(self->saddr == saddr, return;);
308
309 irlmp_do_lap_event(self, LM_LAP_CONNECT_INDICATION, skb);
310}
311
312/*
313 * Function irlmp_link_connect_confirm (qos)
314 *
315 * LAP connection confirmed!
316 *
317 */
318void irlmp_link_connect_confirm(struct lap_cb *self, struct qos_info *qos,
319 struct sk_buff *skb)
320{
321 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
322
323 IRDA_ASSERT(self != NULL, return;);
324 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
325 IRDA_ASSERT(qos != NULL, return;);
326
327 /* Don't need use the skb for now */
328
329 /* Copy QoS settings for this session */
330 self->qos = qos;
331
332 irlmp_do_lap_event(self, LM_LAP_CONNECT_CONFIRM, NULL);
333}
334
335/*
336 * Function irlmp_link_discovery_indication (self, log)
337 *
338 * Device is discovering us
339 *
340 * It's not an answer to our own discoveries, just another device trying
341 * to perform discovery, but we don't want to miss the opportunity
342 * to exploit this information, because :
343 * o We may not actively perform discovery (just passive discovery)
344 * o This type of discovery is much more reliable. In some cases, it
345 * seem that less than 50% of our discoveries get an answer, while
346 * we always get ~100% of these.
347 * o Make faster discovery, statistically divide time of discovery
348 * events by 2 (important for the latency aspect and user feel)
349 * o Even is we do active discovery, the other node might not
350 * answer our discoveries (ex: Palm). The Palm will just perform
351 * one active discovery and connect directly to us.
352 *
353 * However, when both devices discover each other, they might attempt to
354 * connect to each other following the discovery event, and it would create
355 * collisions on the medium (SNRM battle).
356 * The "fix" for that is to disable all connection requests in IrLAP
357 * for 100ms after a discovery indication by setting the media_busy flag.
358 * Previously, we used to postpone the event which was quite ugly. Now
359 * that IrLAP takes care of this problem, just pass the event up...
360 *
361 * Jean II
362 */
363void irlmp_link_discovery_indication(struct lap_cb *self,
364 discovery_t *discovery)
365{
366 IRDA_ASSERT(self != NULL, return;);
367 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
368
369 /* Add to main log, cleanup */
370 irlmp_add_discovery(irlmp->cachelog, discovery);
371
372 /* Just handle it the same way as a discovery confirm,
373 * bypass the LM_LAP state machine (see below) */
374 irlmp_discovery_confirm(irlmp->cachelog, DISCOVERY_PASSIVE);
375}
376
377/*
378 * Function irlmp_link_discovery_confirm (self, log)
379 *
380 * Called by IrLAP with a list of discoveries after the discovery
381 * request has been carried out. A NULL log is received if IrLAP
382 * was unable to carry out the discovery request
383 *
384 */
385void irlmp_link_discovery_confirm(struct lap_cb *self, hashbin_t *log)
386{
387 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
388
389 IRDA_ASSERT(self != NULL, return;);
390 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
391
392 /* Add to main log, cleanup */
393 irlmp_add_discovery_log(irlmp->cachelog, log);
394
395 /* Propagate event to various LSAPs registered for it.
396 * We bypass the LM_LAP state machine because
397 * 1) We do it regardless of the LM_LAP state
398 * 2) It doesn't affect the LM_LAP state
399 * 3) Faster, slimer, simpler, ...
400 * Jean II */
401 irlmp_discovery_confirm(irlmp->cachelog, DISCOVERY_ACTIVE);
402}
403
404#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
405static inline void irlmp_update_cache(struct lap_cb *lap,
406 struct lsap_cb *lsap)
407{
408 /* Prevent concurrent read to get garbage */
409 lap->cache.valid = FALSE;
410 /* Update cache entry */
411 lap->cache.dlsap_sel = lsap->dlsap_sel;
412 lap->cache.slsap_sel = lsap->slsap_sel;
413 lap->cache.lsap = lsap;
414 lap->cache.valid = TRUE;
415}
416#endif
417
418/*
419 * Function irlmp_find_handle (self, dlsap_sel, slsap_sel, status, queue)
420 *
421 * Find handle associated with destination and source LSAP
422 *
423 * Any IrDA connection (LSAP/TSAP) is uniquely identified by
424 * 3 parameters, the local lsap, the remote lsap and the remote address.
425 * We may initiate multiple connections to the same remote service
426 * (they will have different local lsap), a remote device may initiate
427 * multiple connections to the same local service (they will have
428 * different remote lsap), or multiple devices may connect to the same
429 * service and may use the same remote lsap (and they will have
430 * different remote address).
431 * So, where is the remote address ? Each LAP connection is made with
432 * a single remote device, so imply a specific remote address.
433 * Jean II
434 */
435static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel,
436 __u8 slsap_sel, int status,
437 hashbin_t *queue)
438{
439 struct lsap_cb *lsap;
440 unsigned long flags;
441
442 /*
443 * Optimize for the common case. We assume that the last frame
444 * received is in the same connection as the last one, so check in
445 * cache first to avoid the linear search
446 */
447#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
448 if ((self->cache.valid) &&
449 (self->cache.slsap_sel == slsap_sel) &&
450 (self->cache.dlsap_sel == dlsap_sel))
451 {
452 return (self->cache.lsap);
453 }
454#endif
455
456 spin_lock_irqsave(&queue->hb_spinlock, flags);
457
458 lsap = (struct lsap_cb *) hashbin_get_first(queue);
459 while (lsap != NULL) {
460 /*
461 * If this is an incoming connection, then the destination
462 * LSAP selector may have been specified as LM_ANY so that
463 * any client can connect. In that case we only need to check
464 * if the source LSAP (in our view!) match!
465 */
466 if ((status == CONNECT_CMD) &&
467 (lsap->slsap_sel == slsap_sel) &&
468 (lsap->dlsap_sel == LSAP_ANY)) {
469 /* This is where the dest lsap sel is set on incoming
470 * lsaps */
471 lsap->dlsap_sel = dlsap_sel;
472 break;
473 }
474 /*
475 * Check if source LSAP and dest LSAP selectors match.
476 */
477 if ((lsap->slsap_sel == slsap_sel) &&
478 (lsap->dlsap_sel == dlsap_sel))
479 break;
480
481 lsap = (struct lsap_cb *) hashbin_get_next(queue);
482 }
483#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
484 if(lsap)
485 irlmp_update_cache(self, lsap);
486#endif
487 spin_unlock_irqrestore(&queue->hb_spinlock, flags);
488
489 /* Return what we've found or NULL */
490 return lsap;
491}
diff --git a/net/irda/irmod.c b/net/irda/irmod.c
new file mode 100644
index 00000000000..6ffaed4544e
--- /dev/null
+++ b/net/irda/irmod.c
@@ -0,0 +1,185 @@
1/*********************************************************************
2 *
3 * Filename: irmod.c
4 * Version: 0.9
5 * Description: IrDA stack main entry points
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Mon Dec 15 13:55:39 1997
9 * Modified at: Wed Jan 5 15:12:41 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1997, 1999-2000 Dag Brattli, All Rights Reserved.
13 * Copyright (c) 2000-2004 Jean Tourrilhes <jt@hpl.hp.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * Neither Dag Brattli nor University of Tromsø admit liability nor
21 * provide warranty for any of this software. This material is
22 * provided "AS-IS" and at no charge.
23 *
24 ********************************************************************/
25
26/*
27 * This file contains the main entry points of the IrDA stack.
28 * They are in this file and not af_irda.c because some developpers
29 * are using the IrDA stack without the socket API (compiling out
30 * af_irda.c).
31 * Jean II
32 */
33
34#include <linux/config.h>
35#include <linux/module.h>
36#include <linux/moduleparam.h>
37
38#include <net/irda/irda.h>
39#include <net/irda/irmod.h> /* notify_t */
40#include <net/irda/irlap.h> /* irlap_init */
41#include <net/irda/irlmp.h> /* irlmp_init */
42#include <net/irda/iriap.h> /* iriap_init */
43#include <net/irda/irttp.h> /* irttp_init */
44#include <net/irda/irda_device.h> /* irda_device_init */
45
46/* irproc.c */
47extern void irda_proc_register(void);
48extern void irda_proc_unregister(void);
49/* irsysctl.c */
50extern int irda_sysctl_register(void);
51extern void irda_sysctl_unregister(void);
52/* af_irda.c */
53extern int irsock_init(void);
54extern void irsock_cleanup(void);
55/* irlap_frame.c */
56extern int irlap_driver_rcv(struct sk_buff *, struct net_device *,
57 struct packet_type *);
58
59/*
60 * Module parameters
61 */
62#ifdef CONFIG_IRDA_DEBUG
63unsigned int irda_debug = IRDA_DEBUG_LEVEL;
64module_param_named(debug, irda_debug, uint, 0);
65MODULE_PARM_DESC(debug, "IRDA debugging level");
66EXPORT_SYMBOL(irda_debug);
67#endif
68
69/* Packet type handler.
70 * Tell the kernel how IrDA packets should be handled.
71 */
72static struct packet_type irda_packet_type = {
73 .type = __constant_htons(ETH_P_IRDA),
74 .func = irlap_driver_rcv, /* Packet type handler irlap_frame.c */
75};
76
77/*
78 * Function irda_notify_init (notify)
79 *
80 * Used for initializing the notify structure
81 *
82 */
83void irda_notify_init(notify_t *notify)
84{
85 notify->data_indication = NULL;
86 notify->udata_indication = NULL;
87 notify->connect_confirm = NULL;
88 notify->connect_indication = NULL;
89 notify->disconnect_indication = NULL;
90 notify->flow_indication = NULL;
91 notify->status_indication = NULL;
92 notify->instance = NULL;
93 strlcpy(notify->name, "Unknown", sizeof(notify->name));
94}
95EXPORT_SYMBOL(irda_notify_init);
96
97/*
98 * Function irda_init (void)
99 *
100 * Protocol stack initialisation entry point.
101 * Initialise the various components of the IrDA stack
102 */
103static int __init irda_init(void)
104{
105 IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
106
107 /* Lower layer of the stack */
108 irlmp_init();
109 irlap_init();
110
111 /* Higher layers of the stack */
112 iriap_init();
113 irttp_init();
114 irsock_init();
115
116 /* Add IrDA packet type (Start receiving packets) */
117 dev_add_pack(&irda_packet_type);
118
119 /* External APIs */
120#ifdef CONFIG_PROC_FS
121 irda_proc_register();
122#endif
123#ifdef CONFIG_SYSCTL
124 irda_sysctl_register();
125#endif
126
127 /* Driver/dongle support */
128 irda_device_init();
129
130 return 0;
131}
132
133/*
134 * Function irda_cleanup (void)
135 *
136 * Protocol stack cleanup/removal entry point.
137 * Cleanup the various components of the IrDA stack
138 */
139static void __exit irda_cleanup(void)
140{
141 /* Remove External APIs */
142#ifdef CONFIG_SYSCTL
143 irda_sysctl_unregister();
144#endif
145#ifdef CONFIG_PROC_FS
146 irda_proc_unregister();
147#endif
148
149 /* Remove IrDA packet type (stop receiving packets) */
150 dev_remove_pack(&irda_packet_type);
151
152 /* Remove higher layers */
153 irsock_cleanup();
154 irttp_cleanup();
155 iriap_cleanup();
156
157 /* Remove lower layers */
158 irda_device_cleanup();
159 irlap_cleanup(); /* Must be done before irlmp_cleanup()! DB */
160
161 /* Remove middle layer */
162 irlmp_cleanup();
163}
164
165/*
166 * The IrDA stack must be initialised *before* drivers get initialised,
167 * and *before* higher protocols (IrLAN/IrCOMM/IrNET) get initialised,
168 * otherwise bad things will happen (hashbins will be NULL for example).
169 * Those modules are at module_init()/device_initcall() level.
170 *
171 * On the other hand, it needs to be initialised *after* the basic
172 * networking, the /proc/net filesystem and sysctl module. Those are
173 * currently initialised in .../init/main.c (before initcalls).
174 * Also, IrDA drivers needs to be initialised *after* the random number
175 * generator (main stack and higher layer init don't need it anymore).
176 *
177 * Jean II
178 */
179subsys_initcall(irda_init);
180module_exit(irda_cleanup);
181
182MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no> & Jean Tourrilhes <jt@hpl.hp.com>");
183MODULE_DESCRIPTION("The Linux IrDA Protocol Stack");
184MODULE_LICENSE("GPL");
185MODULE_ALIAS_NETPROTO(PF_IRDA);
diff --git a/net/irda/irnet/Kconfig b/net/irda/irnet/Kconfig
new file mode 100644
index 00000000000..28c557f0fdd
--- /dev/null
+++ b/net/irda/irnet/Kconfig
@@ -0,0 +1,13 @@
1config IRNET
2 tristate "IrNET protocol"
3 depends on IRDA && PPP
4 help
5 Say Y here if you want to build support for the IrNET protocol.
6 To compile it as a module, choose M here: the module will be
7 called irnet. IrNET is a PPP driver, so you will also need a
8 working PPP subsystem (driver, daemon and config)...
9
10 IrNET is an alternate way to transfer TCP/IP traffic over IrDA. It
11 uses synchronous PPP over a set of point to point IrDA sockets. You
12 can use it between Linux machine or with W2k.
13
diff --git a/net/irda/irnet/Makefile b/net/irda/irnet/Makefile
new file mode 100644
index 00000000000..b3ee01e0def
--- /dev/null
+++ b/net/irda/irnet/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the Linux IrDA IrNET protocol layer.
3#
4
5obj-$(CONFIG_IRNET) += irnet.o
6
7irnet-objs := irnet_ppp.o irnet_irda.o
diff --git a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h
new file mode 100644
index 00000000000..9004f7349a7
--- /dev/null
+++ b/net/irda/irnet/irnet.h
@@ -0,0 +1,529 @@
1/*
2 * IrNET protocol module : Synchronous PPP over an IrDA socket.
3 *
4 * Jean II - HPL `00 - <jt@hpl.hp.com>
5 *
6 * This file contains definitions and declarations global to the IrNET module,
7 * all grouped in one place...
8 * This file is a *private* header, so other modules don't want to know
9 * what's in there...
10 *
11 * Note : as most part of the Linux kernel, this module is available
12 * under the GNU General Public License (GPL).
13 */
14
15#ifndef IRNET_H
16#define IRNET_H
17
18/************************** DOCUMENTATION ***************************/
19/*
20 * What is IrNET
21 * -------------
22 * IrNET is a protocol allowing to carry TCP/IP traffic between two
23 * IrDA peers in an efficient fashion. It is a thin layer, passing PPP
24 * packets to IrTTP and vice versa. It uses PPP in synchronous mode,
25 * because IrTTP offer a reliable sequenced packet service (as opposed
26 * to a byte stream). In fact, you could see IrNET as carrying TCP/IP
27 * in a IrDA socket, using PPP to provide the glue.
28 *
29 * The main difference with traditional PPP over IrCOMM is that we
30 * avoid the framing and serial emulation which are a performance
31 * bottleneck. It also allows multipoint communications in a sensible
32 * fashion.
33 *
34 * The main difference with IrLAN is that we use PPP for the link
35 * management, which is more standard, interoperable and flexible than
36 * the IrLAN protocol. For example, PPP adds authentication,
37 * encryption, compression, header compression and automated routing
38 * setup. And, as IrNET let PPP do the hard work, the implementation
39 * is much simpler than IrLAN.
40 *
41 * The Linux implementation
42 * ------------------------
43 * IrNET is written on top of the Linux-IrDA stack, and interface with
44 * the generic Linux PPP driver. Because IrNET depend on recent
45 * changes of the PPP driver interface, IrNET will work only with very
46 * recent kernel (2.3.99-pre6 and up).
47 *
48 * The present implementation offer the following features :
49 * o simple user interface using pppd
50 * o efficient implementation (interface directly to PPP and IrTTP)
51 * o addressing (you can specify the name of the IrNET recipient)
52 * o multipoint operation (limited by IrLAP specification)
53 * o information in /proc/net/irda/irnet
54 * o IrNET events on /dev/irnet (for user space daemon)
55 * o IrNET daemon (irnetd) to automatically handle incoming requests
56 * o Windows 2000 compatibility (tested, but need more work)
57 * Currently missing :
58 * o Lot's of testing (that's your job)
59 * o Connection retries (may be too hard to do)
60 * o Check pppd persist mode
61 * o User space daemon (to automatically handle incoming requests)
62 *
63 * The setup is not currently the most easy, but this should get much
64 * better when everything will get integrated...
65 *
66 * Acknowledgements
67 * ----------------
68 * This module is based on :
69 * o The PPP driver (ppp_synctty/ppp_generic) by Paul Mackerras
70 * o The IrLAN protocol (irlan_common/XXX) by Dag Brattli
71 * o The IrSock interface (af_irda) by Dag Brattli
72 * o Some other bits from the kernel and my drivers...
73 * Infinite thanks to those brave souls for providing the infrastructure
74 * upon which IrNET is built.
75 *
76 * Thanks to all my collegues in HP for helping me. In particular,
77 * thanks to Salil Pradhan and Bill Serra for W2k testing...
78 * Thanks to Luiz Magalhaes for irnetd and much testing...
79 *
80 * Thanks to Alan Cox for answering lot's of my stupid questions, and
81 * to Paul Mackerras answering my questions on how to best integrate
82 * IrNET and pppd.
83 *
84 * Jean II
85 *
86 * Note on some implementations choices...
87 * ------------------------------------
88 * 1) Direct interface vs tty/socket
89 * I could have used a tty interface to hook to ppp and use the full
90 * socket API to connect to IrDA. The code would have been easier to
91 * maintain, and maybe the code would have been smaller...
92 * Instead, we hook directly to ppp_generic and to IrTTP, which make
93 * things more complicated...
94 *
95 * The first reason is flexibility : this allow us to create IrNET
96 * instances on demand (no /dev/ircommX crap) and to allow linkname
97 * specification on pppd command line...
98 *
99 * Second reason is speed optimisation. If you look closely at the
100 * transmit and receive paths, you will notice that they are "super lean"
101 * (that's why they look ugly), with no function calls and as little data
102 * copy and modification as I could...
103 *
104 * 2) irnetd in user space
105 * irnetd is implemented in user space, which is necessary to call pppd.
106 * This also give maximum benefits in term of flexibility and customability,
107 * and allow to offer the event channel, useful for other stuff like debug.
108 *
109 * On the other hand, this require a loose coordination between the
110 * present module and irnetd. One critical area is how incoming request
111 * are handled.
112 * When irnet receive an incoming request, it send an event to irnetd and
113 * drop the incoming IrNET socket.
114 * irnetd start a pppd instance, which create a new IrNET socket. This new
115 * socket is then connected in the originating node to the pppd instance.
116 * At this point, in the originating node, the first socket is closed.
117 *
118 * I admit, this is a bit messy and waste some resources. The alternative
119 * is caching incoming socket, and that's also quite messy and waste
120 * resources.
121 * We also make connection time slower. For example, on a 115 kb/s link it
122 * adds 60ms to the connection time (770 ms). However, this is slower than
123 * the time it takes to fire up pppd on my P133...
124 *
125 *
126 * History :
127 * -------
128 *
129 * v1 - 15.5.00 - Jean II
130 * o Basic IrNET (hook to ppp_generic & IrTTP - incl. multipoint)
131 * o control channel on /dev/irnet (set name/address)
132 * o event channel on /dev/irnet (for user space daemon)
133 *
134 * v2 - 5.6.00 - Jean II
135 * o Enable DROP_NOT_READY to avoid PPP timeouts & other weirdness...
136 * o Add DISCONNECT_TO event and rename DISCONNECT_FROM.
137 * o Set official device number alloaction on /dev/irnet
138 *
139 * v3 - 30.8.00 - Jean II
140 * o Update to latest Linux-IrDA changes :
141 * - queue_t => irda_queue_t
142 * o Update to ppp-2.4.0 :
143 * - move irda_irnet_connect from PPPIOCATTACH to TIOCSETD
144 * o Add EXPIRE event (depend on new IrDA-Linux patch)
145 * o Switch from `hashbin_remove' to `hashbin_remove_this' to fix
146 * a multilink bug... (depend on new IrDA-Linux patch)
147 * o fix a self->daddr to self->raddr in irda_irnet_connect to fix
148 * another multilink bug (darn !)
149 * o Remove LINKNAME_IOCTL cruft
150 *
151 * v3b - 31.8.00 - Jean II
152 * o Dump discovery log at event channel startup
153 *
154 * v4 - 28.9.00 - Jean II
155 * o Fix interaction between poll/select and dump discovery log
156 * o Add IRNET_BLOCKED_LINK event (depend on new IrDA-Linux patch)
157 * o Add IRNET_NOANSWER_FROM event (mostly to help support)
158 * o Release flow control in disconnect_indication
159 * o Block packets while connecting (speed up connections)
160 *
161 * v5 - 11.01.01 - Jean II
162 * o Init self->max_header_size, just in case...
163 * o Set up ap->chan.hdrlen, to get zero copy on tx side working.
164 * o avoid tx->ttp->flow->ppp->tx->... loop, by checking flow state
165 * Thanks to Christian Gennerat for finding this bug !
166 * ---
167 * o Declare the proper MTU/MRU that we can support
168 * (but PPP doesn't read the MTU value :-()
169 * o Declare hashbin HB_NOLOCK instead of HB_LOCAL to avoid
170 * disabling and enabling irq twice
171 *
172 * v6 - 31.05.01 - Jean II
173 * o Print source address in Found, Discovery, Expiry & Request events
174 * o Print requested source address in /proc/net/irnet
175 * o Change control channel input. Allow multiple commands in one line.
176 * o Add saddr command to change ap->rsaddr (and use that in IrDA)
177 * ---
178 * o Make the IrDA connection procedure totally asynchronous.
179 * Heavy rewrite of the IAS query code and the whole connection
180 * procedure. Now, irnet_connect() no longer need to be called from
181 * a process context...
182 * o Enable IrDA connect retries in ppp_irnet_send(). The good thing
183 * is that IrDA connect retries are directly driven by PPP LCP
184 * retries (we retry for each LCP packet), so that everything
185 * is transparently controlled from pppd lcp-max-configure.
186 * o Add ttp_connect flag to prevent rentry on the connect procedure
187 * o Test and fixups to eliminate side effects of retries
188 *
189 * v7 - 22.08.01 - Jean II
190 * o Cleanup : Change "saddr = 0x0" to "saddr = DEV_ADDR_ANY"
191 * o Fix bug in BLOCK_WHEN_CONNECT introduced in v6 : due to the
192 * asynchronous IAS query, self->tsap is NULL when PPP send the
193 * first packet. This was preventing "connect-delay 0" to work.
194 * Change the test in ppp_irnet_send() to self->ttp_connect.
195 *
196 * v8 - 1.11.01 - Jean II
197 * o Tighten the use of self->ttp_connect and self->ttp_open to
198 * prevent various race conditions.
199 * o Avoid leaking discovery log and skb
200 * o Replace "self" with "server" in irnet_connect_indication() to
201 * better detect cut'n'paste error ;-)
202 *
203 * v9 - 29.11.01 - Jean II
204 * o Fix event generation in disconnect indication that I broke in v8
205 * It was always generation "No-Answer" because I was testing ttp_open
206 * just after clearing it. *blush*.
207 * o Use newly created irttp_listen() to fix potential crash when LAP
208 * destroyed before irnet module removed.
209 *
210 * v10 - 4.3.2 - Jean II
211 * o When receiving a disconnect indication, don't reenable the
212 * PPP Tx queue, this will trigger a reconnect. Instead, close
213 * the channel, which will kill pppd...
214 *
215 * v11 - 20.3.02 - Jean II
216 * o Oops ! v10 fix disabled IrNET retries and passive behaviour.
217 * Better fix in irnet_disconnect_indication() :
218 * - if connected, kill pppd via hangup.
219 * - if not connected, reenable ppp Tx, which trigger IrNET retry.
220 *
221 * v12 - 10.4.02 - Jean II
222 * o Fix race condition in irnet_connect_indication().
223 * If the socket was already trying to connect, drop old connection
224 * and use new one only if acting as primary. See comments.
225 *
226 * v13 - 30.5.02 - Jean II
227 * o Update module init code
228 *
229 * v14 - 20.2.03 - Jean II
230 * o Add discovery hint bits in the control channel.
231 * o Remove obsolete MOD_INC/DEC_USE_COUNT in favor of .owner
232 *
233 * v15 - 7.4.03 - Jean II
234 * o Replace spin_lock_irqsave() with spin_lock_bh() so that we can
235 * use ppp_unit_number(). It's probably also better overall...
236 * o Disable call to ppp_unregister_channel(), because we can't do it.
237 */
238
239/***************************** INCLUDES *****************************/
240
241#include <linux/module.h>
242
243#include <linux/kernel.h>
244#include <linux/skbuff.h>
245#include <linux/tty.h>
246#include <linux/proc_fs.h>
247#include <linux/devfs_fs_kernel.h>
248#include <linux/netdevice.h>
249#include <linux/miscdevice.h>
250#include <linux/poll.h>
251#include <linux/config.h>
252#include <linux/ctype.h> /* isspace() */
253#include <asm/uaccess.h>
254#include <linux/init.h>
255
256#include <linux/ppp_defs.h>
257#include <linux/if_ppp.h>
258#include <linux/ppp_channel.h>
259
260#include <net/irda/irda.h>
261#include <net/irda/iriap.h>
262#include <net/irda/irias_object.h>
263#include <net/irda/irlmp.h>
264#include <net/irda/irttp.h>
265#include <net/irda/discovery.h>
266
267/***************************** OPTIONS *****************************/
268/*
269 * Define or undefine to compile or not some optional part of the
270 * IrNET driver...
271 * Note : the present defaults make sense, play with that at your
272 * own risk...
273 */
274/* IrDA side of the business... */
275#define DISCOVERY_NOMASK /* To enable W2k compatibility... */
276#define ADVERTISE_HINT /* Advertise IrLAN hint bit */
277#define ALLOW_SIMULT_CONNECT /* This seem to work, cross fingers... */
278#define DISCOVERY_EVENTS /* Query the discovery log to post events */
279#define INITIAL_DISCOVERY /* Dump current discovery log as events */
280#undef STREAM_COMPAT /* Not needed - potentially messy */
281#undef CONNECT_INDIC_KICK /* Might mess IrDA, not needed */
282#undef FAIL_SEND_DISCONNECT /* Might mess IrDA, not needed */
283#undef PASS_CONNECT_PACKETS /* Not needed ? Safe */
284#undef MISSING_PPP_API /* Stuff I wish I could do */
285
286/* PPP side of the business */
287#define BLOCK_WHEN_CONNECT /* Block packets when connecting */
288#define CONNECT_IN_SEND /* Retry IrDA connection procedure */
289#undef FLUSH_TO_PPP /* Not sure about this one, let's play safe */
290#undef SECURE_DEVIRNET /* Bah... */
291
292/****************************** DEBUG ******************************/
293
294/*
295 * This set of flags enable and disable all the various warning,
296 * error and debug message of this driver.
297 * Each section can be enabled and disabled independently
298 */
299/* In the PPP part */
300#define DEBUG_CTRL_TRACE 0 /* Control channel */
301#define DEBUG_CTRL_INFO 0 /* various info */
302#define DEBUG_CTRL_ERROR 1 /* problems */
303#define DEBUG_FS_TRACE 0 /* filesystem callbacks */
304#define DEBUG_FS_INFO 0 /* various info */
305#define DEBUG_FS_ERROR 1 /* problems */
306#define DEBUG_PPP_TRACE 0 /* PPP related functions */
307#define DEBUG_PPP_INFO 0 /* various info */
308#define DEBUG_PPP_ERROR 1 /* problems */
309#define DEBUG_MODULE_TRACE 0 /* module insertion/removal */
310#define DEBUG_MODULE_ERROR 1 /* problems */
311
312/* In the IrDA part */
313#define DEBUG_IRDA_SR_TRACE 0 /* IRDA subroutines */
314#define DEBUG_IRDA_SR_INFO 0 /* various info */
315#define DEBUG_IRDA_SR_ERROR 1 /* problems */
316#define DEBUG_IRDA_SOCK_TRACE 0 /* IRDA main socket functions */
317#define DEBUG_IRDA_SOCK_INFO 0 /* various info */
318#define DEBUG_IRDA_SOCK_ERROR 1 /* problems */
319#define DEBUG_IRDA_SERV_TRACE 0 /* The IrNET server */
320#define DEBUG_IRDA_SERV_INFO 0 /* various info */
321#define DEBUG_IRDA_SERV_ERROR 1 /* problems */
322#define DEBUG_IRDA_TCB_TRACE 0 /* IRDA IrTTP callbacks */
323#define DEBUG_IRDA_CB_INFO 0 /* various info */
324#define DEBUG_IRDA_CB_ERROR 1 /* problems */
325#define DEBUG_IRDA_OCB_TRACE 0 /* IRDA other callbacks */
326#define DEBUG_IRDA_OCB_INFO 0 /* various info */
327#define DEBUG_IRDA_OCB_ERROR 1 /* problems */
328
329#define DEBUG_ASSERT 0 /* Verify all assertions */
330
331/*
332 * These are the macros we are using to actually print the debug
333 * statements. Don't look at it, it's ugly...
334 *
335 * One of the trick is that, as the DEBUG_XXX are constant, the
336 * compiler will optimise away the if() in all cases.
337 */
338/* All error messages (will show up in the normal logs) */
339#define DERROR(dbg, format, args...) \
340 {if(DEBUG_##dbg) \
341 printk(KERN_INFO "irnet: %s(): " format, __FUNCTION__ , ##args);}
342
343/* Normal debug message (will show up in /var/log/debug) */
344#define DEBUG(dbg, format, args...) \
345 {if(DEBUG_##dbg) \
346 printk(KERN_DEBUG "irnet: %s(): " format, __FUNCTION__ , ##args);}
347
348/* Entering a function (trace) */
349#define DENTER(dbg, format, args...) \
350 {if(DEBUG_##dbg) \
351 printk(KERN_DEBUG "irnet: -> %s" format, __FUNCTION__ , ##args);}
352
353/* Entering and exiting a function in one go (trace) */
354#define DPASS(dbg, format, args...) \
355 {if(DEBUG_##dbg) \
356 printk(KERN_DEBUG "irnet: <>%s" format, __FUNCTION__ , ##args);}
357
358/* Exiting a function (trace) */
359#define DEXIT(dbg, format, args...) \
360 {if(DEBUG_##dbg) \
361 printk(KERN_DEBUG "irnet: <-%s()" format, __FUNCTION__ , ##args);}
362
363/* Exit a function with debug */
364#define DRETURN(ret, dbg, args...) \
365 {DEXIT(dbg, ": " args);\
366 return ret; }
367
368/* Exit a function on failed condition */
369#define DABORT(cond, ret, dbg, args...) \
370 {if(cond) {\
371 DERROR(dbg, args);\
372 return ret; }}
373
374/* Invalid assertion, print out an error and exit... */
375#define DASSERT(cond, ret, dbg, args...) \
376 {if((DEBUG_ASSERT) && !(cond)) {\
377 DERROR(dbg, "Invalid assertion: " args);\
378 return ret; }}
379
380/************************ CONSTANTS & MACROS ************************/
381
382/* Paranoia */
383#define IRNET_MAGIC 0xB00754
384
385/* Number of control events in the control channel buffer... */
386#define IRNET_MAX_EVENTS 8 /* Should be more than enough... */
387
388/****************************** TYPES ******************************/
389
390/*
391 * This is the main structure where we store all the data pertaining to
392 * one instance of irnet.
393 * Note : in irnet functions, a pointer this structure is usually called
394 * "ap" or "self". If the code is borrowed from the IrDA stack, it tend
395 * to be called "self", and if it is borrowed from the PPP driver it is
396 * "ap". Apart from that, it's exactly the same structure ;-)
397 */
398typedef struct irnet_socket
399{
400 /* ------------------- Instance management ------------------- */
401 /* We manage a linked list of IrNET socket instances */
402 irda_queue_t q; /* Must be first - for hasbin */
403 int magic; /* Paranoia */
404
405 /* --------------------- FileSystem part --------------------- */
406 /* "pppd" interact directly with us on a /dev/ file */
407 struct file * file; /* File descriptor of this instance */
408 /* TTY stuff - to keep "pppd" happy */
409 struct termios termios; /* Various tty flags */
410 /* Stuff for the control channel */
411 int event_index; /* Last read in the event log */
412
413 /* ------------------------- PPP part ------------------------- */
414 /* We interface directly to the ppp_generic driver in the kernel */
415 int ppp_open; /* registered with ppp_generic */
416 struct ppp_channel chan; /* Interface to generic ppp layer */
417
418 int mru; /* Max size of PPP payload */
419 u32 xaccm[8]; /* Asynchronous character map (just */
420 u32 raccm; /* to please pppd - dummy) */
421 unsigned int flags; /* PPP flags (compression, ...) */
422 unsigned int rbits; /* Unused receive flags ??? */
423
424 /* ------------------------ IrTTP part ------------------------ */
425 /* We create a pseudo "socket" over the IrDA tranport */
426 unsigned long ttp_open; /* Set when IrTTP is ready */
427 unsigned long ttp_connect; /* Set when IrTTP is connecting */
428 struct tsap_cb * tsap; /* IrTTP instance (the connection) */
429
430 char rname[NICKNAME_MAX_LEN + 1];
431 /* IrDA nickname of destination */
432 __u32 rdaddr; /* Requested peer IrDA address */
433 __u32 rsaddr; /* Requested local IrDA address */
434 __u32 daddr; /* actual peer IrDA address */
435 __u32 saddr; /* my local IrDA address */
436 __u8 dtsap_sel; /* Remote TSAP selector */
437 __u8 stsap_sel; /* Local TSAP selector */
438
439 __u32 max_sdu_size_rx;/* Socket parameters used for IrTTP */
440 __u32 max_sdu_size_tx;
441 __u32 max_data_size;
442 __u8 max_header_size;
443 LOCAL_FLOW tx_flow; /* State of the Tx path in IrTTP */
444
445 /* ------------------- IrLMP and IrIAS part ------------------- */
446 /* Used for IrDA Discovery and socket name resolution */
447 void * ckey; /* IrLMP client handle */
448 __u16 mask; /* Hint bits mask (filter discov.)*/
449 int nslots; /* Number of slots for discovery */
450
451 struct iriap_cb * iriap; /* Used to query remote IAS */
452 int errno; /* status of the IAS query */
453
454 /* -------------------- Discovery log part -------------------- */
455 /* Used by initial discovery on the control channel
456 * and by irnet_discover_daddr_and_lsap_sel() */
457 struct irda_device_info *discoveries; /* Copy of the discovery log */
458 int disco_index; /* Last read in the discovery log */
459 int disco_number; /* Size of the discovery log */
460
461} irnet_socket;
462
463/*
464 * This is the various event that we will generate on the control channel
465 */
466typedef enum irnet_event
467{
468 IRNET_DISCOVER, /* New IrNET node discovered */
469 IRNET_EXPIRE, /* IrNET node expired */
470 IRNET_CONNECT_TO, /* IrNET socket has connected to other node */
471 IRNET_CONNECT_FROM, /* Other node has connected to IrNET socket */
472 IRNET_REQUEST_FROM, /* Non satisfied connection request */
473 IRNET_NOANSWER_FROM, /* Failed connection request */
474 IRNET_BLOCKED_LINK, /* Link (IrLAP) is blocked for > 3s */
475 IRNET_DISCONNECT_FROM, /* IrNET socket has disconnected */
476 IRNET_DISCONNECT_TO /* Closing IrNET socket */
477} irnet_event;
478
479/*
480 * This is the storage for an event and its arguments
481 */
482typedef struct irnet_log
483{
484 irnet_event event;
485 int unit;
486 __u32 saddr;
487 __u32 daddr;
488 char name[NICKNAME_MAX_LEN + 1]; /* 21 + 1 */
489 __u16_host_order hints; /* Discovery hint bits */
490} irnet_log;
491
492/*
493 * This is the storage for all events and related stuff...
494 */
495typedef struct irnet_ctrl_channel
496{
497 irnet_log log[IRNET_MAX_EVENTS]; /* Event log */
498 int index; /* Current index in log */
499 spinlock_t spinlock; /* Serialize access to the event log */
500 wait_queue_head_t rwait; /* processes blocked on read (or poll) */
501} irnet_ctrl_channel;
502
503/**************************** PROTOTYPES ****************************/
504/*
505 * Global functions of the IrNET module
506 * Note : we list here also functions called from one file to the other.
507 */
508
509/* -------------------------- IRDA PART -------------------------- */
510extern int
511 irda_irnet_create(irnet_socket *); /* Initialise a IrNET socket */
512extern int
513 irda_irnet_connect(irnet_socket *); /* Try to connect over IrDA */
514extern void
515 irda_irnet_destroy(irnet_socket *); /* Teardown a IrNET socket */
516extern int
517 irda_irnet_init(void); /* Initialise IrDA part of IrNET */
518extern void
519 irda_irnet_cleanup(void); /* Teardown IrDA part of IrNET */
520/* ---------------------------- MODULE ---------------------------- */
521extern int
522 irnet_init(void); /* Initialise IrNET module */
523
524/**************************** VARIABLES ****************************/
525
526/* Control channel stuff - allocated in irnet_irda.h */
527extern struct irnet_ctrl_channel irnet_events;
528
529#endif /* IRNET_H */
diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c
new file mode 100644
index 00000000000..07ec326c71f
--- /dev/null
+++ b/net/irda/irnet/irnet_irda.c
@@ -0,0 +1,1866 @@
1/*
2 * IrNET protocol module : Synchronous PPP over an IrDA socket.
3 *
4 * Jean II - HPL `00 - <jt@hpl.hp.com>
5 *
6 * This file implement the IRDA interface of IrNET.
7 * Basically, we sit on top of IrTTP. We set up IrTTP, IrIAS properly,
8 * and exchange frames with IrTTP.
9 */
10
11#include "irnet_irda.h" /* Private header */
12
13/************************* CONTROL CHANNEL *************************/
14/*
15 * When ppp is not active, /dev/irnet act as a control channel.
16 * Writing allow to set up the IrDA destination of the IrNET channel,
17 * and any application may be read events happening on IrNET...
18 */
19
20/*------------------------------------------------------------------*/
21/*
22 * Post an event to the control channel...
23 * Put the event in the log, and then wait all process blocked on read
24 * so they can read the log...
25 */
26static void
27irnet_post_event(irnet_socket * ap,
28 irnet_event event,
29 __u32 saddr,
30 __u32 daddr,
31 char * name,
32 __u16 hints)
33{
34 int index; /* In the log */
35
36 DENTER(CTRL_TRACE, "(ap=0x%p, event=%d, daddr=%08x, name=``%s'')\n",
37 ap, event, daddr, name);
38
39 /* Protect this section via spinlock.
40 * Note : as we are the only event producer, we only need to exclude
41 * ourself when touching the log, which is nice and easy.
42 */
43 spin_lock_bh(&irnet_events.spinlock);
44
45 /* Copy the event in the log */
46 index = irnet_events.index;
47 irnet_events.log[index].event = event;
48 irnet_events.log[index].daddr = daddr;
49 irnet_events.log[index].saddr = saddr;
50 /* Try to copy IrDA nickname */
51 if(name)
52 strcpy(irnet_events.log[index].name, name);
53 else
54 irnet_events.log[index].name[0] = '\0';
55 /* Copy hints */
56 irnet_events.log[index].hints.word = hints;
57 /* Try to get ppp unit number */
58 if((ap != (irnet_socket *) NULL) && (ap->ppp_open))
59 irnet_events.log[index].unit = ppp_unit_number(&ap->chan);
60 else
61 irnet_events.log[index].unit = -1;
62
63 /* Increment the index
64 * Note that we increment the index only after the event is written,
65 * to make sure that the readers don't get garbage... */
66 irnet_events.index = (index + 1) % IRNET_MAX_EVENTS;
67
68 DEBUG(CTRL_INFO, "New event index is %d\n", irnet_events.index);
69
70 /* Spin lock end */
71 spin_unlock_bh(&irnet_events.spinlock);
72
73 /* Now : wake up everybody waiting for events... */
74 wake_up_interruptible_all(&irnet_events.rwait);
75
76 DEXIT(CTRL_TRACE, "\n");
77}
78
79/************************* IRDA SUBROUTINES *************************/
80/*
81 * These are a bunch of subroutines called from other functions
82 * down there, mostly common code or to improve readability...
83 *
84 * Note : we duplicate quite heavily some routines of af_irda.c,
85 * because our input structure (self) is quite different
86 * (struct irnet instead of struct irda_sock), which make sharing
87 * the same code impossible (at least, without templates).
88 */
89
90/*------------------------------------------------------------------*/
91/*
92 * Function irda_open_tsap (self)
93 *
94 * Open local Transport Service Access Point (TSAP)
95 *
96 * Create a IrTTP instance for us and set all the IrTTP callbacks.
97 */
98static inline int
99irnet_open_tsap(irnet_socket * self)
100{
101 notify_t notify; /* Callback structure */
102
103 DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
104
105 DABORT(self->tsap != NULL, -EBUSY, IRDA_SR_ERROR, "Already busy !\n");
106
107 /* Initialize IrTTP callbacks to be used by the IrDA stack */
108 irda_notify_init(&notify);
109 notify.connect_confirm = irnet_connect_confirm;
110 notify.connect_indication = irnet_connect_indication;
111 notify.disconnect_indication = irnet_disconnect_indication;
112 notify.data_indication = irnet_data_indication;
113 /*notify.udata_indication = NULL;*/
114 notify.flow_indication = irnet_flow_indication;
115 notify.status_indication = irnet_status_indication;
116 notify.instance = self;
117 strlcpy(notify.name, IRNET_NOTIFY_NAME, sizeof(notify.name));
118
119 /* Open an IrTTP instance */
120 self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT,
121 &notify);
122 DABORT(self->tsap == NULL, -ENOMEM,
123 IRDA_SR_ERROR, "Unable to allocate TSAP !\n");
124
125 /* Remember which TSAP selector we actually got */
126 self->stsap_sel = self->tsap->stsap_sel;
127
128 DEXIT(IRDA_SR_TRACE, " - tsap=0x%p, sel=0x%X\n",
129 self->tsap, self->stsap_sel);
130 return 0;
131}
132
133/*------------------------------------------------------------------*/
134/*
135 * Function irnet_ias_to_tsap (self, result, value)
136 *
137 * Examine an IAS object and extract TSAP
138 *
139 * We do an IAP query to find the TSAP associated with the IrNET service.
140 * When IrIAP pass us the result of the query, this function look at
141 * the return values to check for failures and extract the TSAP if
142 * possible.
143 * Also deallocate value
144 * The failure is in self->errno
145 * Return TSAP or -1
146 */
147static inline __u8
148irnet_ias_to_tsap(irnet_socket * self,
149 int result,
150 struct ias_value * value)
151{
152 __u8 dtsap_sel = 0; /* TSAP we are looking for */
153
154 DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
155
156 /* By default, no error */
157 self->errno = 0;
158
159 /* Check if request succeeded */
160 switch(result)
161 {
162 /* Standard errors : service not available */
163 case IAS_CLASS_UNKNOWN:
164 case IAS_ATTRIB_UNKNOWN:
165 DEBUG(IRDA_SR_INFO, "IAS object doesn't exist ! (%d)\n", result);
166 self->errno = -EADDRNOTAVAIL;
167 break;
168
169 /* Other errors, most likely IrDA stack failure */
170 default :
171 DEBUG(IRDA_SR_INFO, "IAS query failed ! (%d)\n", result);
172 self->errno = -EHOSTUNREACH;
173 break;
174
175 /* Success : we got what we wanted */
176 case IAS_SUCCESS:
177 break;
178 }
179
180 /* Check what was returned to us */
181 if(value != NULL)
182 {
183 /* What type of argument have we got ? */
184 switch(value->type)
185 {
186 case IAS_INTEGER:
187 DEBUG(IRDA_SR_INFO, "result=%d\n", value->t.integer);
188 if(value->t.integer != -1)
189 /* Get the remote TSAP selector */
190 dtsap_sel = value->t.integer;
191 else
192 self->errno = -EADDRNOTAVAIL;
193 break;
194 default:
195 self->errno = -EADDRNOTAVAIL;
196 DERROR(IRDA_SR_ERROR, "bad type ! (0x%X)\n", value->type);
197 break;
198 }
199
200 /* Cleanup */
201 irias_delete_value(value);
202 }
203 else /* value == NULL */
204 {
205 /* Nothing returned to us - usually result != SUCCESS */
206 if(!(self->errno))
207 {
208 DERROR(IRDA_SR_ERROR,
209 "IrDA bug : result == SUCCESS && value == NULL\n");
210 self->errno = -EHOSTUNREACH;
211 }
212 }
213 DEXIT(IRDA_SR_TRACE, "\n");
214
215 /* Return the TSAP */
216 return(dtsap_sel);
217}
218
219/*------------------------------------------------------------------*/
220/*
221 * Function irnet_find_lsap_sel (self)
222 *
223 * Try to lookup LSAP selector in remote LM-IAS
224 *
225 * Basically, we start a IAP query, and then go to sleep. When the query
226 * return, irnet_getvalue_confirm will wake us up, and we can examine the
227 * result of the query...
228 * Note that in some case, the query fail even before we go to sleep,
229 * creating some races...
230 */
231static inline int
232irnet_find_lsap_sel(irnet_socket * self)
233{
234 DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
235
236 /* This should not happen */
237 DABORT(self->iriap, -EBUSY, IRDA_SR_ERROR, "busy with a previous query.\n");
238
239 /* Create an IAP instance, will be closed in irnet_getvalue_confirm() */
240 self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
241 irnet_getvalue_confirm);
242
243 /* Treat unexpected signals as disconnect */
244 self->errno = -EHOSTUNREACH;
245
246 /* Query remote LM-IAS */
247 iriap_getvaluebyclass_request(self->iriap, self->rsaddr, self->daddr,
248 IRNET_SERVICE_NAME, IRNET_IAS_VALUE);
249
250 /* The above request is non-blocking.
251 * After a while, IrDA will call us back in irnet_getvalue_confirm()
252 * We will then call irnet_ias_to_tsap() and finish the
253 * connection procedure */
254
255 DEXIT(IRDA_SR_TRACE, "\n");
256 return 0;
257}
258
259/*------------------------------------------------------------------*/
260/*
261 * Function irnet_connect_tsap (self)
262 *
263 * Initialise the TTP socket and initiate TTP connection
264 *
265 */
266static inline int
267irnet_connect_tsap(irnet_socket * self)
268{
269 int err;
270
271 DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
272
273 /* Open a local TSAP (an IrTTP instance) */
274 err = irnet_open_tsap(self);
275 if(err != 0)
276 {
277 clear_bit(0, &self->ttp_connect);
278 DERROR(IRDA_SR_ERROR, "connect aborted!\n");
279 return(err);
280 }
281
282 /* Connect to remote device */
283 err = irttp_connect_request(self->tsap, self->dtsap_sel,
284 self->rsaddr, self->daddr, NULL,
285 self->max_sdu_size_rx, NULL);
286 if(err != 0)
287 {
288 clear_bit(0, &self->ttp_connect);
289 DERROR(IRDA_SR_ERROR, "connect aborted!\n");
290 return(err);
291 }
292
293 /* The above call is non-blocking.
294 * After a while, the IrDA stack will either call us back in
295 * irnet_connect_confirm() or irnet_disconnect_indication()
296 * See you there ;-) */
297
298 DEXIT(IRDA_SR_TRACE, "\n");
299 return(err);
300}
301
302/*------------------------------------------------------------------*/
303/*
304 * Function irnet_discover_next_daddr (self)
305 *
306 * Query the IrNET TSAP of the next device in the log.
307 *
308 * Used in the TSAP discovery procedure.
309 */
310static inline int
311irnet_discover_next_daddr(irnet_socket * self)
312{
313 /* Close the last instance of IrIAP, and open a new one.
314 * We can't reuse the IrIAP instance in the IrIAP callback */
315 if(self->iriap)
316 {
317 iriap_close(self->iriap);
318 self->iriap = NULL;
319 }
320 /* Create a new IAP instance */
321 self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
322 irnet_discovervalue_confirm);
323 if(self->iriap == NULL)
324 return -ENOMEM;
325
326 /* Next discovery - before the call to avoid races */
327 self->disco_index++;
328
329 /* Check if we have one more address to try */
330 if(self->disco_index < self->disco_number)
331 {
332 /* Query remote LM-IAS */
333 iriap_getvaluebyclass_request(self->iriap,
334 self->discoveries[self->disco_index].saddr,
335 self->discoveries[self->disco_index].daddr,
336 IRNET_SERVICE_NAME, IRNET_IAS_VALUE);
337 /* The above request is non-blocking.
338 * After a while, IrDA will call us back in irnet_discovervalue_confirm()
339 * We will then call irnet_ias_to_tsap() and come back here again... */
340 return(0);
341 }
342 else
343 return(1);
344}
345
346/*------------------------------------------------------------------*/
347/*
348 * Function irnet_discover_daddr_and_lsap_sel (self)
349 *
350 * This try to find a device with the requested service.
351 *
352 * Initiate a TSAP discovery procedure.
353 * It basically look into the discovery log. For each address in the list,
354 * it queries the LM-IAS of the device to find if this device offer
355 * the requested service.
356 * If there is more than one node supporting the service, we complain
357 * to the user (it should move devices around).
358 * If we find one node which have the requested TSAP, we connect to it.
359 *
360 * This function just start the whole procedure. It request the discovery
361 * log and submit the first IAS query.
362 * The bulk of the job is handled in irnet_discovervalue_confirm()
363 *
364 * Note : this procedure fails if there is more than one device in range
365 * on the same dongle, because IrLMP doesn't disconnect the LAP when the
366 * last LSAP is closed. Moreover, we would need to wait the LAP
367 * disconnection...
368 */
369static inline int
370irnet_discover_daddr_and_lsap_sel(irnet_socket * self)
371{
372 int ret;
373
374 DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
375
376 /* Ask lmp for the current discovery log */
377 self->discoveries = irlmp_get_discoveries(&self->disco_number, self->mask,
378 DISCOVERY_DEFAULT_SLOTS);
379
380 /* Check if the we got some results */
381 if(self->discoveries == NULL)
382 {
383 self->disco_number = -1;
384 clear_bit(0, &self->ttp_connect);
385 DRETURN(-ENETUNREACH, IRDA_SR_INFO, "No Cachelog...\n");
386 }
387 DEBUG(IRDA_SR_INFO, "Got the log (0x%p), size is %d\n",
388 self->discoveries, self->disco_number);
389
390 /* Start with the first discovery */
391 self->disco_index = -1;
392 self->daddr = DEV_ADDR_ANY;
393
394 /* This will fail if the log is empty - this is non-blocking */
395 ret = irnet_discover_next_daddr(self);
396 if(ret)
397 {
398 /* Close IAP */
399 if(self->iriap)
400 iriap_close(self->iriap);
401 self->iriap = NULL;
402
403 /* Cleanup our copy of the discovery log */
404 kfree(self->discoveries);
405 self->discoveries = NULL;
406
407 clear_bit(0, &self->ttp_connect);
408 DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
409 }
410
411 /* Follow me in irnet_discovervalue_confirm() */
412
413 DEXIT(IRDA_SR_TRACE, "\n");
414 return(0);
415}
416
417/*------------------------------------------------------------------*/
418/*
419 * Function irnet_dname_to_daddr (self)
420 *
421 * Convert an IrDA nickname to a valid IrDA address
422 *
423 * It basically look into the discovery log until there is a match.
424 */
425static inline int
426irnet_dname_to_daddr(irnet_socket * self)
427{
428 struct irda_device_info *discoveries; /* Copy of the discovery log */
429 int number; /* Number of nodes in the log */
430 int i;
431
432 DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
433
434 /* Ask lmp for the current discovery log */
435 discoveries = irlmp_get_discoveries(&number, 0xffff,
436 DISCOVERY_DEFAULT_SLOTS);
437 /* Check if the we got some results */
438 if(discoveries == NULL)
439 DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
440
441 /*
442 * Now, check all discovered devices (if any), and connect
443 * client only about the services that the client is
444 * interested in...
445 */
446 for(i = 0; i < number; i++)
447 {
448 /* Does the name match ? */
449 if(!strncmp(discoveries[i].info, self->rname, NICKNAME_MAX_LEN))
450 {
451 /* Yes !!! Get it.. */
452 self->daddr = discoveries[i].daddr;
453 DEBUG(IRDA_SR_INFO, "discovered device ``%s'' at address 0x%08x.\n",
454 self->rname, self->daddr);
455 kfree(discoveries);
456 DEXIT(IRDA_SR_TRACE, "\n");
457 return 0;
458 }
459 }
460 /* No luck ! */
461 DEBUG(IRDA_SR_INFO, "cannot discover device ``%s'' !!!\n", self->rname);
462 kfree(discoveries);
463 return(-EADDRNOTAVAIL);
464}
465
466
467/************************* SOCKET ROUTINES *************************/
468/*
469 * This are the main operations on IrNET sockets, basically to create
470 * and destroy IrNET sockets. These are called from the PPP part...
471 */
472
473/*------------------------------------------------------------------*/
474/*
475 * Create a IrNET instance : just initialise some parameters...
476 */
477int
478irda_irnet_create(irnet_socket * self)
479{
480 DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
481
482 self->magic = IRNET_MAGIC; /* Paranoia */
483
484 self->ttp_open = 0; /* Prevent higher layer from accessing IrTTP */
485 self->ttp_connect = 0; /* Not connecting yet */
486 self->rname[0] = '\0'; /* May be set via control channel */
487 self->rdaddr = DEV_ADDR_ANY; /* May be set via control channel */
488 self->rsaddr = DEV_ADDR_ANY; /* May be set via control channel */
489 self->daddr = DEV_ADDR_ANY; /* Until we get connected */
490 self->saddr = DEV_ADDR_ANY; /* Until we get connected */
491 self->max_sdu_size_rx = TTP_SAR_UNBOUND;
492
493 /* Register as a client with IrLMP */
494 self->ckey = irlmp_register_client(0, NULL, NULL, NULL);
495#ifdef DISCOVERY_NOMASK
496 self->mask = 0xffff; /* For W2k compatibility */
497#else /* DISCOVERY_NOMASK */
498 self->mask = irlmp_service_to_hint(S_LAN);
499#endif /* DISCOVERY_NOMASK */
500 self->tx_flow = FLOW_START; /* Flow control from IrTTP */
501
502 DEXIT(IRDA_SOCK_TRACE, "\n");
503 return(0);
504}
505
506/*------------------------------------------------------------------*/
507/*
508 * Connect to the other side :
509 * o convert device name to an address
510 * o find the socket number (dlsap)
511 * o Establish the connection
512 *
513 * Note : We no longer mimic af_irda. The IAS query for finding the TSAP
514 * is done asynchronously, like the TTP connection. This allow us to
515 * call this function from any context (not only process).
516 * The downside is that following what's happening in there is tricky
517 * because it involve various functions all over the place...
518 */
519int
520irda_irnet_connect(irnet_socket * self)
521{
522 int err;
523
524 DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
525
526 /* Check if we are already trying to connect.
527 * Because irda_irnet_connect() can be called directly by pppd plus
528 * packet retries in ppp_generic and connect may take time, plus we may
529 * race with irnet_connect_indication(), we need to be careful there... */
530 if(test_and_set_bit(0, &self->ttp_connect))
531 DRETURN(-EBUSY, IRDA_SOCK_INFO, "Already connecting...\n");
532 if((self->iriap != NULL) || (self->tsap != NULL))
533 DERROR(IRDA_SOCK_ERROR, "Socket not cleaned up...\n");
534
535 /* Insert ourselves in the hashbin so that the IrNET server can find us.
536 * Notes : 4th arg is string of 32 char max and must be null terminated
537 * When 4th arg is used (string), 3rd arg isn't (int)
538 * Can't re-insert (MUST remove first) so check for that... */
539 if((irnet_server.running) && (self->q.q_next == NULL))
540 {
541 spin_lock_bh(&irnet_server.spinlock);
542 hashbin_insert(irnet_server.list, (irda_queue_t *) self, 0, self->rname);
543 spin_unlock_bh(&irnet_server.spinlock);
544 DEBUG(IRDA_SOCK_INFO, "Inserted ``%s'' in hashbin...\n", self->rname);
545 }
546
547 /* If we don't have anything (no address, no name) */
548 if((self->rdaddr == DEV_ADDR_ANY) && (self->rname[0] == '\0'))
549 {
550 /* Try to find a suitable address */
551 if((err = irnet_discover_daddr_and_lsap_sel(self)) != 0)
552 DRETURN(err, IRDA_SOCK_INFO, "auto-connect failed!\n");
553 /* In most cases, the call above is non-blocking */
554 }
555 else
556 {
557 /* If we have only the name (no address), try to get an address */
558 if(self->rdaddr == DEV_ADDR_ANY)
559 {
560 if((err = irnet_dname_to_daddr(self)) != 0)
561 DRETURN(err, IRDA_SOCK_INFO, "name connect failed!\n");
562 }
563 else
564 /* Use the requested destination address */
565 self->daddr = self->rdaddr;
566
567 /* Query remote LM-IAS to find LSAP selector */
568 irnet_find_lsap_sel(self);
569 /* The above call is non blocking */
570 }
571
572 /* At this point, we are waiting for the IrDA stack to call us back,
573 * or we have already failed.
574 * We will finish the connection procedure in irnet_connect_tsap().
575 */
576 DEXIT(IRDA_SOCK_TRACE, "\n");
577 return(0);
578}
579
580/*------------------------------------------------------------------*/
581/*
582 * Function irda_irnet_destroy(self)
583 *
584 * Destroy irnet instance
585 *
586 * Note : this need to be called from a process context.
587 */
588void
589irda_irnet_destroy(irnet_socket * self)
590{
591 DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
592 if(self == NULL)
593 return;
594
595 /* Remove ourselves from hashbin (if we are queued in hashbin)
596 * Note : `irnet_server.running' protect us from calls in hashbin_delete() */
597 if((irnet_server.running) && (self->q.q_next != NULL))
598 {
599 struct irnet_socket * entry;
600 DEBUG(IRDA_SOCK_INFO, "Removing from hash..\n");
601 spin_lock_bh(&irnet_server.spinlock);
602 entry = hashbin_remove_this(irnet_server.list, (irda_queue_t *) self);
603 self->q.q_next = NULL;
604 spin_unlock_bh(&irnet_server.spinlock);
605 DASSERT(entry == self, , IRDA_SOCK_ERROR, "Can't remove from hash.\n");
606 }
607
608 /* If we were connected, post a message */
609 if(test_bit(0, &self->ttp_open))
610 {
611 /* Note : as the disconnect comes from ppp_generic, the unit number
612 * doesn't exist anymore when we post the event, so we need to pass
613 * NULL as the first arg... */
614 irnet_post_event(NULL, IRNET_DISCONNECT_TO,
615 self->saddr, self->daddr, self->rname, 0);
616 }
617
618 /* Prevent various IrDA callbacks from messing up things
619 * Need to be first */
620 clear_bit(0, &self->ttp_connect);
621
622 /* Prevent higher layer from accessing IrTTP */
623 clear_bit(0, &self->ttp_open);
624
625 /* Unregister with IrLMP */
626 irlmp_unregister_client(self->ckey);
627
628 /* Unregister with LM-IAS */
629 if(self->iriap)
630 {
631 iriap_close(self->iriap);
632 self->iriap = NULL;
633 }
634
635 /* Cleanup eventual discoveries from connection attempt or control channel */
636 if(self->discoveries != NULL)
637 {
638 /* Cleanup our copy of the discovery log */
639 kfree(self->discoveries);
640 self->discoveries = NULL;
641 }
642
643 /* Close our IrTTP connection */
644 if(self->tsap)
645 {
646 DEBUG(IRDA_SOCK_INFO, "Closing our TTP connection.\n");
647 irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
648 irttp_close_tsap(self->tsap);
649 self->tsap = NULL;
650 }
651 self->stsap_sel = 0;
652
653 DEXIT(IRDA_SOCK_TRACE, "\n");
654 return;
655}
656
657
658/************************** SERVER SOCKET **************************/
659/*
660 * The IrNET service is composed of one server socket and a variable
661 * number of regular IrNET sockets. The server socket is supposed to
662 * handle incoming connections and redirect them to one IrNET sockets.
663 * It's a superset of the regular IrNET socket, but has a very distinct
664 * behaviour...
665 */
666
667/*------------------------------------------------------------------*/
668/*
669 * Function irnet_daddr_to_dname (self)
670 *
671 * Convert an IrDA address to a IrDA nickname
672 *
673 * It basically look into the discovery log until there is a match.
674 */
675static inline int
676irnet_daddr_to_dname(irnet_socket * self)
677{
678 struct irda_device_info *discoveries; /* Copy of the discovery log */
679 int number; /* Number of nodes in the log */
680 int i;
681
682 DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
683
684 /* Ask lmp for the current discovery log */
685 discoveries = irlmp_get_discoveries(&number, 0xffff,
686 DISCOVERY_DEFAULT_SLOTS);
687 /* Check if the we got some results */
688 if (discoveries == NULL)
689 DRETURN(-ENETUNREACH, IRDA_SERV_INFO, "Cachelog empty...\n");
690
691 /* Now, check all discovered devices (if any) */
692 for(i = 0; i < number; i++)
693 {
694 /* Does the name match ? */
695 if(discoveries[i].daddr == self->daddr)
696 {
697 /* Yes !!! Get it.. */
698 strlcpy(self->rname, discoveries[i].info, sizeof(self->rname));
699 self->rname[NICKNAME_MAX_LEN + 1] = '\0';
700 DEBUG(IRDA_SERV_INFO, "Device 0x%08x is in fact ``%s''.\n",
701 self->daddr, self->rname);
702 kfree(discoveries);
703 DEXIT(IRDA_SERV_TRACE, "\n");
704 return 0;
705 }
706 }
707 /* No luck ! */
708 DEXIT(IRDA_SERV_INFO, ": cannot discover device 0x%08x !!!\n", self->daddr);
709 kfree(discoveries);
710 return(-EADDRNOTAVAIL);
711}
712
713/*------------------------------------------------------------------*/
714/*
715 * Function irda_find_socket (self)
716 *
717 * Find the correct IrNET socket
718 *
719 * Look into the list of IrNET sockets and finds one with the right
720 * properties...
721 */
722static inline irnet_socket *
723irnet_find_socket(irnet_socket * self)
724{
725 irnet_socket * new = (irnet_socket *) NULL;
726 int err;
727
728 DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
729
730 /* Get the addresses of the requester */
731 self->daddr = irttp_get_daddr(self->tsap);
732 self->saddr = irttp_get_saddr(self->tsap);
733
734 /* Try to get the IrDA nickname of the requester */
735 err = irnet_daddr_to_dname(self);
736
737 /* Protect access to the instance list */
738 spin_lock_bh(&irnet_server.spinlock);
739
740 /* So now, try to get an socket having specifically
741 * requested that nickname */
742 if(err == 0)
743 {
744 new = (irnet_socket *) hashbin_find(irnet_server.list,
745 0, self->rname);
746 if(new)
747 DEBUG(IRDA_SERV_INFO, "Socket 0x%p matches rname ``%s''.\n",
748 new, new->rname);
749 }
750
751 /* If no name matches, try to find an socket by the destination address */
752 /* It can be either the requested destination address (set via the
753 * control channel), or the current destination address if the
754 * socket is in the middle of a connection request */
755 if(new == (irnet_socket *) NULL)
756 {
757 new = (irnet_socket *) hashbin_get_first(irnet_server.list);
758 while(new !=(irnet_socket *) NULL)
759 {
760 /* Does it have the same address ? */
761 if((new->rdaddr == self->daddr) || (new->daddr == self->daddr))
762 {
763 /* Yes !!! Get it.. */
764 DEBUG(IRDA_SERV_INFO, "Socket 0x%p matches daddr %#08x.\n",
765 new, self->daddr);
766 break;
767 }
768 new = (irnet_socket *) hashbin_get_next(irnet_server.list);
769 }
770 }
771
772 /* If we don't have any socket, get the first unconnected socket */
773 if(new == (irnet_socket *) NULL)
774 {
775 new = (irnet_socket *) hashbin_get_first(irnet_server.list);
776 while(new !=(irnet_socket *) NULL)
777 {
778 /* Is it available ? */
779 if(!(test_bit(0, &new->ttp_open)) && (new->rdaddr == DEV_ADDR_ANY) &&
780 (new->rname[0] == '\0') && (new->ppp_open))
781 {
782 /* Yes !!! Get it.. */
783 DEBUG(IRDA_SERV_INFO, "Socket 0x%p is free.\n",
784 new);
785 break;
786 }
787 new = (irnet_socket *) hashbin_get_next(irnet_server.list);
788 }
789 }
790
791 /* Spin lock end */
792 spin_unlock_bh(&irnet_server.spinlock);
793
794 DEXIT(IRDA_SERV_TRACE, " - new = 0x%p\n", new);
795 return new;
796}
797
798/*------------------------------------------------------------------*/
799/*
800 * Function irda_connect_socket (self)
801 *
802 * Connect an incoming connection to the socket
803 *
804 */
805static inline int
806irnet_connect_socket(irnet_socket * server,
807 irnet_socket * new,
808 struct qos_info * qos,
809 __u32 max_sdu_size,
810 __u8 max_header_size)
811{
812 DENTER(IRDA_SERV_TRACE, "(server=0x%p, new=0x%p)\n",
813 server, new);
814
815 /* Now attach up the new socket */
816 new->tsap = irttp_dup(server->tsap, new);
817 DABORT(new->tsap == NULL, -1, IRDA_SERV_ERROR, "dup failed!\n");
818
819 /* Set up all the relevant parameters on the new socket */
820 new->stsap_sel = new->tsap->stsap_sel;
821 new->dtsap_sel = new->tsap->dtsap_sel;
822 new->saddr = irttp_get_saddr(new->tsap);
823 new->daddr = irttp_get_daddr(new->tsap);
824
825 new->max_header_size = max_header_size;
826 new->max_sdu_size_tx = max_sdu_size;
827 new->max_data_size = max_sdu_size;
828#ifdef STREAM_COMPAT
829 /* If we want to receive "stream sockets" */
830 if(max_sdu_size == 0)
831 new->max_data_size = irttp_get_max_seg_size(new->tsap);
832#endif /* STREAM_COMPAT */
833
834 /* Clean up the original one to keep it in listen state */
835 irttp_listen(server->tsap);
836
837 /* Send a connection response on the new socket */
838 irttp_connect_response(new->tsap, new->max_sdu_size_rx, NULL);
839
840 /* Allow PPP to send its junk over the new socket... */
841 set_bit(0, &new->ttp_open);
842
843 /* Not connecting anymore, and clean up last possible remains
844 * of connection attempts on the socket */
845 clear_bit(0, &new->ttp_connect);
846 if(new->iriap)
847 {
848 iriap_close(new->iriap);
849 new->iriap = NULL;
850 }
851 if(new->discoveries != NULL)
852 {
853 kfree(new->discoveries);
854 new->discoveries = NULL;
855 }
856
857#ifdef CONNECT_INDIC_KICK
858 /* As currently we don't block packets in ppp_irnet_send() while passive,
859 * this is not really needed...
860 * Also, not doing it give IrDA a chance to finish the setup properly
861 * before being swamped with packets... */
862 ppp_output_wakeup(&new->chan);
863#endif /* CONNECT_INDIC_KICK */
864
865 /* Notify the control channel */
866 irnet_post_event(new, IRNET_CONNECT_FROM,
867 new->saddr, new->daddr, server->rname, 0);
868
869 DEXIT(IRDA_SERV_TRACE, "\n");
870 return 0;
871}
872
873/*------------------------------------------------------------------*/
874/*
875 * Function irda_disconnect_server (self)
876 *
877 * Cleanup the server socket when the incoming connection abort
878 *
879 */
880static inline void
881irnet_disconnect_server(irnet_socket * self,
882 struct sk_buff *skb)
883{
884 DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
885
886 /* Put the received packet in the black hole */
887 kfree_skb(skb);
888
889#ifdef FAIL_SEND_DISCONNECT
890 /* Tell the other party we don't want to be connected */
891 /* Hum... Is it the right thing to do ? And do we need to send
892 * a connect response before ? It looks ok without this... */
893 irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
894#endif /* FAIL_SEND_DISCONNECT */
895
896 /* Notify the control channel (see irnet_find_socket()) */
897 irnet_post_event(NULL, IRNET_REQUEST_FROM,
898 self->saddr, self->daddr, self->rname, 0);
899
900 /* Clean up the server to keep it in listen state */
901 irttp_listen(self->tsap);
902
903 DEXIT(IRDA_SERV_TRACE, "\n");
904 return;
905}
906
907/*------------------------------------------------------------------*/
908/*
909 * Function irda_setup_server (self)
910 *
911 * Create a IrTTP server and set it up...
912 *
913 * Register the IrLAN hint bit, create a IrTTP instance for us,
914 * set all the IrTTP callbacks and create an IrIAS entry...
915 */
916static inline int
917irnet_setup_server(void)
918{
919 __u16 hints;
920
921 DENTER(IRDA_SERV_TRACE, "()\n");
922
923 /* Initialise the regular socket part of the server */
924 irda_irnet_create(&irnet_server.s);
925
926 /* Open a local TSAP (an IrTTP instance) for the server */
927 irnet_open_tsap(&irnet_server.s);
928
929 /* PPP part setup */
930 irnet_server.s.ppp_open = 0;
931 irnet_server.s.chan.private = NULL;
932 irnet_server.s.file = NULL;
933
934 /* Get the hint bit corresponding to IrLAN */
935 /* Note : we overload the IrLAN hint bit. As it is only a "hint", and as
936 * we provide roughly the same functionality as IrLAN, this is ok.
937 * In fact, the situation is similar as JetSend overloading the Obex hint
938 */
939 hints = irlmp_service_to_hint(S_LAN);
940
941#ifdef ADVERTISE_HINT
942 /* Register with IrLMP as a service (advertise our hint bit) */
943 irnet_server.skey = irlmp_register_service(hints);
944#endif /* ADVERTISE_HINT */
945
946 /* Register with LM-IAS (so that people can connect to us) */
947 irnet_server.ias_obj = irias_new_object(IRNET_SERVICE_NAME, jiffies);
948 irias_add_integer_attrib(irnet_server.ias_obj, IRNET_IAS_VALUE,
949 irnet_server.s.stsap_sel, IAS_KERNEL_ATTR);
950 irias_insert_object(irnet_server.ias_obj);
951
952#ifdef DISCOVERY_EVENTS
953 /* Tell IrLMP we want to be notified of newly discovered nodes */
954 irlmp_update_client(irnet_server.s.ckey, hints,
955 irnet_discovery_indication, irnet_expiry_indication,
956 (void *) &irnet_server.s);
957#endif
958
959 DEXIT(IRDA_SERV_TRACE, " - self=0x%p\n", &irnet_server.s);
960 return 0;
961}
962
963/*------------------------------------------------------------------*/
964/*
965 * Function irda_destroy_server (self)
966 *
967 * Destroy the IrTTP server...
968 *
969 * Reverse of the previous function...
970 */
971static inline void
972irnet_destroy_server(void)
973{
974 DENTER(IRDA_SERV_TRACE, "()\n");
975
976#ifdef ADVERTISE_HINT
977 /* Unregister with IrLMP */
978 irlmp_unregister_service(irnet_server.skey);
979#endif /* ADVERTISE_HINT */
980
981 /* Unregister with LM-IAS */
982 if(irnet_server.ias_obj)
983 irias_delete_object(irnet_server.ias_obj);
984
985 /* Cleanup the socket part */
986 irda_irnet_destroy(&irnet_server.s);
987
988 DEXIT(IRDA_SERV_TRACE, "\n");
989 return;
990}
991
992
993/************************ IRDA-TTP CALLBACKS ************************/
994/*
995 * When we create a IrTTP instance, we pass to it a set of callbacks
996 * that IrTTP will call in case of various events.
997 * We take care of those events here.
998 */
999
1000/*------------------------------------------------------------------*/
1001/*
1002 * Function irnet_data_indication (instance, sap, skb)
1003 *
1004 * Received some data from TinyTP. Just queue it on the receive queue
1005 *
1006 */
1007static int
1008irnet_data_indication(void * instance,
1009 void * sap,
1010 struct sk_buff *skb)
1011{
1012 irnet_socket * ap = (irnet_socket *) instance;
1013 unsigned char * p;
1014 int code = 0;
1015
1016 DENTER(IRDA_TCB_TRACE, "(self/ap=0x%p, skb=0x%p)\n",
1017 ap, skb);
1018 DASSERT(skb != NULL, 0, IRDA_CB_ERROR, "skb is NULL !!!\n");
1019
1020 /* Check is ppp is ready to receive our packet */
1021 if(!ap->ppp_open)
1022 {
1023 DERROR(IRDA_CB_ERROR, "PPP not ready, dropping packet...\n");
1024 /* When we return error, TTP will need to requeue the skb and
1025 * will stop the sender. IrTTP will stall until we send it a
1026 * flow control request... */
1027 return -ENOMEM;
1028 }
1029
1030 /* strip address/control field if present */
1031 p = skb->data;
1032 if((p[0] == PPP_ALLSTATIONS) && (p[1] == PPP_UI))
1033 {
1034 /* chop off address/control */
1035 if(skb->len < 3)
1036 goto err_exit;
1037 p = skb_pull(skb, 2);
1038 }
1039
1040 /* decompress protocol field if compressed */
1041 if(p[0] & 1)
1042 {
1043 /* protocol is compressed */
1044 skb_push(skb, 1)[0] = 0;
1045 }
1046 else
1047 if(skb->len < 2)
1048 goto err_exit;
1049
1050 /* pass to generic ppp layer */
1051 /* Note : how do I know if ppp can accept or not the packet ? This is
1052 * essential if I want to manage flow control smoothly... */
1053 ppp_input(&ap->chan, skb);
1054
1055 DEXIT(IRDA_TCB_TRACE, "\n");
1056 return 0;
1057
1058 err_exit:
1059 DERROR(IRDA_CB_ERROR, "Packet too small, dropping...\n");
1060 kfree_skb(skb);
1061 ppp_input_error(&ap->chan, code);
1062 return 0; /* Don't return an error code, only for flow control... */
1063}
1064
1065/*------------------------------------------------------------------*/
1066/*
1067 * Function irnet_disconnect_indication (instance, sap, reason, skb)
1068 *
1069 * Connection has been closed. Chech reason to find out why
1070 *
1071 * Note : there are many cases where we come here :
1072 * o attempted to connect, timeout
1073 * o connected, link is broken, LAP has timeout
1074 * o connected, other side close the link
1075 * o connection request on the server not handled
1076 */
1077static void
1078irnet_disconnect_indication(void * instance,
1079 void * sap,
1080 LM_REASON reason,
1081 struct sk_buff *skb)
1082{
1083 irnet_socket * self = (irnet_socket *) instance;
1084 int test_open;
1085 int test_connect;
1086
1087 DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
1088 DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");
1089
1090 /* Don't care about it, but let's not leak it */
1091 if(skb)
1092 dev_kfree_skb(skb);
1093
1094 /* Prevent higher layer from accessing IrTTP */
1095 test_open = test_and_clear_bit(0, &self->ttp_open);
1096 /* Not connecting anymore...
1097 * (note : TSAP is open, so IAP callbacks are no longer pending...) */
1098 test_connect = test_and_clear_bit(0, &self->ttp_connect);
1099
1100 /* If both self->ttp_open and self->ttp_connect are NULL, it mean that we
1101 * have a race condition with irda_irnet_destroy() or
1102 * irnet_connect_indication(), so don't mess up tsap...
1103 */
1104 if(!(test_open || test_connect))
1105 {
1106 DERROR(IRDA_CB_ERROR, "Race condition detected...\n");
1107 return;
1108 }
1109
1110 /* If we were active, notify the control channel */
1111 if(test_open)
1112 irnet_post_event(self, IRNET_DISCONNECT_FROM,
1113 self->saddr, self->daddr, self->rname, 0);
1114 else
1115 /* If we were trying to connect, notify the control channel */
1116 if((self->tsap) && (self != &irnet_server.s))
1117 irnet_post_event(self, IRNET_NOANSWER_FROM,
1118 self->saddr, self->daddr, self->rname, 0);
1119
1120 /* Close our IrTTP connection, cleanup tsap */
1121 if((self->tsap) && (self != &irnet_server.s))
1122 {
1123 DEBUG(IRDA_CB_INFO, "Closing our TTP connection.\n");
1124 irttp_close_tsap(self->tsap);
1125 self->tsap = NULL;
1126 }
1127 /* Cleanup the socket in case we want to reconnect in ppp_output_wakeup() */
1128 self->stsap_sel = 0;
1129 self->daddr = DEV_ADDR_ANY;
1130 self->tx_flow = FLOW_START;
1131
1132 /* Deal with the ppp instance if it's still alive */
1133 if(self->ppp_open)
1134 {
1135 if(test_open)
1136 {
1137#ifdef MISSING_PPP_API
1138 /* ppp_unregister_channel() wants a user context, which we
1139 * are guaranteed to NOT have here. What are we supposed
1140 * to do here ? Jean II */
1141 /* If we were connected, cleanup & close the PPP channel,
1142 * which will kill pppd (hangup) and the rest */
1143 ppp_unregister_channel(&self->chan);
1144 self->ppp_open = 0;
1145#endif
1146 }
1147 else
1148 {
1149 /* If we were trying to connect, flush (drain) ppp_generic
1150 * Tx queue (most often we have blocked it), which will
1151 * trigger an other attempt to connect. If we are passive,
1152 * this will empty the Tx queue after last try. */
1153 ppp_output_wakeup(&self->chan);
1154 }
1155 }
1156
1157 DEXIT(IRDA_TCB_TRACE, "\n");
1158}
1159
1160/*------------------------------------------------------------------*/
1161/*
1162 * Function irnet_connect_confirm (instance, sap, qos, max_sdu_size, skb)
1163 *
1164 * Connections has been confirmed by the remote device
1165 *
1166 */
1167static void
1168irnet_connect_confirm(void * instance,
1169 void * sap,
1170 struct qos_info *qos,
1171 __u32 max_sdu_size,
1172 __u8 max_header_size,
1173 struct sk_buff *skb)
1174{
1175 irnet_socket * self = (irnet_socket *) instance;
1176
1177 DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
1178
1179 /* Check if socket is closing down (via irda_irnet_destroy()) */
1180 if(! test_bit(0, &self->ttp_connect))
1181 {
1182 DERROR(IRDA_CB_ERROR, "Socket no longer connecting. Ouch !\n");
1183 return;
1184 }
1185
1186 /* How much header space do we need to reserve */
1187 self->max_header_size = max_header_size;
1188
1189 /* IrTTP max SDU size in transmit direction */
1190 self->max_sdu_size_tx = max_sdu_size;
1191 self->max_data_size = max_sdu_size;
1192#ifdef STREAM_COMPAT
1193 if(max_sdu_size == 0)
1194 self->max_data_size = irttp_get_max_seg_size(self->tsap);
1195#endif /* STREAM_COMPAT */
1196
1197 /* At this point, IrLMP has assigned our source address */
1198 self->saddr = irttp_get_saddr(self->tsap);
1199
1200 /* Allow higher layer to access IrTTP */
1201 set_bit(0, &self->ttp_open);
1202 clear_bit(0, &self->ttp_connect); /* Not racy, IrDA traffic is serial */
1203 /* Give a kick in the ass of ppp_generic so that he sends us some data */
1204 ppp_output_wakeup(&self->chan);
1205
1206 /* Check size of received packet */
1207 if(skb->len > 0)
1208 {
1209#ifdef PASS_CONNECT_PACKETS
1210 DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.\n");
1211 /* Try to pass it to PPP */
1212 irnet_data_indication(instance, sap, skb);
1213#else /* PASS_CONNECT_PACKETS */
1214 DERROR(IRDA_CB_ERROR, "Dropping non empty packet.\n");
1215 kfree_skb(skb); /* Note : will be optimised with other kfree... */
1216#endif /* PASS_CONNECT_PACKETS */
1217 }
1218 else
1219 kfree_skb(skb);
1220
1221 /* Notify the control channel */
1222 irnet_post_event(self, IRNET_CONNECT_TO,
1223 self->saddr, self->daddr, self->rname, 0);
1224
1225 DEXIT(IRDA_TCB_TRACE, "\n");
1226}
1227
1228/*------------------------------------------------------------------*/
1229/*
1230 * Function irnet_flow_indication (instance, sap, flow)
1231 *
1232 * Used by TinyTP to tell us if it can accept more data or not
1233 *
1234 */
1235static void
1236irnet_flow_indication(void * instance,
1237 void * sap,
1238 LOCAL_FLOW flow)
1239{
1240 irnet_socket * self = (irnet_socket *) instance;
1241 LOCAL_FLOW oldflow = self->tx_flow;
1242
1243 DENTER(IRDA_TCB_TRACE, "(self=0x%p, flow=%d)\n", self, flow);
1244
1245 /* Update our state */
1246 self->tx_flow = flow;
1247
1248 /* Check what IrTTP want us to do... */
1249 switch(flow)
1250 {
1251 case FLOW_START:
1252 DEBUG(IRDA_CB_INFO, "IrTTP wants us to start again\n");
1253 /* Check if we really need to wake up PPP */
1254 if(oldflow == FLOW_STOP)
1255 ppp_output_wakeup(&self->chan);
1256 else
1257 DEBUG(IRDA_CB_INFO, "But we were already transmitting !!!\n");
1258 break;
1259 case FLOW_STOP:
1260 DEBUG(IRDA_CB_INFO, "IrTTP wants us to slow down\n");
1261 break;
1262 default:
1263 DEBUG(IRDA_CB_INFO, "Unknown flow command!\n");
1264 break;
1265 }
1266
1267 DEXIT(IRDA_TCB_TRACE, "\n");
1268}
1269
1270/*------------------------------------------------------------------*/
1271/*
1272 * Function irnet_status_indication (instance, sap, reason, skb)
1273 *
1274 * Link (IrLAP) status report.
1275 *
1276 */
1277static void
1278irnet_status_indication(void * instance,
1279 LINK_STATUS link,
1280 LOCK_STATUS lock)
1281{
1282 irnet_socket * self = (irnet_socket *) instance;
1283
1284 DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
1285 DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");
1286
1287 /* We can only get this event if we are connected */
1288 switch(link)
1289 {
1290 case STATUS_NO_ACTIVITY:
1291 irnet_post_event(self, IRNET_BLOCKED_LINK,
1292 self->saddr, self->daddr, self->rname, 0);
1293 break;
1294 default:
1295 DEBUG(IRDA_CB_INFO, "Unknown status...\n");
1296 }
1297
1298 DEXIT(IRDA_TCB_TRACE, "\n");
1299}
1300
1301/*------------------------------------------------------------------*/
1302/*
1303 * Function irnet_connect_indication(instance, sap, qos, max_sdu_size, userdata)
1304 *
1305 * Incoming connection
1306 *
1307 * In theory, this function is called only on the server socket.
1308 * Some other node is attempting to connect to the IrNET service, and has
1309 * sent a connection request on our server socket.
1310 * We just redirect the connection to the relevant IrNET socket.
1311 *
1312 * Note : we also make sure that between 2 irnet nodes, there can
1313 * exist only one irnet connection.
1314 */
1315static void
1316irnet_connect_indication(void * instance,
1317 void * sap,
1318 struct qos_info *qos,
1319 __u32 max_sdu_size,
1320 __u8 max_header_size,
1321 struct sk_buff *skb)
1322{
1323 irnet_socket * server = &irnet_server.s;
1324 irnet_socket * new = (irnet_socket *) NULL;
1325
1326 DENTER(IRDA_TCB_TRACE, "(server=0x%p)\n", server);
1327 DASSERT(instance == &irnet_server, , IRDA_CB_ERROR,
1328 "Invalid instance (0x%p) !!!\n", instance);
1329 DASSERT(sap == irnet_server.s.tsap, , IRDA_CB_ERROR, "Invalid sap !!!\n");
1330
1331 /* Try to find the most appropriate IrNET socket */
1332 new = irnet_find_socket(server);
1333
1334 /* After all this hard work, do we have an socket ? */
1335 if(new == (irnet_socket *) NULL)
1336 {
1337 DEXIT(IRDA_CB_INFO, ": No socket waiting for this connection.\n");
1338 irnet_disconnect_server(server, skb);
1339 return;
1340 }
1341
1342 /* Is the socket already busy ? */
1343 if(test_bit(0, &new->ttp_open))
1344 {
1345 DEXIT(IRDA_CB_INFO, ": Socket already connected.\n");
1346 irnet_disconnect_server(server, skb);
1347 return;
1348 }
1349
1350 /* The following code is a bit tricky, so need comments ;-)
1351 */
1352 /* If ttp_connect is set, the socket is trying to connect to the other
1353 * end and may have sent a IrTTP connection request and is waiting for
1354 * a connection response (that may never come).
1355 * Now, the pain is that the socket may have opened a tsap and is
1356 * waiting on it, while the other end is trying to connect to it on
1357 * another tsap.
1358 * Because IrNET can be peer to peer, we need to workaround this.
1359 * Furthermore, the way the irnetd script is implemented, the
1360 * target will create a second IrNET connection back to the
1361 * originator and expect the originator to bind this new connection
1362 * to the original PPPD instance.
1363 * And of course, if we don't use irnetd, we can have a race when
1364 * both side try to connect simultaneously, which could leave both
1365 * connections half closed (yuck).
1366 * Conclusions :
1367 * 1) The "originator" must accept the new connection and get rid
1368 * of the old one so that irnetd works
1369 * 2) One side must deny the new connection to avoid races,
1370 * but both side must agree on which side it is...
1371 * Most often, the originator is primary at the LAP layer.
1372 * Jean II
1373 */
1374 /* Now, let's look at the way I wrote the test...
1375 * We need to clear up the ttp_connect flag atomically to prevent
1376 * irnet_disconnect_indication() to mess up the tsap we are going to close.
1377 * We want to clear the ttp_connect flag only if we close the tsap,
1378 * otherwise we will never close it, so we need to check for primary
1379 * *before* doing the test on the flag.
1380 * And of course, ALLOW_SIMULT_CONNECT can disable this entirely...
1381 * Jean II
1382 */
1383
1384 /* Socket already connecting ? On primary ? */
1385 if(0
1386#ifdef ALLOW_SIMULT_CONNECT
1387 || ((irttp_is_primary(server->tsap) == 1) /* primary */
1388 && (test_and_clear_bit(0, &new->ttp_connect)))
1389#endif /* ALLOW_SIMULT_CONNECT */
1390 )
1391 {
1392 DERROR(IRDA_CB_ERROR, "Socket already connecting, but going to reuse it !\n");
1393
1394 /* Cleanup the old TSAP if necessary - IrIAP will be cleaned up later */
1395 if(new->tsap != NULL)
1396 {
1397 /* Close the old connection the new socket was attempting,
1398 * so that we can hook it up to the new connection.
1399 * It's now safe to do it... */
1400 irttp_close_tsap(new->tsap);
1401 new->tsap = NULL;
1402 }
1403 }
1404 else
1405 {
1406 /* Three options :
1407 * 1) socket was not connecting or connected : ttp_connect should be 0.
1408 * 2) we don't want to connect the socket because we are secondary or
1409 * ALLOW_SIMULT_CONNECT is undefined. ttp_connect should be 1.
1410 * 3) we are half way in irnet_disconnect_indication(), and it's a
1411 * nice race condition... Fortunately, we can detect that by checking
1412 * if tsap is still alive. On the other hand, we can't be in
1413 * irda_irnet_destroy() otherwise we would not have found this
1414 * socket in the hashbin.
1415 * Jean II */
1416 if((test_bit(0, &new->ttp_connect)) || (new->tsap != NULL))
1417 {
1418 /* Don't mess this socket, somebody else in in charge... */
1419 DERROR(IRDA_CB_ERROR, "Race condition detected, socket in use, abort connect...\n");
1420 irnet_disconnect_server(server, skb);
1421 return;
1422 }
1423 }
1424
1425 /* So : at this point, we have a socket, and it is idle. Good ! */
1426 irnet_connect_socket(server, new, qos, max_sdu_size, max_header_size);
1427
1428 /* Check size of received packet */
1429 if(skb->len > 0)
1430 {
1431#ifdef PASS_CONNECT_PACKETS
1432 DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.\n");
1433 /* Try to pass it to PPP */
1434 irnet_data_indication(new, new->tsap, skb);
1435#else /* PASS_CONNECT_PACKETS */
1436 DERROR(IRDA_CB_ERROR, "Dropping non empty packet.\n");
1437 kfree_skb(skb); /* Note : will be optimised with other kfree... */
1438#endif /* PASS_CONNECT_PACKETS */
1439 }
1440 else
1441 kfree_skb(skb);
1442
1443 DEXIT(IRDA_TCB_TRACE, "\n");
1444}
1445
1446
1447/********************** IRDA-IAS/LMP CALLBACKS **********************/
1448/*
1449 * These are the callbacks called by other layers of the IrDA stack,
1450 * mainly LMP for discovery and IAS for name queries.
1451 */
1452
1453/*------------------------------------------------------------------*/
1454/*
1455 * Function irnet_getvalue_confirm (result, obj_id, value, priv)
1456 *
1457 * Got answer from remote LM-IAS, just connect
1458 *
1459 * This is the reply to a IAS query we were doing to find the TSAP of
1460 * the device we want to connect to.
1461 * If we have found a valid TSAP, just initiate the TTP connection
1462 * on this TSAP.
1463 */
1464static void
1465irnet_getvalue_confirm(int result,
1466 __u16 obj_id,
1467 struct ias_value *value,
1468 void * priv)
1469{
1470 irnet_socket * self = (irnet_socket *) priv;
1471
1472 DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1473 DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");
1474
1475 /* Check if already connected (via irnet_connect_socket())
1476 * or socket is closing down (via irda_irnet_destroy()) */
1477 if(! test_bit(0, &self->ttp_connect))
1478 {
1479 DERROR(IRDA_OCB_ERROR, "Socket no longer connecting. Ouch !\n");
1480 return;
1481 }
1482
1483 /* We probably don't need to make any more queries */
1484 iriap_close(self->iriap);
1485 self->iriap = NULL;
1486
1487 /* Post process the IAS reply */
1488 self->dtsap_sel = irnet_ias_to_tsap(self, result, value);
1489
1490 /* If error, just go out */
1491 if(self->errno)
1492 {
1493 clear_bit(0, &self->ttp_connect);
1494 DERROR(IRDA_OCB_ERROR, "IAS connect failed ! (0x%X)\n", self->errno);
1495 return;
1496 }
1497
1498 DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n",
1499 self->daddr, self->dtsap_sel);
1500
1501 /* Start up TTP - non blocking */
1502 irnet_connect_tsap(self);
1503
1504 DEXIT(IRDA_OCB_TRACE, "\n");
1505}
1506
1507/*------------------------------------------------------------------*/
1508/*
1509 * Function irnet_discovervalue_confirm (result, obj_id, value, priv)
1510 *
1511 * Handle the TSAP discovery procedure state machine.
1512 * Got answer from remote LM-IAS, try next device
1513 *
1514 * We are doing a TSAP discovery procedure, and we got an answer to
1515 * a IAS query we were doing to find the TSAP on one of the address
1516 * in the discovery log.
1517 *
1518 * If we have found a valid TSAP for the first time, save it. If it's
1519 * not the first time we found one, complain.
1520 *
1521 * If we have more addresses in the log, just initiate a new query.
1522 * Note that those query may fail (see irnet_discover_daddr_and_lsap_sel())
1523 *
1524 * Otherwise, wrap up the procedure (cleanup), check if we have found
1525 * any device and connect to it.
1526 */
1527static void
1528irnet_discovervalue_confirm(int result,
1529 __u16 obj_id,
1530 struct ias_value *value,
1531 void * priv)
1532{
1533 irnet_socket * self = (irnet_socket *) priv;
1534 __u8 dtsap_sel; /* TSAP we are looking for */
1535
1536 DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1537 DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");
1538
1539 /* Check if already connected (via irnet_connect_socket())
1540 * or socket is closing down (via irda_irnet_destroy()) */
1541 if(! test_bit(0, &self->ttp_connect))
1542 {
1543 DERROR(IRDA_OCB_ERROR, "Socket no longer connecting. Ouch !\n");
1544 return;
1545 }
1546
1547 /* Post process the IAS reply */
1548 dtsap_sel = irnet_ias_to_tsap(self, result, value);
1549
1550 /* Have we got something ? */
1551 if(self->errno == 0)
1552 {
1553 /* We found the requested service */
1554 if(self->daddr != DEV_ADDR_ANY)
1555 {
1556 DERROR(IRDA_OCB_ERROR, "More than one device in range supports IrNET...\n");
1557 }
1558 else
1559 {
1560 /* First time we found that one, save it ! */
1561 self->daddr = self->discoveries[self->disco_index].daddr;
1562 self->dtsap_sel = dtsap_sel;
1563 }
1564 }
1565
1566 /* If no failure */
1567 if((self->errno == -EADDRNOTAVAIL) || (self->errno == 0))
1568 {
1569 int ret;
1570
1571 /* Search the next node */
1572 ret = irnet_discover_next_daddr(self);
1573 if(!ret)
1574 {
1575 /* In this case, the above request was non-blocking.
1576 * We will return here after a while... */
1577 return;
1578 }
1579 /* In this case, we have processed the last discovery item */
1580 }
1581
1582 /* No more queries to be done (failure or last one) */
1583
1584 /* We probably don't need to make any more queries */
1585 iriap_close(self->iriap);
1586 self->iriap = NULL;
1587
1588 /* No more items : remove the log and signal termination */
1589 DEBUG(IRDA_OCB_INFO, "Cleaning up log (0x%p)\n",
1590 self->discoveries);
1591 if(self->discoveries != NULL)
1592 {
1593 /* Cleanup our copy of the discovery log */
1594 kfree(self->discoveries);
1595 self->discoveries = NULL;
1596 }
1597 self->disco_number = -1;
1598
1599 /* Check out what we found */
1600 if(self->daddr == DEV_ADDR_ANY)
1601 {
1602 self->daddr = DEV_ADDR_ANY;
1603 clear_bit(0, &self->ttp_connect);
1604 DEXIT(IRDA_OCB_TRACE, ": cannot discover IrNET in any device !!!\n");
1605 return;
1606 }
1607
1608 /* We have a valid address - just connect */
1609
1610 DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n",
1611 self->daddr, self->dtsap_sel);
1612
1613 /* Start up TTP - non blocking */
1614 irnet_connect_tsap(self);
1615
1616 DEXIT(IRDA_OCB_TRACE, "\n");
1617}
1618
1619#ifdef DISCOVERY_EVENTS
1620/*------------------------------------------------------------------*/
1621/*
1622 * Function irnet_discovery_indication (discovery)
1623 *
1624 * Got a discovery indication from IrLMP, post an event
1625 *
1626 * Note : IrLMP take care of matching the hint mask for us, and also
1627 * check if it is a "new" node for us...
1628 *
1629 * As IrLMP filter on the IrLAN hint bit, we get both IrLAN and IrNET
1630 * nodes, so it's only at connection time that we will know if the
1631 * node support IrNET, IrLAN or both. The other solution is to check
1632 * in IAS the PNP ids and service name.
1633 * Note : even if a node support IrNET (or IrLAN), it's no guarantee
1634 * that we will be able to connect to it, the node might already be
1635 * busy...
1636 *
1637 * One last thing : in some case, this function will trigger duplicate
1638 * discovery events. On the other hand, we should catch all
1639 * discoveries properly (i.e. not miss one). Filtering duplicate here
1640 * is to messy, so we leave that to user space...
1641 */
1642static void
1643irnet_discovery_indication(discinfo_t * discovery,
1644 DISCOVERY_MODE mode,
1645 void * priv)
1646{
1647 irnet_socket * self = &irnet_server.s;
1648
1649 DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1650 DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
1651 "Invalid instance (0x%p) !!!\n", priv);
1652
1653 DEBUG(IRDA_OCB_INFO, "Discovered new IrNET/IrLAN node %s...\n",
1654 discovery->info);
1655
1656 /* Notify the control channel */
1657 irnet_post_event(NULL, IRNET_DISCOVER,
1658 discovery->saddr, discovery->daddr, discovery->info,
1659 u16ho(discovery->hints));
1660
1661 DEXIT(IRDA_OCB_TRACE, "\n");
1662}
1663
1664/*------------------------------------------------------------------*/
1665/*
1666 * Function irnet_expiry_indication (expiry)
1667 *
1668 * Got a expiry indication from IrLMP, post an event
1669 *
1670 * Note : IrLMP take care of matching the hint mask for us, we only
1671 * check if it is a "new" node...
1672 */
1673static void
1674irnet_expiry_indication(discinfo_t * expiry,
1675 DISCOVERY_MODE mode,
1676 void * priv)
1677{
1678 irnet_socket * self = &irnet_server.s;
1679
1680 DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1681 DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
1682 "Invalid instance (0x%p) !!!\n", priv);
1683
1684 DEBUG(IRDA_OCB_INFO, "IrNET/IrLAN node %s expired...\n",
1685 expiry->info);
1686
1687 /* Notify the control channel */
1688 irnet_post_event(NULL, IRNET_EXPIRE,
1689 expiry->saddr, expiry->daddr, expiry->info,
1690 u16ho(expiry->hints));
1691
1692 DEXIT(IRDA_OCB_TRACE, "\n");
1693}
1694#endif /* DISCOVERY_EVENTS */
1695
1696
1697/*********************** PROC ENTRY CALLBACKS ***********************/
1698/*
1699 * We create a instance in the /proc filesystem, and here we take care
1700 * of that...
1701 */
1702
1703#ifdef CONFIG_PROC_FS
1704/*------------------------------------------------------------------*/
1705/*
1706 * Function irnet_proc_read (buf, start, offset, len, unused)
1707 *
1708 * Give some info to the /proc file system
1709 */
1710static int
1711irnet_proc_read(char * buf,
1712 char ** start,
1713 off_t offset,
1714 int len)
1715{
1716 irnet_socket * self;
1717 char * state;
1718 int i = 0;
1719
1720 len = 0;
1721
1722 /* Get the IrNET server information... */
1723 len += sprintf(buf+len, "IrNET server - ");
1724 len += sprintf(buf+len, "IrDA state: %s, ",
1725 (irnet_server.running ? "running" : "dead"));
1726 len += sprintf(buf+len, "stsap_sel: %02x, ", irnet_server.s.stsap_sel);
1727 len += sprintf(buf+len, "dtsap_sel: %02x\n", irnet_server.s.dtsap_sel);
1728
1729 /* Do we need to continue ? */
1730 if(!irnet_server.running)
1731 return len;
1732
1733 /* Protect access to the instance list */
1734 spin_lock_bh(&irnet_server.spinlock);
1735
1736 /* Get the sockets one by one... */
1737 self = (irnet_socket *) hashbin_get_first(irnet_server.list);
1738 while(self != NULL)
1739 {
1740 /* Start printing info about the socket. */
1741 len += sprintf(buf+len, "\nIrNET socket %d - ", i++);
1742
1743 /* First, get the requested configuration */
1744 len += sprintf(buf+len, "Requested IrDA name: \"%s\", ", self->rname);
1745 len += sprintf(buf+len, "daddr: %08x, ", self->rdaddr);
1746 len += sprintf(buf+len, "saddr: %08x\n", self->rsaddr);
1747
1748 /* Second, get all the PPP info */
1749 len += sprintf(buf+len, " PPP state: %s",
1750 (self->ppp_open ? "registered" : "unregistered"));
1751 if(self->ppp_open)
1752 {
1753 len += sprintf(buf+len, ", unit: ppp%d",
1754 ppp_unit_number(&self->chan));
1755 len += sprintf(buf+len, ", channel: %d",
1756 ppp_channel_index(&self->chan));
1757 len += sprintf(buf+len, ", mru: %d",
1758 self->mru);
1759 /* Maybe add self->flags ? Later... */
1760 }
1761
1762 /* Then, get all the IrDA specific info... */
1763 if(self->ttp_open)
1764 state = "connected";
1765 else
1766 if(self->tsap != NULL)
1767 state = "connecting";
1768 else
1769 if(self->iriap != NULL)
1770 state = "searching";
1771 else
1772 if(self->ttp_connect)
1773 state = "weird";
1774 else
1775 state = "idle";
1776 len += sprintf(buf+len, "\n IrDA state: %s, ", state);
1777 len += sprintf(buf+len, "daddr: %08x, ", self->daddr);
1778 len += sprintf(buf+len, "stsap_sel: %02x, ", self->stsap_sel);
1779 len += sprintf(buf+len, "dtsap_sel: %02x\n", self->dtsap_sel);
1780
1781 /* Next socket, please... */
1782 self = (irnet_socket *) hashbin_get_next(irnet_server.list);
1783 }
1784
1785 /* Spin lock end */
1786 spin_unlock_bh(&irnet_server.spinlock);
1787
1788 return len;
1789}
1790#endif /* PROC_FS */
1791
1792
1793/********************** CONFIGURATION/CLEANUP **********************/
1794/*
1795 * Initialisation and teardown of the IrDA part, called at module
1796 * insertion and removal...
1797 */
1798
1799/*------------------------------------------------------------------*/
1800/*
1801 * Prepare the IrNET layer for operation...
1802 */
1803int __init
1804irda_irnet_init(void)
1805{
1806 int err = 0;
1807
1808 DENTER(MODULE_TRACE, "()\n");
1809
1810 /* Pure paranoia - should be redundant */
1811 memset(&irnet_server, 0, sizeof(struct irnet_root));
1812
1813 /* Setup start of irnet instance list */
1814 irnet_server.list = hashbin_new(HB_NOLOCK);
1815 DABORT(irnet_server.list == NULL, -ENOMEM,
1816 MODULE_ERROR, "Can't allocate hashbin!\n");
1817 /* Init spinlock for instance list */
1818 spin_lock_init(&irnet_server.spinlock);
1819
1820 /* Initialise control channel */
1821 init_waitqueue_head(&irnet_events.rwait);
1822 irnet_events.index = 0;
1823 /* Init spinlock for event logging */
1824 spin_lock_init(&irnet_events.spinlock);
1825
1826#ifdef CONFIG_PROC_FS
1827 /* Add a /proc file for irnet infos */
1828 create_proc_info_entry("irnet", 0, proc_irda, irnet_proc_read);
1829#endif /* CONFIG_PROC_FS */
1830
1831 /* Setup the IrNET server */
1832 err = irnet_setup_server();
1833
1834 if(!err)
1835 /* We are no longer functional... */
1836 irnet_server.running = 1;
1837
1838 DEXIT(MODULE_TRACE, "\n");
1839 return err;
1840}
1841
1842/*------------------------------------------------------------------*/
1843/*
1844 * Cleanup at exit...
1845 */
1846void __exit
1847irda_irnet_cleanup(void)
1848{
1849 DENTER(MODULE_TRACE, "()\n");
1850
1851 /* We are no longer there... */
1852 irnet_server.running = 0;
1853
1854#ifdef CONFIG_PROC_FS
1855 /* Remove our /proc file */
1856 remove_proc_entry("irnet", proc_irda);
1857#endif /* CONFIG_PROC_FS */
1858
1859 /* Remove our IrNET server from existence */
1860 irnet_destroy_server();
1861
1862 /* Remove all instances of IrNET socket still present */
1863 hashbin_delete(irnet_server.list, (FREE_FUNC) irda_irnet_destroy);
1864
1865 DEXIT(MODULE_TRACE, "\n");
1866}
diff --git a/net/irda/irnet/irnet_irda.h b/net/irda/irnet/irnet_irda.h
new file mode 100644
index 00000000000..f2fecd32d8f
--- /dev/null
+++ b/net/irda/irnet/irnet_irda.h
@@ -0,0 +1,186 @@
1/*
2 * IrNET protocol module : Synchronous PPP over an IrDA socket.
3 *
4 * Jean II - HPL `00 - <jt@hpl.hp.com>
5 *
6 * This file contains all definitions and declarations necessary for the
7 * IRDA part of the IrNET module (dealing with IrTTP, IrIAS and co).
8 * This file is a private header, so other modules don't want to know
9 * what's in there...
10 */
11
12#ifndef IRNET_IRDA_H
13#define IRNET_IRDA_H
14
15/***************************** INCLUDES *****************************/
16/* Please add other headers in irnet.h */
17
18#include "irnet.h" /* Module global include */
19
20/************************ CONSTANTS & MACROS ************************/
21
22/*
23 * Name of the service (socket name) used by IrNET
24 */
25/* IAS object name (or part of it) */
26#define IRNET_SERVICE_NAME "IrNetv1"
27/* IAS attribute */
28#define IRNET_IAS_VALUE "IrDA:TinyTP:LsapSel"
29/* LMP notify name for client (only for /proc/net/irda/irlmp) */
30#define IRNET_NOTIFY_NAME "IrNET socket"
31/* LMP notify name for server (only for /proc/net/irda/irlmp) */
32#define IRNET_NOTIFY_NAME_SERV "IrNET server"
33
34/****************************** TYPES ******************************/
35
36/*
37 * This is the main structure where we store all the data pertaining to
38 * the IrNET server (listen for connection requests) and the root
39 * of the IrNET socket list
40 */
41typedef struct irnet_root
42{
43 irnet_socket s; /* To pretend we are a client... */
44
45 /* Generic stuff */
46 int magic; /* Paranoia */
47 int running; /* Are we operational ? */
48
49 /* Link list of all IrNET instances opened */
50 hashbin_t * list;
51 spinlock_t spinlock; /* Serialize access to the list */
52 /* Note : the way hashbin has been designed is absolutely not
53 * reentrant, beware... So, we blindly protect all with spinlock */
54
55 /* Handle for the hint bit advertised in IrLMP */
56 void * skey;
57
58 /* Server socket part */
59 struct ias_object * ias_obj; /* Our service name + lsap in IAS */
60
61} irnet_root;
62
63
64/**************************** PROTOTYPES ****************************/
65
66/* ----------------------- CONTROL CHANNEL ----------------------- */
67static void
68 irnet_post_event(irnet_socket *,
69 irnet_event,
70 __u32,
71 __u32,
72 char *,
73 __u16);
74/* ----------------------- IRDA SUBROUTINES ----------------------- */
75static inline int
76 irnet_open_tsap(irnet_socket *);
77static inline __u8
78 irnet_ias_to_tsap(irnet_socket *,
79 int,
80 struct ias_value *);
81static inline int
82 irnet_find_lsap_sel(irnet_socket *);
83static inline int
84 irnet_connect_tsap(irnet_socket *);
85static inline int
86 irnet_discover_next_daddr(irnet_socket *);
87static inline int
88 irnet_discover_daddr_and_lsap_sel(irnet_socket *);
89static inline int
90 irnet_dname_to_daddr(irnet_socket *);
91/* ------------------------ SERVER SOCKET ------------------------ */
92static inline int
93 irnet_daddr_to_dname(irnet_socket *);
94static inline irnet_socket *
95 irnet_find_socket(irnet_socket *);
96static inline int
97 irnet_connect_socket(irnet_socket *,
98 irnet_socket *,
99 struct qos_info *,
100 __u32,
101 __u8);
102static inline void
103 irnet_disconnect_server(irnet_socket *,
104 struct sk_buff *);
105static inline int
106 irnet_setup_server(void);
107static inline void
108 irnet_destroy_server(void);
109/* ---------------------- IRDA-TTP CALLBACKS ---------------------- */
110static int
111 irnet_data_indication(void *, /* instance */
112 void *, /* sap */
113 struct sk_buff *);
114static void
115 irnet_disconnect_indication(void *,
116 void *,
117 LM_REASON,
118 struct sk_buff *);
119static void
120 irnet_connect_confirm(void *,
121 void *,
122 struct qos_info *,
123 __u32,
124 __u8,
125 struct sk_buff *);
126static void
127 irnet_flow_indication(void *,
128 void *,
129 LOCAL_FLOW);
130static void
131 irnet_status_indication(void *,
132 LINK_STATUS,
133 LOCK_STATUS);
134static void
135 irnet_connect_indication(void *,
136 void *,
137 struct qos_info *,
138 __u32,
139 __u8,
140 struct sk_buff *);
141/* -------------------- IRDA-IAS/LMP CALLBACKS -------------------- */
142static void
143 irnet_getvalue_confirm(int,
144 __u16,
145 struct ias_value *,
146 void *);
147static void
148 irnet_discovervalue_confirm(int,
149 __u16,
150 struct ias_value *,
151 void *);
152#ifdef DISCOVERY_EVENTS
153static void
154 irnet_discovery_indication(discinfo_t *,
155 DISCOVERY_MODE,
156 void *);
157static void
158 irnet_expiry_indication(discinfo_t *,
159 DISCOVERY_MODE,
160 void *);
161#endif
162/* -------------------------- PROC ENTRY -------------------------- */
163#ifdef CONFIG_PROC_FS
164static int
165 irnet_proc_read(char *,
166 char **,
167 off_t,
168 int);
169#endif /* CONFIG_PROC_FS */
170
171/**************************** VARIABLES ****************************/
172
173/*
174 * The IrNET server. Listen to connection requests and co...
175 */
176static struct irnet_root irnet_server;
177
178/* Control channel stuff (note : extern) */
179struct irnet_ctrl_channel irnet_events;
180
181/* The /proc/net/irda directory, defined elsewhere... */
182#ifdef CONFIG_PROC_FS
183extern struct proc_dir_entry *proc_irda;
184#endif /* CONFIG_PROC_FS */
185
186#endif /* IRNET_IRDA_H */
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c
new file mode 100644
index 00000000000..f8f984bb992
--- /dev/null
+++ b/net/irda/irnet/irnet_ppp.c
@@ -0,0 +1,1142 @@
1/*
2 * IrNET protocol module : Synchronous PPP over an IrDA socket.
3 *
4 * Jean II - HPL `00 - <jt@hpl.hp.com>
5 *
6 * This file implement the PPP interface and /dev/irnet character device.
7 * The PPP interface hook to the ppp_generic module, handle all our
8 * relationship to the PPP code in the kernel (and by extension to pppd),
9 * and exchange PPP frames with this module (send/receive).
10 * The /dev/irnet device is used primarily for 2 functions :
11 * 1) as a stub for pppd (the ppp daemon), so that we can appropriately
12 * generate PPP sessions (we pretend we are a tty).
13 * 2) as a control channel (write commands, read events)
14 */
15
16#include "irnet_ppp.h" /* Private header */
17/* Please put other headers in irnet.h - Thanks */
18
19/* Generic PPP callbacks (to call us) */
20static struct ppp_channel_ops irnet_ppp_ops = {
21 .start_xmit = ppp_irnet_send,
22 .ioctl = ppp_irnet_ioctl
23};
24
25/************************* CONTROL CHANNEL *************************/
26/*
27 * When a pppd instance is not active on /dev/irnet, it acts as a control
28 * channel.
29 * Writing allow to set up the IrDA destination of the IrNET channel,
30 * and any application may be read events happening in IrNET...
31 */
32
33/*------------------------------------------------------------------*/
34/*
35 * Write is used to send a command to configure a IrNET channel
36 * before it is open by pppd. The syntax is : "command argument"
37 * Currently there is only two defined commands :
38 * o name : set the requested IrDA nickname of the IrNET peer.
39 * o addr : set the requested IrDA address of the IrNET peer.
40 * Note : the code is crude, but effective...
41 */
42static inline ssize_t
43irnet_ctrl_write(irnet_socket * ap,
44 const char __user *buf,
45 size_t count)
46{
47 char command[IRNET_MAX_COMMAND];
48 char * start; /* Current command being processed */
49 char * next; /* Next command to process */
50 int length; /* Length of current command */
51
52 DENTER(CTRL_TRACE, "(ap=0x%p, count=%Zd)\n", ap, count);
53
54 /* Check for overflow... */
55 DABORT(count >= IRNET_MAX_COMMAND, -ENOMEM,
56 CTRL_ERROR, "Too much data !!!\n");
57
58 /* Get the data in the driver */
59 if(copy_from_user(command, buf, count))
60 {
61 DERROR(CTRL_ERROR, "Invalid user space pointer.\n");
62 return -EFAULT;
63 }
64
65 /* Safe terminate the string */
66 command[count] = '\0';
67 DEBUG(CTRL_INFO, "Command line received is ``%s'' (%Zd).\n",
68 command, count);
69
70 /* Check every commands in the command line */
71 next = command;
72 while(next != NULL)
73 {
74 /* Look at the next command */
75 start = next;
76
77 /* Scrap whitespaces before the command */
78 while(isspace(*start))
79 start++;
80
81 /* ',' is our command separator */
82 next = strchr(start, ',');
83 if(next)
84 {
85 *next = '\0'; /* Terminate command */
86 length = next - start; /* Length */
87 next++; /* Skip the '\0' */
88 }
89 else
90 length = strlen(start);
91
92 DEBUG(CTRL_INFO, "Found command ``%s'' (%d).\n", start, length);
93
94 /* Check if we recognised one of the known command
95 * We can't use "switch" with strings, so hack with "continue" */
96
97 /* First command : name -> Requested IrDA nickname */
98 if(!strncmp(start, "name", 4))
99 {
100 /* Copy the name only if is included and not "any" */
101 if((length > 5) && (strcmp(start + 5, "any")))
102 {
103 /* Strip out trailing whitespaces */
104 while(isspace(start[length - 1]))
105 length--;
106
107 /* Copy the name for later reuse */
108 memcpy(ap->rname, start + 5, length - 5);
109 ap->rname[length - 5] = '\0';
110 }
111 else
112 ap->rname[0] = '\0';
113 DEBUG(CTRL_INFO, "Got rname = ``%s''\n", ap->rname);
114
115 /* Restart the loop */
116 continue;
117 }
118
119 /* Second command : addr, daddr -> Requested IrDA destination address
120 * Also process : saddr -> Requested IrDA source address */
121 if((!strncmp(start, "addr", 4)) ||
122 (!strncmp(start, "daddr", 5)) ||
123 (!strncmp(start, "saddr", 5)))
124 {
125 __u32 addr = DEV_ADDR_ANY;
126
127 /* Copy the address only if is included and not "any" */
128 if((length > 5) && (strcmp(start + 5, "any")))
129 {
130 char * begp = start + 5;
131 char * endp;
132
133 /* Scrap whitespaces before the command */
134 while(isspace(*begp))
135 begp++;
136
137 /* Convert argument to a number (last arg is the base) */
138 addr = simple_strtoul(begp, &endp, 16);
139 /* Has it worked ? (endp should be start + length) */
140 DABORT(endp <= (start + 5), -EINVAL,
141 CTRL_ERROR, "Invalid address.\n");
142 }
143 /* Which type of address ? */
144 if(start[0] == 's')
145 {
146 /* Save it */
147 ap->rsaddr = addr;
148 DEBUG(CTRL_INFO, "Got rsaddr = %08x\n", ap->rsaddr);
149 }
150 else
151 {
152 /* Save it */
153 ap->rdaddr = addr;
154 DEBUG(CTRL_INFO, "Got rdaddr = %08x\n", ap->rdaddr);
155 }
156
157 /* Restart the loop */
158 continue;
159 }
160
161 /* Other possible command : connect N (number of retries) */
162
163 /* No command matched -> Failed... */
164 DABORT(1, -EINVAL, CTRL_ERROR, "Not a recognised IrNET command.\n");
165 }
166
167 /* Success : we have parsed all commands successfully */
168 return(count);
169}
170
171#ifdef INITIAL_DISCOVERY
172/*------------------------------------------------------------------*/
173/*
174 * Function irnet_get_discovery_log (self)
175 *
176 * Query the content on the discovery log if not done
177 *
178 * This function query the current content of the discovery log
179 * at the startup of the event channel and save it in the internal struct.
180 */
181static void
182irnet_get_discovery_log(irnet_socket * ap)
183{
184 __u16 mask = irlmp_service_to_hint(S_LAN);
185
186 /* Ask IrLMP for the current discovery log */
187 ap->discoveries = irlmp_get_discoveries(&ap->disco_number, mask,
188 DISCOVERY_DEFAULT_SLOTS);
189
190 /* Check if the we got some results */
191 if(ap->discoveries == NULL)
192 ap->disco_number = -1;
193
194 DEBUG(CTRL_INFO, "Got the log (0x%p), size is %d\n",
195 ap->discoveries, ap->disco_number);
196}
197
198/*------------------------------------------------------------------*/
199/*
200 * Function irnet_read_discovery_log (self, event)
201 *
202 * Read the content on the discovery log
203 *
204 * This function dump the current content of the discovery log
205 * at the startup of the event channel.
206 * Return 1 if wrote an event on the control channel...
207 *
208 * State of the ap->disco_XXX variables :
209 * Socket creation : discoveries = NULL ; disco_index = 0 ; disco_number = 0
210 * While reading : discoveries = ptr ; disco_index = X ; disco_number = Y
211 * After reading : discoveries = NULL ; disco_index = Y ; disco_number = -1
212 */
213static inline int
214irnet_read_discovery_log(irnet_socket * ap,
215 char * event)
216{
217 int done_event = 0;
218
219 DENTER(CTRL_TRACE, "(ap=0x%p, event=0x%p)\n",
220 ap, event);
221
222 /* Test if we have some work to do or we have already finished */
223 if(ap->disco_number == -1)
224 {
225 DEBUG(CTRL_INFO, "Already done\n");
226 return 0;
227 }
228
229 /* Test if it's the first time and therefore we need to get the log */
230 if(ap->discoveries == NULL)
231 irnet_get_discovery_log(ap);
232
233 /* Check if we have more item to dump */
234 if(ap->disco_index < ap->disco_number)
235 {
236 /* Write an event */
237 sprintf(event, "Found %08x (%s) behind %08x {hints %02X-%02X}\n",
238 ap->discoveries[ap->disco_index].daddr,
239 ap->discoveries[ap->disco_index].info,
240 ap->discoveries[ap->disco_index].saddr,
241 ap->discoveries[ap->disco_index].hints[0],
242 ap->discoveries[ap->disco_index].hints[1]);
243 DEBUG(CTRL_INFO, "Writing discovery %d : %s\n",
244 ap->disco_index, ap->discoveries[ap->disco_index].info);
245
246 /* We have an event */
247 done_event = 1;
248 /* Next discovery */
249 ap->disco_index++;
250 }
251
252 /* Check if we have done the last item */
253 if(ap->disco_index >= ap->disco_number)
254 {
255 /* No more items : remove the log and signal termination */
256 DEBUG(CTRL_INFO, "Cleaning up log (0x%p)\n",
257 ap->discoveries);
258 if(ap->discoveries != NULL)
259 {
260 /* Cleanup our copy of the discovery log */
261 kfree(ap->discoveries);
262 ap->discoveries = NULL;
263 }
264 ap->disco_number = -1;
265 }
266
267 return done_event;
268}
269#endif /* INITIAL_DISCOVERY */
270
271/*------------------------------------------------------------------*/
272/*
273 * Read is used to get IrNET events
274 */
275static inline ssize_t
276irnet_ctrl_read(irnet_socket * ap,
277 struct file * file,
278 char __user * buf,
279 size_t count)
280{
281 DECLARE_WAITQUEUE(wait, current);
282 char event[64]; /* Max event is 61 char */
283 ssize_t ret = 0;
284
285 DENTER(CTRL_TRACE, "(ap=0x%p, count=%Zd)\n", ap, count);
286
287 /* Check if we can write an event out in one go */
288 DABORT(count < sizeof(event), -EOVERFLOW, CTRL_ERROR, "Buffer to small.\n");
289
290#ifdef INITIAL_DISCOVERY
291 /* Check if we have read the log */
292 if(irnet_read_discovery_log(ap, event))
293 {
294 /* We have an event !!! Copy it to the user */
295 if(copy_to_user(buf, event, strlen(event)))
296 {
297 DERROR(CTRL_ERROR, "Invalid user space pointer.\n");
298 return -EFAULT;
299 }
300
301 DEXIT(CTRL_TRACE, "\n");
302 return(strlen(event));
303 }
304#endif /* INITIAL_DISCOVERY */
305
306 /* Put ourselves on the wait queue to be woken up */
307 add_wait_queue(&irnet_events.rwait, &wait);
308 current->state = TASK_INTERRUPTIBLE;
309 for(;;)
310 {
311 /* If there is unread events */
312 ret = 0;
313 if(ap->event_index != irnet_events.index)
314 break;
315 ret = -EAGAIN;
316 if(file->f_flags & O_NONBLOCK)
317 break;
318 ret = -ERESTARTSYS;
319 if(signal_pending(current))
320 break;
321 /* Yield and wait to be woken up */
322 schedule();
323 }
324 current->state = TASK_RUNNING;
325 remove_wait_queue(&irnet_events.rwait, &wait);
326
327 /* Did we got it ? */
328 if(ret != 0)
329 {
330 /* No, return the error code */
331 DEXIT(CTRL_TRACE, " - ret %Zd\n", ret);
332 return ret;
333 }
334
335 /* Which event is it ? */
336 switch(irnet_events.log[ap->event_index].event)
337 {
338 case IRNET_DISCOVER:
339 sprintf(event, "Discovered %08x (%s) behind %08x {hints %02X-%02X}\n",
340 irnet_events.log[ap->event_index].daddr,
341 irnet_events.log[ap->event_index].name,
342 irnet_events.log[ap->event_index].saddr,
343 irnet_events.log[ap->event_index].hints.byte[0],
344 irnet_events.log[ap->event_index].hints.byte[1]);
345 break;
346 case IRNET_EXPIRE:
347 sprintf(event, "Expired %08x (%s) behind %08x {hints %02X-%02X}\n",
348 irnet_events.log[ap->event_index].daddr,
349 irnet_events.log[ap->event_index].name,
350 irnet_events.log[ap->event_index].saddr,
351 irnet_events.log[ap->event_index].hints.byte[0],
352 irnet_events.log[ap->event_index].hints.byte[1]);
353 break;
354 case IRNET_CONNECT_TO:
355 sprintf(event, "Connected to %08x (%s) on ppp%d\n",
356 irnet_events.log[ap->event_index].daddr,
357 irnet_events.log[ap->event_index].name,
358 irnet_events.log[ap->event_index].unit);
359 break;
360 case IRNET_CONNECT_FROM:
361 sprintf(event, "Connection from %08x (%s) on ppp%d\n",
362 irnet_events.log[ap->event_index].daddr,
363 irnet_events.log[ap->event_index].name,
364 irnet_events.log[ap->event_index].unit);
365 break;
366 case IRNET_REQUEST_FROM:
367 sprintf(event, "Request from %08x (%s) behind %08x\n",
368 irnet_events.log[ap->event_index].daddr,
369 irnet_events.log[ap->event_index].name,
370 irnet_events.log[ap->event_index].saddr);
371 break;
372 case IRNET_NOANSWER_FROM:
373 sprintf(event, "No-answer from %08x (%s) on ppp%d\n",
374 irnet_events.log[ap->event_index].daddr,
375 irnet_events.log[ap->event_index].name,
376 irnet_events.log[ap->event_index].unit);
377 break;
378 case IRNET_BLOCKED_LINK:
379 sprintf(event, "Blocked link with %08x (%s) on ppp%d\n",
380 irnet_events.log[ap->event_index].daddr,
381 irnet_events.log[ap->event_index].name,
382 irnet_events.log[ap->event_index].unit);
383 break;
384 case IRNET_DISCONNECT_FROM:
385 sprintf(event, "Disconnection from %08x (%s) on ppp%d\n",
386 irnet_events.log[ap->event_index].daddr,
387 irnet_events.log[ap->event_index].name,
388 irnet_events.log[ap->event_index].unit);
389 break;
390 case IRNET_DISCONNECT_TO:
391 sprintf(event, "Disconnected to %08x (%s)\n",
392 irnet_events.log[ap->event_index].daddr,
393 irnet_events.log[ap->event_index].name);
394 break;
395 default:
396 sprintf(event, "Bug\n");
397 }
398 /* Increment our event index */
399 ap->event_index = (ap->event_index + 1) % IRNET_MAX_EVENTS;
400
401 DEBUG(CTRL_INFO, "Event is :%s", event);
402
403 /* Copy it to the user */
404 if(copy_to_user(buf, event, strlen(event)))
405 {
406 DERROR(CTRL_ERROR, "Invalid user space pointer.\n");
407 return -EFAULT;
408 }
409
410 DEXIT(CTRL_TRACE, "\n");
411 return(strlen(event));
412}
413
414/*------------------------------------------------------------------*/
415/*
416 * Poll : called when someone do a select on /dev/irnet.
417 * Just check if there are new events...
418 */
419static inline unsigned int
420irnet_ctrl_poll(irnet_socket * ap,
421 struct file * file,
422 poll_table * wait)
423{
424 unsigned int mask;
425
426 DENTER(CTRL_TRACE, "(ap=0x%p)\n", ap);
427
428 poll_wait(file, &irnet_events.rwait, wait);
429 mask = POLLOUT | POLLWRNORM;
430 /* If there is unread events */
431 if(ap->event_index != irnet_events.index)
432 mask |= POLLIN | POLLRDNORM;
433#ifdef INITIAL_DISCOVERY
434 if(ap->disco_number != -1)
435 {
436 /* Test if it's the first time and therefore we need to get the log */
437 if(ap->discoveries == NULL)
438 irnet_get_discovery_log(ap);
439 /* Recheck */
440 if(ap->disco_number != -1)
441 mask |= POLLIN | POLLRDNORM;
442 }
443#endif /* INITIAL_DISCOVERY */
444
445 DEXIT(CTRL_TRACE, " - mask=0x%X\n", mask);
446 return mask;
447}
448
449
450/*********************** FILESYSTEM CALLBACKS ***********************/
451/*
452 * Implement the usual open, read, write functions that will be called
453 * by the file system when some action is performed on /dev/irnet.
454 * Most of those actions will in fact be performed by "pppd" or
455 * the control channel, we just act as a redirector...
456 */
457
458/*------------------------------------------------------------------*/
459/*
460 * Open : when somebody open /dev/irnet
461 * We basically create a new instance of irnet and initialise it.
462 */
463static int
464dev_irnet_open(struct inode * inode,
465 struct file * file)
466{
467 struct irnet_socket * ap;
468 int err;
469
470 DENTER(FS_TRACE, "(file=0x%p)\n", file);
471
472#ifdef SECURE_DEVIRNET
473 /* This could (should?) be enforced by the permissions on /dev/irnet. */
474 if(!capable(CAP_NET_ADMIN))
475 return -EPERM;
476#endif /* SECURE_DEVIRNET */
477
478 /* Allocate a private structure for this IrNET instance */
479 ap = kmalloc(sizeof(*ap), GFP_KERNEL);
480 DABORT(ap == NULL, -ENOMEM, FS_ERROR, "Can't allocate struct irnet...\n");
481
482 /* initialize the irnet structure */
483 memset(ap, 0, sizeof(*ap));
484 ap->file = file;
485
486 /* PPP channel setup */
487 ap->ppp_open = 0;
488 ap->chan.private = ap;
489 ap->chan.ops = &irnet_ppp_ops;
490 ap->chan.mtu = (2048 - TTP_MAX_HEADER - 2 - PPP_HDRLEN);
491 ap->chan.hdrlen = 2 + TTP_MAX_HEADER; /* for A/C + Max IrDA hdr */
492 /* PPP parameters */
493 ap->mru = (2048 - TTP_MAX_HEADER - 2 - PPP_HDRLEN);
494 ap->xaccm[0] = ~0U;
495 ap->xaccm[3] = 0x60000000U;
496 ap->raccm = ~0U;
497
498 /* Setup the IrDA part... */
499 err = irda_irnet_create(ap);
500 if(err)
501 {
502 DERROR(FS_ERROR, "Can't setup IrDA link...\n");
503 kfree(ap);
504 return err;
505 }
506
507 /* For the control channel */
508 ap->event_index = irnet_events.index; /* Cancel all past events */
509
510 /* Put our stuff where we will be able to find it later */
511 file->private_data = ap;
512
513 DEXIT(FS_TRACE, " - ap=0x%p\n", ap);
514 return 0;
515}
516
517
518/*------------------------------------------------------------------*/
519/*
520 * Close : when somebody close /dev/irnet
521 * Destroy the instance of /dev/irnet
522 */
523static int
524dev_irnet_close(struct inode * inode,
525 struct file * file)
526{
527 irnet_socket * ap = (struct irnet_socket *) file->private_data;
528
529 DENTER(FS_TRACE, "(file=0x%p, ap=0x%p)\n",
530 file, ap);
531 DABORT(ap == NULL, 0, FS_ERROR, "ap is NULL !!!\n");
532
533 /* Detach ourselves */
534 file->private_data = NULL;
535
536 /* Close IrDA stuff */
537 irda_irnet_destroy(ap);
538
539 /* Disconnect from the generic PPP layer if not already done */
540 if(ap->ppp_open)
541 {
542 DERROR(FS_ERROR, "Channel still registered - deregistering !\n");
543 ap->ppp_open = 0;
544 ppp_unregister_channel(&ap->chan);
545 }
546
547 kfree(ap);
548
549 DEXIT(FS_TRACE, "\n");
550 return 0;
551}
552
553/*------------------------------------------------------------------*/
554/*
555 * Write does nothing.
556 * (we receive packet from ppp_generic through ppp_irnet_send())
557 */
558static ssize_t
559dev_irnet_write(struct file * file,
560 const char __user *buf,
561 size_t count,
562 loff_t * ppos)
563{
564 irnet_socket * ap = (struct irnet_socket *) file->private_data;
565
566 DPASS(FS_TRACE, "(file=0x%p, ap=0x%p, count=%Zd)\n",
567 file, ap, count);
568 DABORT(ap == NULL, -ENXIO, FS_ERROR, "ap is NULL !!!\n");
569
570 /* If we are connected to ppp_generic, let it handle the job */
571 if(ap->ppp_open)
572 return -EAGAIN;
573 else
574 return irnet_ctrl_write(ap, buf, count);
575}
576
577/*------------------------------------------------------------------*/
578/*
579 * Read doesn't do much either.
580 * (pppd poll us, but ultimately reads through /dev/ppp)
581 */
582static ssize_t
583dev_irnet_read(struct file * file,
584 char __user * buf,
585 size_t count,
586 loff_t * ppos)
587{
588 irnet_socket * ap = (struct irnet_socket *) file->private_data;
589
590 DPASS(FS_TRACE, "(file=0x%p, ap=0x%p, count=%Zd)\n",
591 file, ap, count);
592 DABORT(ap == NULL, -ENXIO, FS_ERROR, "ap is NULL !!!\n");
593
594 /* If we are connected to ppp_generic, let it handle the job */
595 if(ap->ppp_open)
596 return -EAGAIN;
597 else
598 return irnet_ctrl_read(ap, file, buf, count);
599}
600
601/*------------------------------------------------------------------*/
602/*
603 * Poll : called when someone do a select on /dev/irnet
604 */
605static unsigned int
606dev_irnet_poll(struct file * file,
607 poll_table * wait)
608{
609 irnet_socket * ap = (struct irnet_socket *) file->private_data;
610 unsigned int mask;
611
612 DENTER(FS_TRACE, "(file=0x%p, ap=0x%p)\n",
613 file, ap);
614
615 mask = POLLOUT | POLLWRNORM;
616 DABORT(ap == NULL, mask, FS_ERROR, "ap is NULL !!!\n");
617
618 /* If we are connected to ppp_generic, let it handle the job */
619 if(!ap->ppp_open)
620 mask |= irnet_ctrl_poll(ap, file, wait);
621
622 DEXIT(FS_TRACE, " - mask=0x%X\n", mask);
623 return(mask);
624}
625
626/*------------------------------------------------------------------*/
627/*
628 * IOCtl : Called when someone does some ioctls on /dev/irnet
629 * This is the way pppd configure us and control us while the PPP
630 * instance is active.
631 */
632static int
633dev_irnet_ioctl(struct inode * inode,
634 struct file * file,
635 unsigned int cmd,
636 unsigned long arg)
637{
638 irnet_socket * ap = (struct irnet_socket *) file->private_data;
639 int err;
640 int val;
641 void __user *argp = (void __user *)arg;
642
643 DENTER(FS_TRACE, "(file=0x%p, ap=0x%p, cmd=0x%X)\n",
644 file, ap, cmd);
645
646 /* Basic checks... */
647 DASSERT(ap != NULL, -ENXIO, PPP_ERROR, "ap is NULL...\n");
648#ifdef SECURE_DEVIRNET
649 if(!capable(CAP_NET_ADMIN))
650 return -EPERM;
651#endif /* SECURE_DEVIRNET */
652
653 err = -EFAULT;
654 switch(cmd)
655 {
656 /* Set discipline (should be N_SYNC_PPP or N_TTY) */
657 case TIOCSETD:
658 if(get_user(val, (int __user *)argp))
659 break;
660 if((val == N_SYNC_PPP) || (val == N_PPP))
661 {
662 DEBUG(FS_INFO, "Entering PPP discipline.\n");
663 /* PPP channel setup (ap->chan in configued in dev_irnet_open())*/
664 err = ppp_register_channel(&ap->chan);
665 if(err == 0)
666 {
667 /* Our ppp side is active */
668 ap->ppp_open = 1;
669
670 DEBUG(FS_INFO, "Trying to establish a connection.\n");
671 /* Setup the IrDA link now - may fail... */
672 irda_irnet_connect(ap);
673 }
674 else
675 DERROR(FS_ERROR, "Can't setup PPP channel...\n");
676 }
677 else
678 {
679 /* In theory, should be N_TTY */
680 DEBUG(FS_INFO, "Exiting PPP discipline.\n");
681 /* Disconnect from the generic PPP layer */
682 if(ap->ppp_open)
683 {
684 ap->ppp_open = 0;
685 ppp_unregister_channel(&ap->chan);
686 }
687 else
688 DERROR(FS_ERROR, "Channel not registered !\n");
689 err = 0;
690 }
691 break;
692
693 /* Query PPP channel and unit number */
694 case PPPIOCGCHAN:
695 if(!ap->ppp_open)
696 break;
697 if(put_user(ppp_channel_index(&ap->chan), (int __user *)argp))
698 break;
699 DEBUG(FS_INFO, "Query channel.\n");
700 err = 0;
701 break;
702 case PPPIOCGUNIT:
703 if(!ap->ppp_open)
704 break;
705 if(put_user(ppp_unit_number(&ap->chan), (int __user *)argp))
706 break;
707 DEBUG(FS_INFO, "Query unit number.\n");
708 err = 0;
709 break;
710
711 /* All these ioctls can be passed both directly and from ppp_generic,
712 * so we just deal with them in one place...
713 */
714 case PPPIOCGFLAGS:
715 case PPPIOCSFLAGS:
716 case PPPIOCGASYNCMAP:
717 case PPPIOCSASYNCMAP:
718 case PPPIOCGRASYNCMAP:
719 case PPPIOCSRASYNCMAP:
720 case PPPIOCGXASYNCMAP:
721 case PPPIOCSXASYNCMAP:
722 case PPPIOCGMRU:
723 case PPPIOCSMRU:
724 DEBUG(FS_INFO, "Standard PPP ioctl.\n");
725 if(!capable(CAP_NET_ADMIN))
726 err = -EPERM;
727 else
728 err = ppp_irnet_ioctl(&ap->chan, cmd, arg);
729 break;
730
731 /* TTY IOCTLs : Pretend that we are a tty, to keep pppd happy */
732 /* Get termios */
733 case TCGETS:
734 DEBUG(FS_INFO, "Get termios.\n");
735 if(kernel_termios_to_user_termios((struct termios __user *)argp, &ap->termios))
736 break;
737 err = 0;
738 break;
739 /* Set termios */
740 case TCSETSF:
741 DEBUG(FS_INFO, "Set termios.\n");
742 if(user_termios_to_kernel_termios(&ap->termios, (struct termios __user *)argp))
743 break;
744 err = 0;
745 break;
746
747 /* Set DTR/RTS */
748 case TIOCMBIS:
749 case TIOCMBIC:
750 /* Set exclusive/non-exclusive mode */
751 case TIOCEXCL:
752 case TIOCNXCL:
753 DEBUG(FS_INFO, "TTY compatibility.\n");
754 err = 0;
755 break;
756
757 case TCGETA:
758 DEBUG(FS_INFO, "TCGETA\n");
759 break;
760
761 case TCFLSH:
762 DEBUG(FS_INFO, "TCFLSH\n");
763 /* Note : this will flush buffers in PPP, so it *must* be done
764 * We should also worry that we don't accept junk here and that
765 * we get rid of our own buffers */
766#ifdef FLUSH_TO_PPP
767 ppp_output_wakeup(&ap->chan);
768#endif /* FLUSH_TO_PPP */
769 err = 0;
770 break;
771
772 case FIONREAD:
773 DEBUG(FS_INFO, "FIONREAD\n");
774 val = 0;
775 if(put_user(val, (int __user *)argp))
776 break;
777 err = 0;
778 break;
779
780 default:
781 DERROR(FS_ERROR, "Unsupported ioctl (0x%X)\n", cmd);
782 err = -ENOIOCTLCMD;
783 }
784
785 DEXIT(FS_TRACE, " - err = 0x%X\n", err);
786 return err;
787}
788
789/************************** PPP CALLBACKS **************************/
790/*
791 * This are the functions that the generic PPP driver in the kernel
792 * will call to communicate to us.
793 */
794
795/*------------------------------------------------------------------*/
796/*
797 * Prepare the ppp frame for transmission over the IrDA socket.
798 * We make sure that the header space is enough, and we change ppp header
799 * according to flags passed by pppd.
800 * This is not a callback, but just a helper function used in ppp_irnet_send()
801 */
802static inline struct sk_buff *
803irnet_prepare_skb(irnet_socket * ap,
804 struct sk_buff * skb)
805{
806 unsigned char * data;
807 int proto; /* PPP protocol */
808 int islcp; /* Protocol == LCP */
809 int needaddr; /* Need PPP address */
810
811 DENTER(PPP_TRACE, "(ap=0x%p, skb=0x%p)\n",
812 ap, skb);
813
814 /* Extract PPP protocol from the frame */
815 data = skb->data;
816 proto = (data[0] << 8) + data[1];
817
818 /* LCP packets with codes between 1 (configure-request)
819 * and 7 (code-reject) must be sent as though no options
820 * have been negotiated. */
821 islcp = (proto == PPP_LCP) && (1 <= data[2]) && (data[2] <= 7);
822
823 /* compress protocol field if option enabled */
824 if((data[0] == 0) && (ap->flags & SC_COMP_PROT) && (!islcp))
825 skb_pull(skb,1);
826
827 /* Check if we need address/control fields */
828 needaddr = 2*((ap->flags & SC_COMP_AC) == 0 || islcp);
829
830 /* Is the skb headroom large enough to contain all IrDA-headers? */
831 if((skb_headroom(skb) < (ap->max_header_size + needaddr)) ||
832 (skb_shared(skb)))
833 {
834 struct sk_buff * new_skb;
835
836 DEBUG(PPP_INFO, "Reallocating skb\n");
837
838 /* Create a new skb */
839 new_skb = skb_realloc_headroom(skb, ap->max_header_size + needaddr);
840
841 /* We have to free the original skb anyway */
842 dev_kfree_skb(skb);
843
844 /* Did the realloc succeed ? */
845 DABORT(new_skb == NULL, NULL, PPP_ERROR, "Could not realloc skb\n");
846
847 /* Use the new skb instead */
848 skb = new_skb;
849 }
850
851 /* prepend address/control fields if necessary */
852 if(needaddr)
853 {
854 skb_push(skb, 2);
855 skb->data[0] = PPP_ALLSTATIONS;
856 skb->data[1] = PPP_UI;
857 }
858
859 DEXIT(PPP_TRACE, "\n");
860
861 return skb;
862}
863
864/*------------------------------------------------------------------*/
865/*
866 * Send a packet to the peer over the IrTTP connection.
867 * Returns 1 iff the packet was accepted.
868 * Returns 0 iff packet was not consumed.
869 * If the packet was not accepted, we will call ppp_output_wakeup
870 * at some later time to reactivate flow control in ppp_generic.
871 */
872static int
873ppp_irnet_send(struct ppp_channel * chan,
874 struct sk_buff * skb)
875{
876 irnet_socket * self = (struct irnet_socket *) chan->private;
877 int ret;
878
879 DENTER(PPP_TRACE, "(channel=0x%p, ap/self=0x%p)\n",
880 chan, self);
881
882 /* Check if things are somewhat valid... */
883 DASSERT(self != NULL, 0, PPP_ERROR, "Self is NULL !!!\n");
884
885 /* Check if we are connected */
886 if(!(test_bit(0, &self->ttp_open)))
887 {
888#ifdef CONNECT_IN_SEND
889 /* Let's try to connect one more time... */
890 /* Note : we won't be connected after this call, but we should be
891 * ready for next packet... */
892 /* If we are already connecting, this will fail */
893 irda_irnet_connect(self);
894#endif /* CONNECT_IN_SEND */
895
896 DEBUG(PPP_INFO, "IrTTP not ready ! (%ld-%ld)\n",
897 self->ttp_open, self->ttp_connect);
898
899 /* Note : we can either drop the packet or block the packet.
900 *
901 * Blocking the packet allow us a better connection time,
902 * because by calling ppp_output_wakeup() we can have
903 * ppp_generic resending the LCP request immediately to us,
904 * rather than waiting for one of pppd periodic transmission of
905 * LCP request.
906 *
907 * On the other hand, if we block all packet, all those periodic
908 * transmissions of pppd accumulate in ppp_generic, creating a
909 * backlog of LCP request. When we eventually connect later on,
910 * we have to transmit all this backlog before we can connect
911 * proper (if we don't timeout before).
912 *
913 * The current strategy is as follow :
914 * While we are attempting to connect, we block packets to get
915 * a better connection time.
916 * If we fail to connect, we drain the queue and start dropping packets
917 */
918#ifdef BLOCK_WHEN_CONNECT
919 /* If we are attempting to connect */
920 if(test_bit(0, &self->ttp_connect))
921 {
922 /* Blocking packet, ppp_generic will retry later */
923 return 0;
924 }
925#endif /* BLOCK_WHEN_CONNECT */
926
927 /* Dropping packet, pppd will retry later */
928 dev_kfree_skb(skb);
929 return 1;
930 }
931
932 /* Check if the queue can accept any packet, otherwise block */
933 if(self->tx_flow != FLOW_START)
934 DRETURN(0, PPP_INFO, "IrTTP queue full (%d skbs)...\n",
935 skb_queue_len(&self->tsap->tx_queue));
936
937 /* Prepare ppp frame for transmission */
938 skb = irnet_prepare_skb(self, skb);
939 DABORT(skb == NULL, 1, PPP_ERROR, "Prepare skb for Tx failed.\n");
940
941 /* Send the packet to IrTTP */
942 ret = irttp_data_request(self->tsap, skb);
943 if(ret < 0)
944 {
945 /*
946 * > IrTTPs tx queue is full, so we just have to
947 * > drop the frame! You might think that we should
948 * > just return -1 and don't deallocate the frame,
949 * > but that is dangerous since it's possible that
950 * > we have replaced the original skb with a new
951 * > one with larger headroom, and that would really
952 * > confuse do_dev_queue_xmit() in dev.c! I have
953 * > tried :-) DB
954 * Correction : we verify the flow control above (self->tx_flow),
955 * so we come here only if IrTTP doesn't like the packet (empty,
956 * too large, IrTTP not connected). In those rare cases, it's ok
957 * to drop it, we don't want to see it here again...
958 * Jean II
959 */
960 DERROR(PPP_ERROR, "IrTTP doesn't like this packet !!! (0x%X)\n", ret);
961 /* irttp_data_request already free the packet */
962 }
963
964 DEXIT(PPP_TRACE, "\n");
965 return 1; /* Packet has been consumed */
966}
967
968/*------------------------------------------------------------------*/
969/*
970 * Take care of the ioctls that ppp_generic doesn't want to deal with...
971 * Note : we are also called from dev_irnet_ioctl().
972 */
973static int
974ppp_irnet_ioctl(struct ppp_channel * chan,
975 unsigned int cmd,
976 unsigned long arg)
977{
978 irnet_socket * ap = (struct irnet_socket *) chan->private;
979 int err;
980 int val;
981 u32 accm[8];
982 void __user *argp = (void __user *)arg;
983
984 DENTER(PPP_TRACE, "(channel=0x%p, ap=0x%p, cmd=0x%X)\n",
985 chan, ap, cmd);
986
987 /* Basic checks... */
988 DASSERT(ap != NULL, -ENXIO, PPP_ERROR, "ap is NULL...\n");
989
990 err = -EFAULT;
991 switch(cmd)
992 {
993 /* PPP flags */
994 case PPPIOCGFLAGS:
995 val = ap->flags | ap->rbits;
996 if(put_user(val, (int __user *) argp))
997 break;
998 err = 0;
999 break;
1000 case PPPIOCSFLAGS:
1001 if(get_user(val, (int __user *) argp))
1002 break;
1003 ap->flags = val & ~SC_RCV_BITS;
1004 ap->rbits = val & SC_RCV_BITS;
1005 err = 0;
1006 break;
1007
1008 /* Async map stuff - all dummy to please pppd */
1009 case PPPIOCGASYNCMAP:
1010 if(put_user(ap->xaccm[0], (u32 __user *) argp))
1011 break;
1012 err = 0;
1013 break;
1014 case PPPIOCSASYNCMAP:
1015 if(get_user(ap->xaccm[0], (u32 __user *) argp))
1016 break;
1017 err = 0;
1018 break;
1019 case PPPIOCGRASYNCMAP:
1020 if(put_user(ap->raccm, (u32 __user *) argp))
1021 break;
1022 err = 0;
1023 break;
1024 case PPPIOCSRASYNCMAP:
1025 if(get_user(ap->raccm, (u32 __user *) argp))
1026 break;
1027 err = 0;
1028 break;
1029 case PPPIOCGXASYNCMAP:
1030 if(copy_to_user(argp, ap->xaccm, sizeof(ap->xaccm)))
1031 break;
1032 err = 0;
1033 break;
1034 case PPPIOCSXASYNCMAP:
1035 if(copy_from_user(accm, argp, sizeof(accm)))
1036 break;
1037 accm[2] &= ~0x40000000U; /* can't escape 0x5e */
1038 accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */
1039 memcpy(ap->xaccm, accm, sizeof(ap->xaccm));
1040 err = 0;
1041 break;
1042
1043 /* Max PPP frame size */
1044 case PPPIOCGMRU:
1045 if(put_user(ap->mru, (int __user *) argp))
1046 break;
1047 err = 0;
1048 break;
1049 case PPPIOCSMRU:
1050 if(get_user(val, (int __user *) argp))
1051 break;
1052 if(val < PPP_MRU)
1053 val = PPP_MRU;
1054 ap->mru = val;
1055 err = 0;
1056 break;
1057
1058 default:
1059 DEBUG(PPP_INFO, "Unsupported ioctl (0x%X)\n", cmd);
1060 err = -ENOIOCTLCMD;
1061 }
1062
1063 DEXIT(PPP_TRACE, " - err = 0x%X\n", err);
1064 return err;
1065}
1066
1067/************************** INITIALISATION **************************/
1068/*
1069 * Module initialisation and all that jazz...
1070 */
1071
1072/*------------------------------------------------------------------*/
1073/*
1074 * Hook our device callbacks in the filesystem, to connect our code
1075 * to /dev/irnet
1076 */
1077static inline int __init
1078ppp_irnet_init(void)
1079{
1080 int err = 0;
1081
1082 DENTER(MODULE_TRACE, "()\n");
1083
1084 /* Allocate ourselves as a minor in the misc range */
1085 err = misc_register(&irnet_misc_device);
1086
1087 DEXIT(MODULE_TRACE, "\n");
1088 return err;
1089}
1090
1091/*------------------------------------------------------------------*/
1092/*
1093 * Cleanup at exit...
1094 */
1095static inline void __exit
1096ppp_irnet_cleanup(void)
1097{
1098 DENTER(MODULE_TRACE, "()\n");
1099
1100 /* De-allocate /dev/irnet minor in misc range */
1101 misc_deregister(&irnet_misc_device);
1102
1103 DEXIT(MODULE_TRACE, "\n");
1104}
1105
1106/*------------------------------------------------------------------*/
1107/*
1108 * Module main entry point
1109 */
1110int __init
1111irnet_init(void)
1112{
1113 int err;
1114
1115 /* Initialise both parts... */
1116 err = irda_irnet_init();
1117 if(!err)
1118 err = ppp_irnet_init();
1119 return err;
1120}
1121
1122/*------------------------------------------------------------------*/
1123/*
1124 * Module exit
1125 */
1126static void __exit
1127irnet_cleanup(void)
1128{
1129 irda_irnet_cleanup();
1130 ppp_irnet_cleanup();
1131}
1132
1133/*------------------------------------------------------------------*/
1134/*
1135 * Module magic
1136 */
1137module_init(irnet_init);
1138module_exit(irnet_cleanup);
1139MODULE_AUTHOR("Jean Tourrilhes <jt@hpl.hp.com>");
1140MODULE_DESCRIPTION("IrNET : Synchronous PPP over IrDA");
1141MODULE_LICENSE("GPL");
1142MODULE_ALIAS_CHARDEV(10, 187);
diff --git a/net/irda/irnet/irnet_ppp.h b/net/irda/irnet/irnet_ppp.h
new file mode 100644
index 00000000000..d2beb7df8f7
--- /dev/null
+++ b/net/irda/irnet/irnet_ppp.h
@@ -0,0 +1,119 @@
1/*
2 * IrNET protocol module : Synchronous PPP over an IrDA socket.
3 *
4 * Jean II - HPL `00 - <jt@hpl.hp.com>
5 *
6 * This file contains all definitions and declarations necessary for the
7 * PPP part of the IrNET module.
8 * This file is a private header, so other modules don't want to know
9 * what's in there...
10 */
11
12#ifndef IRNET_PPP_H
13#define IRNET_PPP_H
14
15/***************************** INCLUDES *****************************/
16
17#include "irnet.h" /* Module global include */
18
19/************************ CONSTANTS & MACROS ************************/
20
21/* /dev/irnet file constants */
22#define IRNET_MAJOR 10 /* Misc range */
23#define IRNET_MINOR 187 /* Official allocation */
24
25/* IrNET control channel stuff */
26#define IRNET_MAX_COMMAND 256 /* Max length of a command line */
27
28/* PPP hardcore stuff */
29
30/* Bits in rbits (PPP flags in irnet struct) */
31#define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP)
32
33/* Bit numbers in busy */
34#define XMIT_BUSY 0
35#define RECV_BUSY 1
36#define XMIT_WAKEUP 2
37#define XMIT_FULL 3
38
39/* Queue management */
40#define PPPSYNC_MAX_RQLEN 32 /* arbitrary */
41
42/****************************** TYPES ******************************/
43
44
45/**************************** PROTOTYPES ****************************/
46
47/* ----------------------- CONTROL CHANNEL ----------------------- */
48static inline ssize_t
49 irnet_ctrl_write(irnet_socket *,
50 const char *,
51 size_t);
52static inline ssize_t
53 irnet_ctrl_read(irnet_socket *,
54 struct file *,
55 char *,
56 size_t);
57static inline unsigned int
58 irnet_ctrl_poll(irnet_socket *,
59 struct file *,
60 poll_table *);
61/* ----------------------- CHARACTER DEVICE ----------------------- */
62static int
63 dev_irnet_open(struct inode *, /* fs callback : open */
64 struct file *),
65 dev_irnet_close(struct inode *,
66 struct file *);
67static ssize_t
68 dev_irnet_write(struct file *,
69 const char __user *,
70 size_t,
71 loff_t *),
72 dev_irnet_read(struct file *,
73 char __user *,
74 size_t,
75 loff_t *);
76static unsigned int
77 dev_irnet_poll(struct file *,
78 poll_table *);
79static int
80 dev_irnet_ioctl(struct inode *,
81 struct file *,
82 unsigned int,
83 unsigned long);
84/* ------------------------ PPP INTERFACE ------------------------ */
85static inline struct sk_buff *
86 irnet_prepare_skb(irnet_socket *,
87 struct sk_buff *);
88static int
89 ppp_irnet_send(struct ppp_channel *,
90 struct sk_buff *);
91static int
92 ppp_irnet_ioctl(struct ppp_channel *,
93 unsigned int,
94 unsigned long);
95
96/**************************** VARIABLES ****************************/
97
98/* Filesystem callbacks (to call us) */
99static struct file_operations irnet_device_fops =
100{
101 .owner = THIS_MODULE,
102 .read = dev_irnet_read,
103 .write = dev_irnet_write,
104 .poll = dev_irnet_poll,
105 .ioctl = dev_irnet_ioctl,
106 .open = dev_irnet_open,
107 .release = dev_irnet_close
108 /* Also : llseek, readdir, mmap, flush, fsync, fasync, lock, readv, writev */
109};
110
111/* Structure so that the misc major (drivers/char/misc.c) take care of us... */
112static struct miscdevice irnet_misc_device =
113{
114 IRNET_MINOR,
115 "irnet",
116 &irnet_device_fops
117};
118
119#endif /* IRNET_PPP_H */
diff --git a/net/irda/irproc.c b/net/irda/irproc.c
new file mode 100644
index 00000000000..88b9c43f637
--- /dev/null
+++ b/net/irda/irproc.c
@@ -0,0 +1,100 @@
1/*********************************************************************
2 *
3 * Filename: irproc.c
4 * Version: 1.0
5 * Description: Various entries in the /proc file system
6 * Status: Experimental.
7 * Author: Thomas Davis, <ratbert@radiks.net>
8 * Created at: Sat Feb 21 21:33:24 1998
9 * Modified at: Sun Nov 14 08:54:54 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1998-1999, Dag Brattli <dagb@cs.uit.no>
13 * Copyright (c) 1998, Thomas Davis, <ratbert@radiks.net>,
14 * All Rights Reserved.
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
20 *
21 * I, Thomas Davis, provide no warranty for any of this software.
22 * This material is provided "AS-IS" and at no charge.
23 *
24 ********************************************************************/
25
26#include <linux/miscdevice.h>
27#include <linux/proc_fs.h>
28#include <linux/seq_file.h>
29#include <linux/module.h>
30#include <linux/init.h>
31
32#include <net/irda/irda.h>
33#include <net/irda/irlap.h>
34#include <net/irda/irlmp.h>
35
36extern struct file_operations discovery_seq_fops;
37extern struct file_operations irlap_seq_fops;
38extern struct file_operations irlmp_seq_fops;
39extern struct file_operations irttp_seq_fops;
40extern struct file_operations irias_seq_fops;
41
42struct irda_entry {
43 const char *name;
44 struct file_operations *fops;
45};
46
47struct proc_dir_entry *proc_irda;
48EXPORT_SYMBOL(proc_irda);
49
50static struct irda_entry irda_dirs[] = {
51 {"discovery", &discovery_seq_fops},
52 {"irttp", &irttp_seq_fops},
53 {"irlmp", &irlmp_seq_fops},
54 {"irlap", &irlap_seq_fops},
55 {"irias", &irias_seq_fops},
56};
57
58/*
59 * Function irda_proc_register (void)
60 *
61 * Register irda entry in /proc file system
62 *
63 */
64void __init irda_proc_register(void)
65{
66 int i;
67 struct proc_dir_entry *d;
68
69 proc_irda = proc_mkdir("irda", proc_net);
70 if (proc_irda == NULL)
71 return;
72 proc_irda->owner = THIS_MODULE;
73
74 for (i=0; i<ARRAY_SIZE(irda_dirs); i++) {
75 d = create_proc_entry(irda_dirs[i].name, 0, proc_irda);
76 if (d)
77 d->proc_fops = irda_dirs[i].fops;
78 }
79}
80
81/*
82 * Function irda_proc_unregister (void)
83 *
84 * Unregister irda entry in /proc file system
85 *
86 */
87void __exit irda_proc_unregister(void)
88{
89 int i;
90
91 if (proc_irda) {
92 for (i=0; i<ARRAY_SIZE(irda_dirs); i++)
93 remove_proc_entry(irda_dirs[i].name, proc_irda);
94
95 remove_proc_entry("irda", proc_net);
96 proc_irda = NULL;
97 }
98}
99
100
diff --git a/net/irda/irqueue.c b/net/irda/irqueue.c
new file mode 100644
index 00000000000..b0dd3ea3599
--- /dev/null
+++ b/net/irda/irqueue.c
@@ -0,0 +1,915 @@
1/*********************************************************************
2 *
3 * Filename: irqueue.c
4 * Version: 0.3
5 * Description: General queue implementation
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Tue Jun 9 13:29:31 1998
9 * Modified at: Sun Dec 12 13:48:22 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 * Modified at: Thu Jan 4 14:29:10 CET 2001
12 * Modified by: Marc Zyngier <mzyngier@freesurf.fr>
13 *
14 * Copyright (C) 1998-1999, Aage Kvalnes <aage@cs.uit.no>
15 * Copyright (C) 1998, Dag Brattli,
16 * All Rights Reserved.
17 *
18 * This code is taken from the Vortex Operating System written by Aage
19 * Kvalnes. Aage has agreed that this code can use the GPL licence,
20 * although he does not use that licence in his own code.
21 *
22 * This copyright does however _not_ include the ELF hash() function
23 * which I currently don't know which licence or copyright it
24 * has. Please inform me if you know.
25 *
26 * This program is free software; you can redistribute it and/or
27 * modify it under the terms of the GNU General Public License as
28 * published by the Free Software Foundation; either version 2 of
29 * the License, or (at your option) any later version.
30 *
31 * Neither Dag Brattli nor University of Tromsø admit liability nor
32 * provide warranty for any of this software. This material is
33 * provided "AS-IS" and at no charge.
34 *
35 ********************************************************************/
36
37/*
38 * NOTE :
39 * There are various problems with this package :
40 * o the hash function for ints is pathetic (but could be changed)
41 * o locking is sometime suspicious (especially during enumeration)
42 * o most users have only a few elements (== overhead)
43 * o most users never use seach, so don't benefit from hashing
44 * Problem already fixed :
45 * o not 64 bit compliant (most users do hashv = (int) self)
46 * o hashbin_remove() is broken => use hashbin_remove_this()
47 * I think most users would be better served by a simple linked list
48 * (like include/linux/list.h) with a global spinlock per list.
49 * Jean II
50 */
51
52/*
53 * Notes on the concurrent access to hashbin and other SMP issues
54 * -------------------------------------------------------------
55 * Hashbins are very often in the IrDA stack a global repository of
56 * information, and therefore used in a very asynchronous manner following
57 * various events (driver calls, timers, user calls...).
58 * Therefore, very often it is highly important to consider the
59 * management of concurrent access to the hashbin and how to guarantee the
60 * consistency of the operations on it.
61 *
62 * First, we need to define the objective of locking :
63 * 1) Protect user data (content pointed by the hashbin)
64 * 2) Protect hashbin structure itself (linked list in each bin)
65 *
66 * OLD LOCKING
67 * -----------
68 *
69 * The previous locking strategy, either HB_LOCAL or HB_GLOBAL were
70 * both inadequate in *both* aspect.
71 * o HB_GLOBAL was using a spinlock for each bin (local locking).
72 * o HB_LOCAL was disabling irq on *all* CPUs, so use a single
73 * global semaphore.
74 * The problems were :
75 * A) Global irq disabling is no longer supported by the kernel
76 * B) No protection for the hashbin struct global data
77 * o hashbin_delete()
78 * o hb_current
79 * C) No protection for user data in some cases
80 *
81 * A) HB_LOCAL use global irq disabling, so doesn't work on kernel
82 * 2.5.X. Even when it is supported (kernel 2.4.X and earlier), its
83 * performance is not satisfactory on SMP setups. Most hashbins were
84 * HB_LOCAL, so (A) definitely need fixing.
85 * B) HB_LOCAL could be modified to fix (B). However, because HB_GLOBAL
86 * lock only the individual bins, it will never be able to lock the
87 * global data, so can't do (B).
88 * C) Some functions return pointer to data that is still in the
89 * hashbin :
90 * o hashbin_find()
91 * o hashbin_get_first()
92 * o hashbin_get_next()
93 * As the data is still in the hashbin, it may be changed or free'd
94 * while the caller is examinimg the data. In those case, locking can't
95 * be done within the hashbin, but must include use of the data within
96 * the caller.
97 * The caller can easily do this with HB_LOCAL (just disable irqs).
98 * However, this is impossible with HB_GLOBAL because the caller has no
99 * way to know the proper bin, so don't know which spinlock to use.
100 *
101 * Quick summary : can no longer use HB_LOCAL, and HB_GLOBAL is
102 * fundamentally broken and will never work.
103 *
104 * NEW LOCKING
105 * -----------
106 *
107 * To fix those problems, I've introduce a few changes in the
108 * hashbin locking :
109 * 1) New HB_LOCK scheme
110 * 2) hashbin->hb_spinlock
111 * 3) New hashbin usage policy
112 *
113 * HB_LOCK :
114 * -------
115 * HB_LOCK is a locking scheme intermediate between the old HB_LOCAL
116 * and HB_GLOBAL. It uses a single spinlock to protect the whole content
117 * of the hashbin. As it is a single spinlock, it can protect the global
118 * data of the hashbin and not only the bins themselves.
119 * HB_LOCK can only protect some of the hashbin calls, so it only lock
120 * call that can be made 100% safe and leave other call unprotected.
121 * HB_LOCK in theory is slower than HB_GLOBAL, but as the hashbin
122 * content is always small contention is not high, so it doesn't matter
123 * much. HB_LOCK is probably faster than HB_LOCAL.
124 *
125 * hashbin->hb_spinlock :
126 * --------------------
127 * The spinlock that HB_LOCK uses is available for caller, so that
128 * the caller can protect unprotected calls (see below).
129 * If the caller want to do entirely its own locking (HB_NOLOCK), he
130 * can do so and may use safely this spinlock.
131 * Locking is done like this :
132 * spin_lock_irqsave(&hashbin->hb_spinlock, flags);
133 * Releasing the lock :
134 * spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
135 *
136 * Safe & Protected calls :
137 * ----------------------
138 * The following calls are safe or protected via HB_LOCK :
139 * o hashbin_new() -> safe
140 * o hashbin_delete()
141 * o hashbin_insert()
142 * o hashbin_remove_first()
143 * o hashbin_remove()
144 * o hashbin_remove_this()
145 * o HASHBIN_GET_SIZE() -> atomic
146 *
147 * The following calls only protect the hashbin itself :
148 * o hashbin_lock_find()
149 * o hashbin_find_next()
150 *
151 * Unprotected calls :
152 * -----------------
153 * The following calls need to be protected by the caller :
154 * o hashbin_find()
155 * o hashbin_get_first()
156 * o hashbin_get_next()
157 *
158 * Locking Policy :
159 * --------------
160 * If the hashbin is used only in a single thread of execution
161 * (explicitly or implicitely), you can use HB_NOLOCK
162 * If the calling module already provide concurrent access protection,
163 * you may use HB_NOLOCK.
164 *
165 * In all other cases, you need to use HB_LOCK and lock the hashbin
166 * every time before calling one of the unprotected calls. You also must
167 * use the pointer returned by the unprotected call within the locked
168 * region.
169 *
170 * Extra care for enumeration :
171 * --------------------------
172 * hashbin_get_first() and hashbin_get_next() use the hashbin to
173 * store the current position, in hb_current.
174 * As long as the hashbin remains locked, this is safe. If you unlock
175 * the hashbin, the current position may change if anybody else modify
176 * or enumerate the hashbin.
177 * Summary : do the full enumeration while locked.
178 *
179 * Alternatively, you may use hashbin_find_next(). But, this will
180 * be slower, is more complex to use and doesn't protect the hashbin
181 * content. So, care is needed here as well.
182 *
183 * Other issues :
184 * ------------
185 * I believe that we are overdoing it by using spin_lock_irqsave()
186 * and we should use only spin_lock_bh() or similar. But, I don't have
187 * the balls to try it out.
188 * Don't believe that because hashbin are now (somewhat) SMP safe
189 * that the rest of the code is. Higher layers tend to be safest,
190 * but LAP and LMP would need some serious dedicated love.
191 *
192 * Jean II
193 */
194#include <linux/module.h>
195
196#include <net/irda/irda.h>
197#include <net/irda/irqueue.h>
198
199/************************ QUEUE SUBROUTINES ************************/
200
201/*
202 * Hashbin
203 */
204#define GET_HASHBIN(x) ( x & HASHBIN_MASK )
205
206/*
207 * Function hash (name)
208 *
209 * This function hash the input string 'name' using the ELF hash
210 * function for strings.
211 */
212static __u32 hash( const char* name)
213{
214 __u32 h = 0;
215 __u32 g;
216
217 while(*name) {
218 h = (h<<4) + *name++;
219 if ((g = (h & 0xf0000000)))
220 h ^=g>>24;
221 h &=~g;
222 }
223 return h;
224}
225
226/*
227 * Function enqueue_first (queue, proc)
228 *
229 * Insert item first in queue.
230 *
231 */
232static void enqueue_first(irda_queue_t **queue, irda_queue_t* element)
233{
234
235 IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
236
237 /*
238 * Check if queue is empty.
239 */
240 if ( *queue == NULL ) {
241 /*
242 * Queue is empty. Insert one element into the queue.
243 */
244 element->q_next = element->q_prev = *queue = element;
245
246 } else {
247 /*
248 * Queue is not empty. Insert element into front of queue.
249 */
250 element->q_next = (*queue);
251 (*queue)->q_prev->q_next = element;
252 element->q_prev = (*queue)->q_prev;
253 (*queue)->q_prev = element;
254 (*queue) = element;
255 }
256}
257
258
259/*
260 * Function dequeue (queue)
261 *
262 * Remove first entry in queue
263 *
264 */
265static irda_queue_t *dequeue_first(irda_queue_t **queue)
266{
267 irda_queue_t *ret;
268
269 IRDA_DEBUG( 4, "dequeue_first()\n");
270
271 /*
272 * Set return value
273 */
274 ret = *queue;
275
276 if ( *queue == NULL ) {
277 /*
278 * Queue was empty.
279 */
280 } else if ( (*queue)->q_next == *queue ) {
281 /*
282 * Queue only contained a single element. It will now be
283 * empty.
284 */
285 *queue = NULL;
286 } else {
287 /*
288 * Queue contained several element. Remove the first one.
289 */
290 (*queue)->q_prev->q_next = (*queue)->q_next;
291 (*queue)->q_next->q_prev = (*queue)->q_prev;
292 *queue = (*queue)->q_next;
293 }
294
295 /*
296 * Return the removed entry (or NULL of queue was empty).
297 */
298 return ret;
299}
300
301/*
302 * Function dequeue_general (queue, element)
303 *
304 *
305 */
306static irda_queue_t *dequeue_general(irda_queue_t **queue, irda_queue_t* element)
307{
308 irda_queue_t *ret;
309
310 IRDA_DEBUG( 4, "dequeue_general()\n");
311
312 /*
313 * Set return value
314 */
315 ret = *queue;
316
317 if ( *queue == NULL ) {
318 /*
319 * Queue was empty.
320 */
321 } else if ( (*queue)->q_next == *queue ) {
322 /*
323 * Queue only contained a single element. It will now be
324 * empty.
325 */
326 *queue = NULL;
327
328 } else {
329 /*
330 * Remove specific element.
331 */
332 element->q_prev->q_next = element->q_next;
333 element->q_next->q_prev = element->q_prev;
334 if ( (*queue) == element)
335 (*queue) = element->q_next;
336 }
337
338 /*
339 * Return the removed entry (or NULL of queue was empty).
340 */
341 return ret;
342}
343
344/************************ HASHBIN MANAGEMENT ************************/
345
346/*
347 * Function hashbin_create ( type, name )
348 *
349 * Create hashbin!
350 *
351 */
352hashbin_t *hashbin_new(int type)
353{
354 hashbin_t* hashbin;
355
356 /*
357 * Allocate new hashbin
358 */
359 hashbin = kmalloc( sizeof(hashbin_t), GFP_ATOMIC);
360 if (!hashbin)
361 return NULL;
362
363 /*
364 * Initialize structure
365 */
366 memset(hashbin, 0, sizeof(hashbin_t));
367 hashbin->hb_type = type;
368 hashbin->magic = HB_MAGIC;
369 //hashbin->hb_current = NULL;
370
371 /* Make sure all spinlock's are unlocked */
372 if ( hashbin->hb_type & HB_LOCK ) {
373 spin_lock_init(&hashbin->hb_spinlock);
374 }
375
376 return hashbin;
377}
378EXPORT_SYMBOL(hashbin_new);
379
380
381/*
382 * Function hashbin_delete (hashbin, free_func)
383 *
384 * Destroy hashbin, the free_func can be a user supplied special routine
385 * for deallocating this structure if it's complex. If not the user can
386 * just supply kfree, which should take care of the job.
387 */
388int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func)
389{
390 irda_queue_t* queue;
391 unsigned long flags = 0;
392 int i;
393
394 IRDA_ASSERT(hashbin != NULL, return -1;);
395 IRDA_ASSERT(hashbin->magic == HB_MAGIC, return -1;);
396
397 /* Synchronize */
398 if ( hashbin->hb_type & HB_LOCK ) {
399 spin_lock_irqsave(&hashbin->hb_spinlock, flags);
400 }
401
402 /*
403 * Free the entries in the hashbin, TODO: use hashbin_clear when
404 * it has been shown to work
405 */
406 for (i = 0; i < HASHBIN_SIZE; i ++ ) {
407 queue = dequeue_first((irda_queue_t**) &hashbin->hb_queue[i]);
408 while (queue ) {
409 if (free_func)
410 (*free_func)(queue);
411 queue = dequeue_first(
412 (irda_queue_t**) &hashbin->hb_queue[i]);
413 }
414 }
415
416 /* Cleanup local data */
417 hashbin->hb_current = NULL;
418 hashbin->magic = ~HB_MAGIC;
419
420 /* Release lock */
421 if ( hashbin->hb_type & HB_LOCK) {
422 spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
423 }
424
425 /*
426 * Free the hashbin structure
427 */
428 kfree(hashbin);
429
430 return 0;
431}
432EXPORT_SYMBOL(hashbin_delete);
433
434/********************* HASHBIN LIST OPERATIONS *********************/
435
436/*
437 * Function hashbin_insert (hashbin, entry, name)
438 *
439 * Insert an entry into the hashbin
440 *
441 */
442void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, long hashv,
443 const char* name)
444{
445 unsigned long flags = 0;
446 int bin;
447
448 IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
449
450 IRDA_ASSERT( hashbin != NULL, return;);
451 IRDA_ASSERT( hashbin->magic == HB_MAGIC, return;);
452
453 /*
454 * Locate hashbin
455 */
456 if ( name )
457 hashv = hash( name );
458 bin = GET_HASHBIN( hashv );
459
460 /* Synchronize */
461 if ( hashbin->hb_type & HB_LOCK ) {
462 spin_lock_irqsave(&hashbin->hb_spinlock, flags);
463 } /* Default is no-lock */
464
465 /*
466 * Store name and key
467 */
468 entry->q_hash = hashv;
469 if ( name )
470 strlcpy( entry->q_name, name, sizeof(entry->q_name));
471
472 /*
473 * Insert new entry first
474 */
475 enqueue_first( (irda_queue_t**) &hashbin->hb_queue[ bin ],
476 entry);
477 hashbin->hb_size++;
478
479 /* Release lock */
480 if ( hashbin->hb_type & HB_LOCK ) {
481 spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
482 } /* Default is no-lock */
483}
484EXPORT_SYMBOL(hashbin_insert);
485
486/*
487 * Function hashbin_remove_first (hashbin)
488 *
489 * Remove first entry of the hashbin
490 *
491 * Note : this function no longer use hashbin_remove(), but does things
492 * similar to hashbin_remove_this(), so can be considered safe.
493 * Jean II
494 */
495void *hashbin_remove_first( hashbin_t *hashbin)
496{
497 unsigned long flags = 0;
498 irda_queue_t *entry = NULL;
499
500 /* Synchronize */
501 if ( hashbin->hb_type & HB_LOCK ) {
502 spin_lock_irqsave(&hashbin->hb_spinlock, flags);
503 } /* Default is no-lock */
504
505 entry = hashbin_get_first( hashbin);
506 if ( entry != NULL) {
507 int bin;
508 long hashv;
509 /*
510 * Locate hashbin
511 */
512 hashv = entry->q_hash;
513 bin = GET_HASHBIN( hashv );
514
515 /*
516 * Dequeue the entry...
517 */
518 dequeue_general( (irda_queue_t**) &hashbin->hb_queue[ bin ],
519 (irda_queue_t*) entry );
520 hashbin->hb_size--;
521 entry->q_next = NULL;
522 entry->q_prev = NULL;
523
524 /*
525 * Check if this item is the currently selected item, and in
526 * that case we must reset hb_current
527 */
528 if ( entry == hashbin->hb_current)
529 hashbin->hb_current = NULL;
530 }
531
532 /* Release lock */
533 if ( hashbin->hb_type & HB_LOCK ) {
534 spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
535 } /* Default is no-lock */
536
537 return entry;
538}
539
540
541/*
542 * Function hashbin_remove (hashbin, hashv, name)
543 *
544 * Remove entry with the given name
545 *
546 * The use of this function is highly discouraged, because the whole
547 * concept behind hashbin_remove() is broken. In many cases, it's not
548 * possible to guarantee the unicity of the index (either hashv or name),
549 * leading to removing the WRONG entry.
550 * The only simple safe use is :
551 * hashbin_remove(hasbin, (int) self, NULL);
552 * In other case, you must think hard to guarantee unicity of the index.
553 * Jean II
554 */
555void* hashbin_remove( hashbin_t* hashbin, long hashv, const char* name)
556{
557 int bin, found = FALSE;
558 unsigned long flags = 0;
559 irda_queue_t* entry;
560
561 IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
562
563 IRDA_ASSERT( hashbin != NULL, return NULL;);
564 IRDA_ASSERT( hashbin->magic == HB_MAGIC, return NULL;);
565
566 /*
567 * Locate hashbin
568 */
569 if ( name )
570 hashv = hash( name );
571 bin = GET_HASHBIN( hashv );
572
573 /* Synchronize */
574 if ( hashbin->hb_type & HB_LOCK ) {
575 spin_lock_irqsave(&hashbin->hb_spinlock, flags);
576 } /* Default is no-lock */
577
578 /*
579 * Search for entry
580 */
581 entry = hashbin->hb_queue[ bin ];
582 if ( entry ) {
583 do {
584 /*
585 * Check for key
586 */
587 if ( entry->q_hash == hashv ) {
588 /*
589 * Name compare too?
590 */
591 if ( name ) {
592 if ( strcmp( entry->q_name, name) == 0)
593 {
594 found = TRUE;
595 break;
596 }
597 } else {
598 found = TRUE;
599 break;
600 }
601 }
602 entry = entry->q_next;
603 } while ( entry != hashbin->hb_queue[ bin ] );
604 }
605
606 /*
607 * If entry was found, dequeue it
608 */
609 if ( found ) {
610 dequeue_general( (irda_queue_t**) &hashbin->hb_queue[ bin ],
611 (irda_queue_t*) entry );
612 hashbin->hb_size--;
613
614 /*
615 * Check if this item is the currently selected item, and in
616 * that case we must reset hb_current
617 */
618 if ( entry == hashbin->hb_current)
619 hashbin->hb_current = NULL;
620 }
621
622 /* Release lock */
623 if ( hashbin->hb_type & HB_LOCK ) {
624 spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
625 } /* Default is no-lock */
626
627
628 /* Return */
629 if ( found )
630 return entry;
631 else
632 return NULL;
633
634}
635EXPORT_SYMBOL(hashbin_remove);
636
637/*
638 * Function hashbin_remove_this (hashbin, entry)
639 *
640 * Remove entry with the given name
641 *
642 * In some cases, the user of hashbin can't guarantee the unicity
643 * of either the hashv or name.
644 * In those cases, using the above function is guaranteed to cause troubles,
645 * so we use this one instead...
646 * And by the way, it's also faster, because we skip the search phase ;-)
647 */
648void* hashbin_remove_this( hashbin_t* hashbin, irda_queue_t* entry)
649{
650 unsigned long flags = 0;
651 int bin;
652 long hashv;
653
654 IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
655
656 IRDA_ASSERT( hashbin != NULL, return NULL;);
657 IRDA_ASSERT( hashbin->magic == HB_MAGIC, return NULL;);
658 IRDA_ASSERT( entry != NULL, return NULL;);
659
660 /* Synchronize */
661 if ( hashbin->hb_type & HB_LOCK ) {
662 spin_lock_irqsave(&hashbin->hb_spinlock, flags);
663 } /* Default is no-lock */
664
665 /* Check if valid and not already removed... */
666 if((entry->q_next == NULL) || (entry->q_prev == NULL)) {
667 entry = NULL;
668 goto out;
669 }
670
671 /*
672 * Locate hashbin
673 */
674 hashv = entry->q_hash;
675 bin = GET_HASHBIN( hashv );
676
677 /*
678 * Dequeue the entry...
679 */
680 dequeue_general( (irda_queue_t**) &hashbin->hb_queue[ bin ],
681 (irda_queue_t*) entry );
682 hashbin->hb_size--;
683 entry->q_next = NULL;
684 entry->q_prev = NULL;
685
686 /*
687 * Check if this item is the currently selected item, and in
688 * that case we must reset hb_current
689 */
690 if ( entry == hashbin->hb_current)
691 hashbin->hb_current = NULL;
692out:
693 /* Release lock */
694 if ( hashbin->hb_type & HB_LOCK ) {
695 spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
696 } /* Default is no-lock */
697
698 return entry;
699}
700EXPORT_SYMBOL(hashbin_remove_this);
701
702/*********************** HASHBIN ENUMERATION ***********************/
703
704/*
705 * Function hashbin_common_find (hashbin, hashv, name)
706 *
707 * Find item with the given hashv or name
708 *
709 */
710void* hashbin_find( hashbin_t* hashbin, long hashv, const char* name )
711{
712 int bin;
713 irda_queue_t* entry;
714
715 IRDA_DEBUG( 4, "hashbin_find()\n");
716
717 IRDA_ASSERT( hashbin != NULL, return NULL;);
718 IRDA_ASSERT( hashbin->magic == HB_MAGIC, return NULL;);
719
720 /*
721 * Locate hashbin
722 */
723 if ( name )
724 hashv = hash( name );
725 bin = GET_HASHBIN( hashv );
726
727 /*
728 * Search for entry
729 */
730 entry = hashbin->hb_queue[ bin];
731 if ( entry ) {
732 do {
733 /*
734 * Check for key
735 */
736 if ( entry->q_hash == hashv ) {
737 /*
738 * Name compare too?
739 */
740 if ( name ) {
741 if ( strcmp( entry->q_name, name ) == 0 ) {
742 return entry;
743 }
744 } else {
745 return entry;
746 }
747 }
748 entry = entry->q_next;
749 } while ( entry != hashbin->hb_queue[ bin ] );
750 }
751
752 return NULL;
753}
754EXPORT_SYMBOL(hashbin_find);
755
756/*
757 * Function hashbin_lock_find (hashbin, hashv, name)
758 *
759 * Find item with the given hashv or name
760 *
761 * Same, but with spinlock protection...
762 * I call it safe, but it's only safe with respect to the hashbin, not its
763 * content. - Jean II
764 */
765void* hashbin_lock_find( hashbin_t* hashbin, long hashv, const char* name )
766{
767 unsigned long flags = 0;
768 irda_queue_t* entry;
769
770 /* Synchronize */
771 spin_lock_irqsave(&hashbin->hb_spinlock, flags);
772
773 /*
774 * Search for entry
775 */
776 entry = (irda_queue_t* ) hashbin_find( hashbin, hashv, name );
777
778 /* Release lock */
779 spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
780
781 return entry;
782}
783EXPORT_SYMBOL(hashbin_lock_find);
784
785/*
786 * Function hashbin_find (hashbin, hashv, name, pnext)
787 *
788 * Find an item with the given hashv or name, and its successor
789 *
790 * This function allow to do concurrent enumerations without the
791 * need to lock over the whole session, because the caller keep the
792 * context of the search. On the other hand, it might fail and return
793 * NULL if the entry is removed. - Jean II
794 */
795void* hashbin_find_next( hashbin_t* hashbin, long hashv, const char* name,
796 void ** pnext)
797{
798 unsigned long flags = 0;
799 irda_queue_t* entry;
800
801 /* Synchronize */
802 spin_lock_irqsave(&hashbin->hb_spinlock, flags);
803
804 /*
805 * Search for current entry
806 * This allow to check if the current item is still in the
807 * hashbin or has been removed.
808 */
809 entry = (irda_queue_t* ) hashbin_find( hashbin, hashv, name );
810
811 /*
812 * Trick hashbin_get_next() to return what we want
813 */
814 if(entry) {
815 hashbin->hb_current = entry;
816 *pnext = hashbin_get_next( hashbin );
817 } else
818 *pnext = NULL;
819
820 /* Release lock */
821 spin_unlock_irqrestore(&hashbin->hb_spinlock, flags);
822
823 return entry;
824}
825EXPORT_SYMBOL(hashbin_find_next);
826
827/*
828 * Function hashbin_get_first (hashbin)
829 *
830 * Get a pointer to first element in hashbin, this function must be
831 * called before any calls to hashbin_get_next()!
832 *
833 */
834irda_queue_t *hashbin_get_first( hashbin_t* hashbin)
835{
836 irda_queue_t *entry;
837 int i;
838
839 IRDA_ASSERT( hashbin != NULL, return NULL;);
840 IRDA_ASSERT( hashbin->magic == HB_MAGIC, return NULL;);
841
842 if ( hashbin == NULL)
843 return NULL;
844
845 for ( i = 0; i < HASHBIN_SIZE; i ++ ) {
846 entry = hashbin->hb_queue[ i];
847 if ( entry) {
848 hashbin->hb_current = entry;
849 return entry;
850 }
851 }
852 /*
853 * Did not find any item in hashbin
854 */
855 return NULL;
856}
857EXPORT_SYMBOL(hashbin_get_first);
858
859/*
860 * Function hashbin_get_next (hashbin)
861 *
862 * Get next item in hashbin. A series of hashbin_get_next() calls must
863 * be started by a call to hashbin_get_first(). The function returns
864 * NULL when all items have been traversed
865 *
866 * The context of the search is stored within the hashbin, so you must
867 * protect yourself from concurrent enumerations. - Jean II
868 */
869irda_queue_t *hashbin_get_next( hashbin_t *hashbin)
870{
871 irda_queue_t* entry;
872 int bin;
873 int i;
874
875 IRDA_ASSERT( hashbin != NULL, return NULL;);
876 IRDA_ASSERT( hashbin->magic == HB_MAGIC, return NULL;);
877
878 if ( hashbin->hb_current == NULL) {
879 IRDA_ASSERT( hashbin->hb_current != NULL, return NULL;);
880 return NULL;
881 }
882 entry = hashbin->hb_current->q_next;
883 bin = GET_HASHBIN( entry->q_hash);
884
885 /*
886 * Make sure that we are not back at the beginning of the queue
887 * again
888 */
889 if ( entry != hashbin->hb_queue[ bin ]) {
890 hashbin->hb_current = entry;
891
892 return entry;
893 }
894
895 /*
896 * Check that this is not the last queue in hashbin
897 */
898 if ( bin >= HASHBIN_SIZE)
899 return NULL;
900
901 /*
902 * Move to next queue in hashbin
903 */
904 bin++;
905 for ( i = bin; i < HASHBIN_SIZE; i++ ) {
906 entry = hashbin->hb_queue[ i];
907 if ( entry) {
908 hashbin->hb_current = entry;
909
910 return entry;
911 }
912 }
913 return NULL;
914}
915EXPORT_SYMBOL(hashbin_get_next);
diff --git a/net/irda/irsysctl.c b/net/irda/irsysctl.c
new file mode 100644
index 00000000000..1b1c4193359
--- /dev/null
+++ b/net/irda/irsysctl.c
@@ -0,0 +1,297 @@
1/*********************************************************************
2 *
3 * Filename: irsysctl.c
4 * Version: 1.0
5 * Description: Sysctl interface for IrDA
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun May 24 22:12:06 1998
9 * Modified at: Fri Jun 4 02:50:15 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1997, 1999 Dag Brattli, All Rights Reserved.
13 * Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * Neither Dag Brattli nor University of Tromsø admit liability nor
21 * provide warranty for any of this software. This material is
22 * provided "AS-IS" and at no charge.
23 *
24 ********************************************************************/
25
26#include <linux/config.h>
27#include <linux/mm.h>
28#include <linux/ctype.h>
29#include <linux/sysctl.h>
30#include <linux/init.h>
31
32#include <net/irda/irda.h> /* irda_debug */
33#include <net/irda/irias_object.h>
34
35#define NET_IRDA 412 /* Random number */
36enum { DISCOVERY=1, DEVNAME, DEBUG, FAST_POLL, DISCOVERY_SLOTS,
37 DISCOVERY_TIMEOUT, SLOT_TIMEOUT, MAX_BAUD_RATE, MIN_TX_TURN_TIME,
38 MAX_TX_DATA_SIZE, MAX_TX_WINDOW, MAX_NOREPLY_TIME, WARN_NOREPLY_TIME,
39 LAP_KEEPALIVE_TIME };
40
41extern int sysctl_discovery;
42extern int sysctl_discovery_slots;
43extern int sysctl_discovery_timeout;
44extern int sysctl_slot_timeout;
45extern int sysctl_fast_poll_increase;
46extern char sysctl_devname[];
47extern int sysctl_max_baud_rate;
48extern int sysctl_min_tx_turn_time;
49extern int sysctl_max_tx_data_size;
50extern int sysctl_max_tx_window;
51extern int sysctl_max_noreply_time;
52extern int sysctl_warn_noreply_time;
53extern int sysctl_lap_keepalive_time;
54
55/* this is needed for the proc_dointvec_minmax - Jean II */
56static int max_discovery_slots = 16; /* ??? */
57static int min_discovery_slots = 1;
58/* IrLAP 6.13.2 says 25ms to 10+70ms - allow higher since some devices
59 * seems to require it. (from Dag's comment) */
60static int max_slot_timeout = 160;
61static int min_slot_timeout = 20;
62static int max_max_baud_rate = 16000000; /* See qos.c - IrLAP spec */
63static int min_max_baud_rate = 2400;
64static int max_min_tx_turn_time = 10000; /* See qos.c - IrLAP spec */
65static int min_min_tx_turn_time;
66static int max_max_tx_data_size = 2048; /* See qos.c - IrLAP spec */
67static int min_max_tx_data_size = 64;
68static int max_max_tx_window = 7; /* See qos.c - IrLAP spec */
69static int min_max_tx_window = 1;
70static int max_max_noreply_time = 40; /* See qos.c - IrLAP spec */
71static int min_max_noreply_time = 3;
72static int max_warn_noreply_time = 3; /* 3s == standard */
73static int min_warn_noreply_time = 1; /* 1s == min WD_TIMER */
74static int max_lap_keepalive_time = 10000; /* 10s */
75static int min_lap_keepalive_time = 100; /* 100us */
76/* For other sysctl, I've no idea of the range. Maybe Dag could help
77 * us on that - Jean II */
78
79static int do_devname(ctl_table *table, int write, struct file *filp,
80 void __user *buffer, size_t *lenp, loff_t *ppos)
81{
82 int ret;
83
84 ret = proc_dostring(table, write, filp, buffer, lenp, ppos);
85 if (ret == 0 && write) {
86 struct ias_value *val;
87
88 val = irias_new_string_value(sysctl_devname);
89 if (val)
90 irias_object_change_attribute("Device", "DeviceName", val);
91 }
92 return ret;
93}
94
95/* One file */
96static ctl_table irda_table[] = {
97 {
98 .ctl_name = DISCOVERY,
99 .procname = "discovery",
100 .data = &sysctl_discovery,
101 .maxlen = sizeof(int),
102 .mode = 0644,
103 .proc_handler = &proc_dointvec
104 },
105 {
106 .ctl_name = DEVNAME,
107 .procname = "devname",
108 .data = sysctl_devname,
109 .maxlen = 65,
110 .mode = 0644,
111 .proc_handler = &do_devname,
112 .strategy = &sysctl_string
113 },
114#ifdef CONFIG_IRDA_DEBUG
115 {
116 .ctl_name = DEBUG,
117 .procname = "debug",
118 .data = &irda_debug,
119 .maxlen = sizeof(int),
120 .mode = 0644,
121 .proc_handler = &proc_dointvec
122 },
123#endif
124#ifdef CONFIG_IRDA_FAST_RR
125 {
126 .ctl_name = FAST_POLL,
127 .procname = "fast_poll_increase",
128 .data = &sysctl_fast_poll_increase,
129 .maxlen = sizeof(int),
130 .mode = 0644,
131 .proc_handler = &proc_dointvec
132 },
133#endif
134 {
135 .ctl_name = DISCOVERY_SLOTS,
136 .procname = "discovery_slots",
137 .data = &sysctl_discovery_slots,
138 .maxlen = sizeof(int),
139 .mode = 0644,
140 .proc_handler = &proc_dointvec_minmax,
141 .strategy = &sysctl_intvec,
142 .extra1 = &min_discovery_slots,
143 .extra2 = &max_discovery_slots
144 },
145 {
146 .ctl_name = DISCOVERY_TIMEOUT,
147 .procname = "discovery_timeout",
148 .data = &sysctl_discovery_timeout,
149 .maxlen = sizeof(int),
150 .mode = 0644,
151 .proc_handler = &proc_dointvec
152 },
153 {
154 .ctl_name = SLOT_TIMEOUT,
155 .procname = "slot_timeout",
156 .data = &sysctl_slot_timeout,
157 .maxlen = sizeof(int),
158 .mode = 0644,
159 .proc_handler = &proc_dointvec_minmax,
160 .strategy = &sysctl_intvec,
161 .extra1 = &min_slot_timeout,
162 .extra2 = &max_slot_timeout
163 },
164 {
165 .ctl_name = MAX_BAUD_RATE,
166 .procname = "max_baud_rate",
167 .data = &sysctl_max_baud_rate,
168 .maxlen = sizeof(int),
169 .mode = 0644,
170 .proc_handler = &proc_dointvec_minmax,
171 .strategy = &sysctl_intvec,
172 .extra1 = &min_max_baud_rate,
173 .extra2 = &max_max_baud_rate
174 },
175 {
176 .ctl_name = MIN_TX_TURN_TIME,
177 .procname = "min_tx_turn_time",
178 .data = &sysctl_min_tx_turn_time,
179 .maxlen = sizeof(int),
180 .mode = 0644,
181 .proc_handler = &proc_dointvec_minmax,
182 .strategy = &sysctl_intvec,
183 .extra1 = &min_min_tx_turn_time,
184 .extra2 = &max_min_tx_turn_time
185 },
186 {
187 .ctl_name = MAX_TX_DATA_SIZE,
188 .procname = "max_tx_data_size",
189 .data = &sysctl_max_tx_data_size,
190 .maxlen = sizeof(int),
191 .mode = 0644,
192 .proc_handler = &proc_dointvec_minmax,
193 .strategy = &sysctl_intvec,
194 .extra1 = &min_max_tx_data_size,
195 .extra2 = &max_max_tx_data_size
196 },
197 {
198 .ctl_name = MAX_TX_WINDOW,
199 .procname = "max_tx_window",
200 .data = &sysctl_max_tx_window,
201 .maxlen = sizeof(int),
202 .mode = 0644,
203 .proc_handler = &proc_dointvec_minmax,
204 .strategy = &sysctl_intvec,
205 .extra1 = &min_max_tx_window,
206 .extra2 = &max_max_tx_window
207 },
208 {
209 .ctl_name = MAX_NOREPLY_TIME,
210 .procname = "max_noreply_time",
211 .data = &sysctl_max_noreply_time,
212 .maxlen = sizeof(int),
213 .mode = 0644,
214 .proc_handler = &proc_dointvec_minmax,
215 .strategy = &sysctl_intvec,
216 .extra1 = &min_max_noreply_time,
217 .extra2 = &max_max_noreply_time
218 },
219 {
220 .ctl_name = WARN_NOREPLY_TIME,
221 .procname = "warn_noreply_time",
222 .data = &sysctl_warn_noreply_time,
223 .maxlen = sizeof(int),
224 .mode = 0644,
225 .proc_handler = &proc_dointvec_minmax,
226 .strategy = &sysctl_intvec,
227 .extra1 = &min_warn_noreply_time,
228 .extra2 = &max_warn_noreply_time
229 },
230 {
231 .ctl_name = LAP_KEEPALIVE_TIME,
232 .procname = "lap_keepalive_time",
233 .data = &sysctl_lap_keepalive_time,
234 .maxlen = sizeof(int),
235 .mode = 0644,
236 .proc_handler = &proc_dointvec_minmax,
237 .strategy = &sysctl_intvec,
238 .extra1 = &min_lap_keepalive_time,
239 .extra2 = &max_lap_keepalive_time
240 },
241 { .ctl_name = 0 }
242};
243
244/* One directory */
245static ctl_table irda_net_table[] = {
246 {
247 .ctl_name = NET_IRDA,
248 .procname = "irda",
249 .maxlen = 0,
250 .mode = 0555,
251 .child = irda_table
252 },
253 { .ctl_name = 0 }
254};
255
256/* The parent directory */
257static ctl_table irda_root_table[] = {
258 {
259 .ctl_name = CTL_NET,
260 .procname = "net",
261 .maxlen = 0,
262 .mode = 0555,
263 .child = irda_net_table
264 },
265 { .ctl_name = 0 }
266};
267
268static struct ctl_table_header *irda_table_header;
269
270/*
271 * Function irda_sysctl_register (void)
272 *
273 * Register our sysctl interface
274 *
275 */
276int __init irda_sysctl_register(void)
277{
278 irda_table_header = register_sysctl_table(irda_root_table, 0);
279 if (!irda_table_header)
280 return -ENOMEM;
281
282 return 0;
283}
284
285/*
286 * Function irda_sysctl_unregister (void)
287 *
288 * Unregister our sysctl interface
289 *
290 */
291void __exit irda_sysctl_unregister(void)
292{
293 unregister_sysctl_table(irda_table_header);
294}
295
296
297
diff --git a/net/irda/irttp.c b/net/irda/irttp.c
new file mode 100644
index 00000000000..d091ccf773b
--- /dev/null
+++ b/net/irda/irttp.c
@@ -0,0 +1,1912 @@
1/*********************************************************************
2 *
3 * Filename: irttp.c
4 * Version: 1.2
5 * Description: Tiny Transport Protocol (TTP) implementation
6 * Status: Stable
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sun Aug 31 20:14:31 1997
9 * Modified at: Wed Jan 5 11:31:27 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
13 * All Rights Reserved.
14 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
20 *
21 * Neither Dag Brattli nor University of Tromsø admit liability nor
22 * provide warranty for any of this software. This material is
23 * provided "AS-IS" and at no charge.
24 *
25 ********************************************************************/
26
27#include <linux/config.h>
28#include <linux/skbuff.h>
29#include <linux/init.h>
30#include <linux/seq_file.h>
31
32#include <asm/byteorder.h>
33#include <asm/unaligned.h>
34
35#include <net/irda/irda.h>
36#include <net/irda/irlap.h>
37#include <net/irda/irlmp.h>
38#include <net/irda/parameters.h>
39#include <net/irda/irttp.h>
40
41static struct irttp_cb *irttp = NULL;
42
43static void __irttp_close_tsap(struct tsap_cb *self);
44
45static int irttp_data_indication(void *instance, void *sap,
46 struct sk_buff *skb);
47static int irttp_udata_indication(void *instance, void *sap,
48 struct sk_buff *skb);
49static void irttp_disconnect_indication(void *instance, void *sap,
50 LM_REASON reason, struct sk_buff *);
51static void irttp_connect_indication(void *instance, void *sap,
52 struct qos_info *qos, __u32 max_sdu_size,
53 __u8 header_size, struct sk_buff *skb);
54static void irttp_connect_confirm(void *instance, void *sap,
55 struct qos_info *qos, __u32 max_sdu_size,
56 __u8 header_size, struct sk_buff *skb);
57static void irttp_run_tx_queue(struct tsap_cb *self);
58static void irttp_run_rx_queue(struct tsap_cb *self);
59
60static void irttp_flush_queues(struct tsap_cb *self);
61static void irttp_fragment_skb(struct tsap_cb *self, struct sk_buff *skb);
62static struct sk_buff *irttp_reassemble_skb(struct tsap_cb *self);
63static void irttp_todo_expired(unsigned long data);
64static int irttp_param_max_sdu_size(void *instance, irda_param_t *param,
65 int get);
66
67static void irttp_flow_indication(void *instance, void *sap, LOCAL_FLOW flow);
68static void irttp_status_indication(void *instance,
69 LINK_STATUS link, LOCK_STATUS lock);
70
71/* Information for parsing parameters in IrTTP */
72static pi_minor_info_t pi_minor_call_table[] = {
73 { NULL, 0 }, /* 0x00 */
74 { irttp_param_max_sdu_size, PV_INTEGER | PV_BIG_ENDIAN } /* 0x01 */
75};
76static pi_major_info_t pi_major_call_table[] = {{ pi_minor_call_table, 2 }};
77static pi_param_info_t param_info = { pi_major_call_table, 1, 0x0f, 4 };
78
79/************************ GLOBAL PROCEDURES ************************/
80
81/*
82 * Function irttp_init (void)
83 *
84 * Initialize the IrTTP layer. Called by module initialization code
85 *
86 */
87int __init irttp_init(void)
88{
89 /* Initialize the irttp structure. */
90 if (irttp == NULL) {
91 irttp = kmalloc(sizeof(struct irttp_cb), GFP_KERNEL);
92 if (irttp == NULL)
93 return -ENOMEM;
94 }
95 memset(irttp, 0, sizeof(struct irttp_cb));
96
97 irttp->magic = TTP_MAGIC;
98
99 irttp->tsaps = hashbin_new(HB_LOCK);
100 if (!irttp->tsaps) {
101 IRDA_ERROR("%s: can't allocate IrTTP hashbin!\n",
102 __FUNCTION__);
103 return -ENOMEM;
104 }
105
106 return 0;
107}
108
109/*
110 * Function irttp_cleanup (void)
111 *
112 * Called by module destruction/cleanup code
113 *
114 */
115void __exit irttp_cleanup(void)
116{
117 /* Check for main structure */
118 IRDA_ASSERT(irttp != NULL, return;);
119 IRDA_ASSERT(irttp->magic == TTP_MAGIC, return;);
120
121 /*
122 * Delete hashbin and close all TSAP instances in it
123 */
124 hashbin_delete(irttp->tsaps, (FREE_FUNC) __irttp_close_tsap);
125
126 irttp->magic = 0;
127
128 /* De-allocate main structure */
129 kfree(irttp);
130
131 irttp = NULL;
132}
133
134/*************************** SUBROUTINES ***************************/
135
136/*
137 * Function irttp_start_todo_timer (self, timeout)
138 *
139 * Start todo timer.
140 *
141 * Made it more effient and unsensitive to race conditions - Jean II
142 */
143static inline void irttp_start_todo_timer(struct tsap_cb *self, int timeout)
144{
145 /* Set new value for timer */
146 mod_timer(&self->todo_timer, jiffies + timeout);
147}
148
149/*
150 * Function irttp_todo_expired (data)
151 *
152 * Todo timer has expired!
153 *
154 * One of the restriction of the timer is that it is run only on the timer
155 * interrupt which run every 10ms. This mean that even if you set the timer
156 * with a delay of 0, it may take up to 10ms before it's run.
157 * So, to minimise latency and keep cache fresh, we try to avoid using
158 * it as much as possible.
159 * Note : we can't use tasklets, because they can't be asynchronously
160 * killed (need user context), and we can't guarantee that here...
161 * Jean II
162 */
163static void irttp_todo_expired(unsigned long data)
164{
165 struct tsap_cb *self = (struct tsap_cb *) data;
166
167 /* Check that we still exist */
168 if (!self || self->magic != TTP_TSAP_MAGIC)
169 return;
170
171 IRDA_DEBUG(4, "%s(instance=%p)\n", __FUNCTION__, self);
172
173 /* Try to make some progress, especially on Tx side - Jean II */
174 irttp_run_rx_queue(self);
175 irttp_run_tx_queue(self);
176
177 /* Check if time for disconnect */
178 if (test_bit(0, &self->disconnect_pend)) {
179 /* Check if it's possible to disconnect yet */
180 if (skb_queue_empty(&self->tx_queue)) {
181 /* Make sure disconnect is not pending anymore */
182 clear_bit(0, &self->disconnect_pend); /* FALSE */
183
184 /* Note : self->disconnect_skb may be NULL */
185 irttp_disconnect_request(self, self->disconnect_skb,
186 P_NORMAL);
187 self->disconnect_skb = NULL;
188 } else {
189 /* Try again later */
190 irttp_start_todo_timer(self, HZ/10);
191
192 /* No reason to try and close now */
193 return;
194 }
195 }
196
197 /* Check if it's closing time */
198 if (self->close_pend)
199 /* Finish cleanup */
200 irttp_close_tsap(self);
201}
202
203/*
204 * Function irttp_flush_queues (self)
205 *
206 * Flushes (removes all frames) in transitt-buffer (tx_list)
207 */
208void irttp_flush_queues(struct tsap_cb *self)
209{
210 struct sk_buff* skb;
211
212 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
213
214 IRDA_ASSERT(self != NULL, return;);
215 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
216
217 /* Deallocate frames waiting to be sent */
218 while ((skb = skb_dequeue(&self->tx_queue)) != NULL)
219 dev_kfree_skb(skb);
220
221 /* Deallocate received frames */
222 while ((skb = skb_dequeue(&self->rx_queue)) != NULL)
223 dev_kfree_skb(skb);
224
225 /* Deallocate received fragments */
226 while ((skb = skb_dequeue(&self->rx_fragments)) != NULL)
227 dev_kfree_skb(skb);
228}
229
230/*
231 * Function irttp_reassemble (self)
232 *
233 * Makes a new (continuous) skb of all the fragments in the fragment
234 * queue
235 *
236 */
237static struct sk_buff *irttp_reassemble_skb(struct tsap_cb *self)
238{
239 struct sk_buff *skb, *frag;
240 int n = 0; /* Fragment index */
241
242 IRDA_ASSERT(self != NULL, return NULL;);
243 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return NULL;);
244
245 IRDA_DEBUG(2, "%s(), self->rx_sdu_size=%d\n", __FUNCTION__,
246 self->rx_sdu_size);
247
248 skb = dev_alloc_skb(TTP_HEADER + self->rx_sdu_size);
249 if (!skb)
250 return NULL;
251
252 /*
253 * Need to reserve space for TTP header in case this skb needs to
254 * be requeued in case delivery failes
255 */
256 skb_reserve(skb, TTP_HEADER);
257 skb_put(skb, self->rx_sdu_size);
258
259 /*
260 * Copy all fragments to a new buffer
261 */
262 while ((frag = skb_dequeue(&self->rx_fragments)) != NULL) {
263 memcpy(skb->data+n, frag->data, frag->len);
264 n += frag->len;
265
266 dev_kfree_skb(frag);
267 }
268
269 IRDA_DEBUG(2,
270 "%s(), frame len=%d, rx_sdu_size=%d, rx_max_sdu_size=%d\n",
271 __FUNCTION__, n, self->rx_sdu_size, self->rx_max_sdu_size);
272 /* Note : irttp_run_rx_queue() calculate self->rx_sdu_size
273 * by summing the size of all fragments, so we should always
274 * have n == self->rx_sdu_size, except in cases where we
275 * droped the last fragment (when self->rx_sdu_size exceed
276 * self->rx_max_sdu_size), where n < self->rx_sdu_size.
277 * Jean II */
278 IRDA_ASSERT(n <= self->rx_sdu_size, n = self->rx_sdu_size;);
279
280 /* Set the new length */
281 skb_trim(skb, n);
282
283 self->rx_sdu_size = 0;
284
285 return skb;
286}
287
288/*
289 * Function irttp_fragment_skb (skb)
290 *
291 * Fragments a frame and queues all the fragments for transmission
292 *
293 */
294static inline void irttp_fragment_skb(struct tsap_cb *self,
295 struct sk_buff *skb)
296{
297 struct sk_buff *frag;
298 __u8 *frame;
299
300 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
301
302 IRDA_ASSERT(self != NULL, return;);
303 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
304 IRDA_ASSERT(skb != NULL, return;);
305
306 /*
307 * Split frame into a number of segments
308 */
309 while (skb->len > self->max_seg_size) {
310 IRDA_DEBUG(2, "%s(), fragmenting ...\n", __FUNCTION__);
311
312 /* Make new segment */
313 frag = dev_alloc_skb(self->max_seg_size+self->max_header_size);
314 if (!frag)
315 return;
316
317 skb_reserve(frag, self->max_header_size);
318
319 /* Copy data from the original skb into this fragment. */
320 memcpy(skb_put(frag, self->max_seg_size), skb->data,
321 self->max_seg_size);
322
323 /* Insert TTP header, with the more bit set */
324 frame = skb_push(frag, TTP_HEADER);
325 frame[0] = TTP_MORE;
326
327 /* Hide the copied data from the original skb */
328 skb_pull(skb, self->max_seg_size);
329
330 /* Queue fragment */
331 skb_queue_tail(&self->tx_queue, frag);
332 }
333 /* Queue what is left of the original skb */
334 IRDA_DEBUG(2, "%s(), queuing last segment\n", __FUNCTION__);
335
336 frame = skb_push(skb, TTP_HEADER);
337 frame[0] = 0x00; /* Clear more bit */
338
339 /* Queue fragment */
340 skb_queue_tail(&self->tx_queue, skb);
341}
342
343/*
344 * Function irttp_param_max_sdu_size (self, param)
345 *
346 * Handle the MaxSduSize parameter in the connect frames, this function
347 * will be called both when this parameter needs to be inserted into, and
348 * extracted from the connect frames
349 */
350static int irttp_param_max_sdu_size(void *instance, irda_param_t *param,
351 int get)
352{
353 struct tsap_cb *self;
354
355 self = (struct tsap_cb *) instance;
356
357 IRDA_ASSERT(self != NULL, return -1;);
358 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
359
360 if (get)
361 param->pv.i = self->tx_max_sdu_size;
362 else
363 self->tx_max_sdu_size = param->pv.i;
364
365 IRDA_DEBUG(1, "%s(), MaxSduSize=%d\n", __FUNCTION__, param->pv.i);
366
367 return 0;
368}
369
370/*************************** CLIENT CALLS ***************************/
371/************************** LMP CALLBACKS **************************/
372/* Everything is happily mixed up. Waiting for next clean up - Jean II */
373
374/*
375 * Function irttp_open_tsap (stsap, notify)
376 *
377 * Create TSAP connection endpoint,
378 */
379struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
380{
381 struct tsap_cb *self;
382 struct lsap_cb *lsap;
383 notify_t ttp_notify;
384
385 IRDA_ASSERT(irttp != NULL, return NULL;);
386 IRDA_ASSERT(irttp->magic == TTP_MAGIC, return NULL;);
387
388 /* The IrLMP spec (IrLMP 1.1 p10) says that we have the right to
389 * use only 0x01-0x6F. Of course, we can use LSAP_ANY as well.
390 * JeanII */
391 if((stsap_sel != LSAP_ANY) &&
392 ((stsap_sel < 0x01) || (stsap_sel >= 0x70))) {
393 IRDA_DEBUG(0, "%s(), invalid tsap!\n", __FUNCTION__);
394 return NULL;
395 }
396
397 self = kmalloc(sizeof(struct tsap_cb), GFP_ATOMIC);
398 if (self == NULL) {
399 IRDA_DEBUG(0, "%s(), unable to kmalloc!\n", __FUNCTION__);
400 return NULL;
401 }
402 memset(self, 0, sizeof(struct tsap_cb));
403 spin_lock_init(&self->lock);
404
405 /* Initialise todo timer */
406 init_timer(&self->todo_timer);
407 self->todo_timer.data = (unsigned long) self;
408 self->todo_timer.function = &irttp_todo_expired;
409
410 /* Initialize callbacks for IrLMP to use */
411 irda_notify_init(&ttp_notify);
412 ttp_notify.connect_confirm = irttp_connect_confirm;
413 ttp_notify.connect_indication = irttp_connect_indication;
414 ttp_notify.disconnect_indication = irttp_disconnect_indication;
415 ttp_notify.data_indication = irttp_data_indication;
416 ttp_notify.udata_indication = irttp_udata_indication;
417 ttp_notify.flow_indication = irttp_flow_indication;
418 if(notify->status_indication != NULL)
419 ttp_notify.status_indication = irttp_status_indication;
420 ttp_notify.instance = self;
421 strncpy(ttp_notify.name, notify->name, NOTIFY_MAX_NAME);
422
423 self->magic = TTP_TSAP_MAGIC;
424 self->connected = FALSE;
425
426 skb_queue_head_init(&self->rx_queue);
427 skb_queue_head_init(&self->tx_queue);
428 skb_queue_head_init(&self->rx_fragments);
429 /*
430 * Create LSAP at IrLMP layer
431 */
432 lsap = irlmp_open_lsap(stsap_sel, &ttp_notify, 0);
433 if (lsap == NULL) {
434 IRDA_WARNING("%s: unable to allocate LSAP!!\n", __FUNCTION__);
435 return NULL;
436 }
437
438 /*
439 * If user specified LSAP_ANY as source TSAP selector, then IrLMP
440 * will replace it with whatever source selector which is free, so
441 * the stsap_sel we have might not be valid anymore
442 */
443 self->stsap_sel = lsap->slsap_sel;
444 IRDA_DEBUG(4, "%s(), stsap_sel=%02x\n", __FUNCTION__, self->stsap_sel);
445
446 self->notify = *notify;
447 self->lsap = lsap;
448
449 hashbin_insert(irttp->tsaps, (irda_queue_t *) self, (long) self, NULL);
450
451 if (credit > TTP_RX_MAX_CREDIT)
452 self->initial_credit = TTP_RX_MAX_CREDIT;
453 else
454 self->initial_credit = credit;
455
456 return self;
457}
458EXPORT_SYMBOL(irttp_open_tsap);
459
460/*
461 * Function irttp_close (handle)
462 *
463 * Remove an instance of a TSAP. This function should only deal with the
464 * deallocation of the TSAP, and resetting of the TSAPs values;
465 *
466 */
467static void __irttp_close_tsap(struct tsap_cb *self)
468{
469 /* First make sure we're connected. */
470 IRDA_ASSERT(self != NULL, return;);
471 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
472
473 irttp_flush_queues(self);
474
475 del_timer(&self->todo_timer);
476
477 /* This one won't be cleaned up if we are disconnect_pend + close_pend
478 * and we receive a disconnect_indication */
479 if (self->disconnect_skb)
480 dev_kfree_skb(self->disconnect_skb);
481
482 self->connected = FALSE;
483 self->magic = ~TTP_TSAP_MAGIC;
484
485 kfree(self);
486}
487
488/*
489 * Function irttp_close (self)
490 *
491 * Remove TSAP from list of all TSAPs and then deallocate all resources
492 * associated with this TSAP
493 *
494 * Note : because we *free* the tsap structure, it is the responsibility
495 * of the caller to make sure we are called only once and to deal with
496 * possible race conditions. - Jean II
497 */
498int irttp_close_tsap(struct tsap_cb *self)
499{
500 struct tsap_cb *tsap;
501
502 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
503
504 IRDA_ASSERT(self != NULL, return -1;);
505 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
506
507 /* Make sure tsap has been disconnected */
508 if (self->connected) {
509 /* Check if disconnect is not pending */
510 if (!test_bit(0, &self->disconnect_pend)) {
511 IRDA_WARNING("%s: TSAP still connected!\n",
512 __FUNCTION__);
513 irttp_disconnect_request(self, NULL, P_NORMAL);
514 }
515 self->close_pend = TRUE;
516 irttp_start_todo_timer(self, HZ/10);
517
518 return 0; /* Will be back! */
519 }
520
521 tsap = hashbin_remove(irttp->tsaps, (long) self, NULL);
522
523 IRDA_ASSERT(tsap == self, return -1;);
524
525 /* Close corresponding LSAP */
526 if (self->lsap) {
527 irlmp_close_lsap(self->lsap);
528 self->lsap = NULL;
529 }
530
531 __irttp_close_tsap(self);
532
533 return 0;
534}
535EXPORT_SYMBOL(irttp_close_tsap);
536
537/*
538 * Function irttp_udata_request (self, skb)
539 *
540 * Send unreliable data on this TSAP
541 *
542 */
543int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb)
544{
545 IRDA_ASSERT(self != NULL, return -1;);
546 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
547 IRDA_ASSERT(skb != NULL, return -1;);
548
549 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
550
551 /* Check that nothing bad happens */
552 if ((skb->len == 0) || (!self->connected)) {
553 IRDA_DEBUG(1, "%s(), No data, or not connected\n",
554 __FUNCTION__);
555 goto err;
556 }
557
558 if (skb->len > self->max_seg_size) {
559 IRDA_DEBUG(1, "%s(), UData is to large for IrLAP!\n",
560 __FUNCTION__);
561 goto err;
562 }
563
564 irlmp_udata_request(self->lsap, skb);
565 self->stats.tx_packets++;
566
567 return 0;
568
569err:
570 dev_kfree_skb(skb);
571 return -1;
572}
573EXPORT_SYMBOL(irttp_udata_request);
574
575
576/*
577 * Function irttp_data_request (handle, skb)
578 *
579 * Queue frame for transmission. If SAR is enabled, fragement the frame
580 * and queue the fragments for transmission
581 */
582int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb)
583{
584 __u8 *frame;
585 int ret;
586
587 IRDA_ASSERT(self != NULL, return -1;);
588 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
589 IRDA_ASSERT(skb != NULL, return -1;);
590
591 IRDA_DEBUG(2, "%s() : queue len = %d\n", __FUNCTION__,
592 skb_queue_len(&self->tx_queue));
593
594 /* Check that nothing bad happens */
595 if ((skb->len == 0) || (!self->connected)) {
596 IRDA_WARNING("%s: No data, or not connected\n", __FUNCTION__);
597 ret = -ENOTCONN;
598 goto err;
599 }
600
601 /*
602 * Check if SAR is disabled, and the frame is larger than what fits
603 * inside an IrLAP frame
604 */
605 if ((self->tx_max_sdu_size == 0) && (skb->len > self->max_seg_size)) {
606 IRDA_ERROR("%s: SAR disabled, and data is to large for IrLAP!\n",
607 __FUNCTION__);
608 ret = -EMSGSIZE;
609 goto err;
610 }
611
612 /*
613 * Check if SAR is enabled, and the frame is larger than the
614 * TxMaxSduSize
615 */
616 if ((self->tx_max_sdu_size != 0) &&
617 (self->tx_max_sdu_size != TTP_SAR_UNBOUND) &&
618 (skb->len > self->tx_max_sdu_size))
619 {
620 IRDA_ERROR("%s: SAR enabled, but data is larger than TxMaxSduSize!\n",
621 __FUNCTION__);
622 ret = -EMSGSIZE;
623 goto err;
624 }
625 /*
626 * Check if transmit queue is full
627 */
628 if (skb_queue_len(&self->tx_queue) >= TTP_TX_MAX_QUEUE) {
629 /*
630 * Give it a chance to empty itself
631 */
632 irttp_run_tx_queue(self);
633
634 /* Drop packet. This error code should trigger the caller
635 * to resend the data in the client code - Jean II */
636 ret = -ENOBUFS;
637 goto err;
638 }
639
640 /* Queue frame, or queue frame segments */
641 if ((self->tx_max_sdu_size == 0) || (skb->len < self->max_seg_size)) {
642 /* Queue frame */
643 IRDA_ASSERT(skb_headroom(skb) >= TTP_HEADER, return -1;);
644 frame = skb_push(skb, TTP_HEADER);
645 frame[0] = 0x00; /* Clear more bit */
646
647 skb_queue_tail(&self->tx_queue, skb);
648 } else {
649 /*
650 * Fragment the frame, this function will also queue the
651 * fragments, we don't care about the fact the transmit
652 * queue may be overfilled by all the segments for a little
653 * while
654 */
655 irttp_fragment_skb(self, skb);
656 }
657
658 /* Check if we can accept more data from client */
659 if ((!self->tx_sdu_busy) &&
660 (skb_queue_len(&self->tx_queue) > TTP_TX_HIGH_THRESHOLD)) {
661 /* Tx queue filling up, so stop client. */
662 if (self->notify.flow_indication) {
663 self->notify.flow_indication(self->notify.instance,
664 self, FLOW_STOP);
665 }
666 /* self->tx_sdu_busy is the state of the client.
667 * Update state after notifying client to avoid
668 * race condition with irttp_flow_indication().
669 * If the queue empty itself after our test but before
670 * we set the flag, we will fix ourselves below in
671 * irttp_run_tx_queue().
672 * Jean II */
673 self->tx_sdu_busy = TRUE;
674 }
675
676 /* Try to make some progress */
677 irttp_run_tx_queue(self);
678
679 return 0;
680
681err:
682 dev_kfree_skb(skb);
683 return ret;
684}
685EXPORT_SYMBOL(irttp_data_request);
686
687/*
688 * Function irttp_run_tx_queue (self)
689 *
690 * Transmit packets queued for transmission (if possible)
691 *
692 */
693static void irttp_run_tx_queue(struct tsap_cb *self)
694{
695 struct sk_buff *skb;
696 unsigned long flags;
697 int n;
698
699 IRDA_DEBUG(2, "%s() : send_credit = %d, queue_len = %d\n",
700 __FUNCTION__,
701 self->send_credit, skb_queue_len(&self->tx_queue));
702
703 /* Get exclusive access to the tx queue, otherwise don't touch it */
704 if (irda_lock(&self->tx_queue_lock) == FALSE)
705 return;
706
707 /* Try to send out frames as long as we have credits
708 * and as long as LAP is not full. If LAP is full, it will
709 * poll us through irttp_flow_indication() - Jean II */
710 while ((self->send_credit > 0) &&
711 (!irlmp_lap_tx_queue_full(self->lsap)) &&
712 (skb = skb_dequeue(&self->tx_queue)))
713 {
714 /*
715 * Since we can transmit and receive frames concurrently,
716 * the code below is a critical region and we must assure that
717 * nobody messes with the credits while we update them.
718 */
719 spin_lock_irqsave(&self->lock, flags);
720
721 n = self->avail_credit;
722 self->avail_credit = 0;
723
724 /* Only room for 127 credits in frame */
725 if (n > 127) {
726 self->avail_credit = n-127;
727 n = 127;
728 }
729 self->remote_credit += n;
730 self->send_credit--;
731
732 spin_unlock_irqrestore(&self->lock, flags);
733
734 /*
735 * More bit must be set by the data_request() or fragment()
736 * functions
737 */
738 skb->data[0] |= (n & 0x7f);
739
740 /* Detach from socket.
741 * The current skb has a reference to the socket that sent
742 * it (skb->sk). When we pass it to IrLMP, the skb will be
743 * stored in in IrLAP (self->wx_list). When we are within
744 * IrLAP, we lose the notion of socket, so we should not
745 * have a reference to a socket. So, we drop it here.
746 *
747 * Why does it matter ?
748 * When the skb is freed (kfree_skb), if it is associated
749 * with a socket, it release buffer space on the socket
750 * (through sock_wfree() and sock_def_write_space()).
751 * If the socket no longer exist, we may crash. Hard.
752 * When we close a socket, we make sure that associated packets
753 * in IrTTP are freed. However, we have no way to cancel
754 * the packet that we have passed to IrLAP. So, if a packet
755 * remains in IrLAP (retry on the link or else) after we
756 * close the socket, we are dead !
757 * Jean II */
758 if (skb->sk != NULL) {
759 /* IrSOCK application, IrOBEX, ... */
760 skb_orphan(skb);
761 }
762 /* IrCOMM over IrTTP, IrLAN, ... */
763
764 /* Pass the skb to IrLMP - done */
765 irlmp_data_request(self->lsap, skb);
766 self->stats.tx_packets++;
767 }
768
769 /* Check if we can accept more frames from client.
770 * We don't want to wait until the todo timer to do that, and we
771 * can't use tasklets (grr...), so we are obliged to give control
772 * to client. That's ok, this test will be true not too often
773 * (max once per LAP window) and we are called from places
774 * where we can spend a bit of time doing stuff. - Jean II */
775 if ((self->tx_sdu_busy) &&
776 (skb_queue_len(&self->tx_queue) < TTP_TX_LOW_THRESHOLD) &&
777 (!self->close_pend))
778 {
779 if (self->notify.flow_indication)
780 self->notify.flow_indication(self->notify.instance,
781 self, FLOW_START);
782
783 /* self->tx_sdu_busy is the state of the client.
784 * We don't really have a race here, but it's always safer
785 * to update our state after the client - Jean II */
786 self->tx_sdu_busy = FALSE;
787 }
788
789 /* Reset lock */
790 self->tx_queue_lock = 0;
791}
792
793/*
794 * Function irttp_give_credit (self)
795 *
796 * Send a dataless flowdata TTP-PDU and give available credit to peer
797 * TSAP
798 */
799static inline void irttp_give_credit(struct tsap_cb *self)
800{
801 struct sk_buff *tx_skb = NULL;
802 unsigned long flags;
803 int n;
804
805 IRDA_ASSERT(self != NULL, return;);
806 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
807
808 IRDA_DEBUG(4, "%s() send=%d,avail=%d,remote=%d\n",
809 __FUNCTION__,
810 self->send_credit, self->avail_credit, self->remote_credit);
811
812 /* Give credit to peer */
813 tx_skb = dev_alloc_skb(64);
814 if (!tx_skb)
815 return;
816
817 /* Reserve space for LMP, and LAP header */
818 skb_reserve(tx_skb, self->max_header_size);
819
820 /*
821 * Since we can transmit and receive frames concurrently,
822 * the code below is a critical region and we must assure that
823 * nobody messes with the credits while we update them.
824 */
825 spin_lock_irqsave(&self->lock, flags);
826
827 n = self->avail_credit;
828 self->avail_credit = 0;
829
830 /* Only space for 127 credits in frame */
831 if (n > 127) {
832 self->avail_credit = n - 127;
833 n = 127;
834 }
835 self->remote_credit += n;
836
837 spin_unlock_irqrestore(&self->lock, flags);
838
839 skb_put(tx_skb, 1);
840 tx_skb->data[0] = (__u8) (n & 0x7f);
841
842 irlmp_data_request(self->lsap, tx_skb);
843 self->stats.tx_packets++;
844}
845
846/*
847 * Function irttp_udata_indication (instance, sap, skb)
848 *
849 * Received some unit-data (unreliable)
850 *
851 */
852static int irttp_udata_indication(void *instance, void *sap,
853 struct sk_buff *skb)
854{
855 struct tsap_cb *self;
856 int err;
857
858 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
859
860 self = (struct tsap_cb *) instance;
861
862 IRDA_ASSERT(self != NULL, return -1;);
863 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
864 IRDA_ASSERT(skb != NULL, return -1;);
865
866 self->stats.rx_packets++;
867
868 /* Just pass data to layer above */
869 if (self->notify.udata_indication) {
870 err = self->notify.udata_indication(self->notify.instance,
871 self,skb);
872 /* Same comment as in irttp_do_data_indication() */
873 if (!err)
874 return 0;
875 }
876 /* Either no handler, or handler returns an error */
877 dev_kfree_skb(skb);
878
879 return 0;
880}
881
882/*
883 * Function irttp_data_indication (instance, sap, skb)
884 *
885 * Receive segment from IrLMP.
886 *
887 */
888static int irttp_data_indication(void *instance, void *sap,
889 struct sk_buff *skb)
890{
891 struct tsap_cb *self;
892 unsigned long flags;
893 int n;
894
895 self = (struct tsap_cb *) instance;
896
897 n = skb->data[0] & 0x7f; /* Extract the credits */
898
899 self->stats.rx_packets++;
900
901 /* Deal with inbound credit
902 * Since we can transmit and receive frames concurrently,
903 * the code below is a critical region and we must assure that
904 * nobody messes with the credits while we update them.
905 */
906 spin_lock_irqsave(&self->lock, flags);
907 self->send_credit += n;
908 if (skb->len > 1)
909 self->remote_credit--;
910 spin_unlock_irqrestore(&self->lock, flags);
911
912 /*
913 * Data or dataless packet? Dataless frames contains only the
914 * TTP_HEADER.
915 */
916 if (skb->len > 1) {
917 /*
918 * We don't remove the TTP header, since we must preserve the
919 * more bit, so the defragment routing knows what to do
920 */
921 skb_queue_tail(&self->rx_queue, skb);
922 } else {
923 /* Dataless flowdata TTP-PDU */
924 dev_kfree_skb(skb);
925 }
926
927
928 /* Push data to the higher layer.
929 * We do it synchronously because running the todo timer for each
930 * receive packet would be too much overhead and latency.
931 * By passing control to the higher layer, we run the risk that
932 * it may take time or grab a lock. Most often, the higher layer
933 * will only put packet in a queue.
934 * Anyway, packets are only dripping through the IrDA, so we can
935 * have time before the next packet.
936 * Further, we are run from NET_BH, so the worse that can happen is
937 * us missing the optimal time to send back the PF bit in LAP.
938 * Jean II */
939 irttp_run_rx_queue(self);
940
941 /* We now give credits to peer in irttp_run_rx_queue().
942 * We need to send credit *NOW*, otherwise we are going
943 * to miss the next Tx window. The todo timer may take
944 * a while before it's run... - Jean II */
945
946 /*
947 * If the peer device has given us some credits and we didn't have
948 * anyone from before, then we need to shedule the tx queue.
949 * We need to do that because our Tx have stopped (so we may not
950 * get any LAP flow indication) and the user may be stopped as
951 * well. - Jean II
952 */
953 if (self->send_credit == n) {
954 /* Restart pushing stuff to LAP */
955 irttp_run_tx_queue(self);
956 /* Note : we don't want to schedule the todo timer
957 * because it has horrible latency. No tasklets
958 * because the tasklet API is broken. - Jean II */
959 }
960
961 return 0;
962}
963
964/*
965 * Function irttp_status_indication (self, reason)
966 *
967 * Status_indication, just pass to the higher layer...
968 *
969 */
970static void irttp_status_indication(void *instance,
971 LINK_STATUS link, LOCK_STATUS lock)
972{
973 struct tsap_cb *self;
974
975 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
976
977 self = (struct tsap_cb *) instance;
978
979 IRDA_ASSERT(self != NULL, return;);
980 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
981
982 /* Check if client has already closed the TSAP and gone away */
983 if (self->close_pend)
984 return;
985
986 /*
987 * Inform service user if he has requested it
988 */
989 if (self->notify.status_indication != NULL)
990 self->notify.status_indication(self->notify.instance,
991 link, lock);
992 else
993 IRDA_DEBUG(2, "%s(), no handler\n", __FUNCTION__);
994}
995
996/*
997 * Function irttp_flow_indication (self, reason)
998 *
999 * Flow_indication : IrLAP tells us to send more data.
1000 *
1001 */
1002static void irttp_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
1003{
1004 struct tsap_cb *self;
1005
1006 self = (struct tsap_cb *) instance;
1007
1008 IRDA_ASSERT(self != NULL, return;);
1009 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
1010
1011 IRDA_DEBUG(4, "%s(instance=%p)\n", __FUNCTION__, self);
1012
1013 /* We are "polled" directly from LAP, and the LAP want to fill
1014 * its Tx window. We want to do our best to send it data, so that
1015 * we maximise the window. On the other hand, we want to limit the
1016 * amount of work here so that LAP doesn't hang forever waiting
1017 * for packets. - Jean II */
1018
1019 /* Try to send some packets. Currently, LAP calls us every time
1020 * there is one free slot, so we will send only one packet.
1021 * This allow the scheduler to do its round robin - Jean II */
1022 irttp_run_tx_queue(self);
1023
1024 /* Note regarding the interraction with higher layer.
1025 * irttp_run_tx_queue() may call the client when its queue
1026 * start to empty, via notify.flow_indication(). Initially.
1027 * I wanted this to happen in a tasklet, to avoid client
1028 * grabbing the CPU, but we can't use tasklets safely. And timer
1029 * is definitely too slow.
1030 * This will happen only once per LAP window, and usually at
1031 * the third packet (unless window is smaller). LAP is still
1032 * doing mtt and sending first packet so it's sort of OK
1033 * to do that. Jean II */
1034
1035 /* If we need to send disconnect. try to do it now */
1036 if(self->disconnect_pend)
1037 irttp_start_todo_timer(self, 0);
1038}
1039
1040/*
1041 * Function irttp_flow_request (self, command)
1042 *
1043 * This function could be used by the upper layers to tell IrTTP to stop
1044 * delivering frames if the receive queues are starting to get full, or
1045 * to tell IrTTP to start delivering frames again.
1046 */
1047void irttp_flow_request(struct tsap_cb *self, LOCAL_FLOW flow)
1048{
1049 IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
1050
1051 IRDA_ASSERT(self != NULL, return;);
1052 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
1053
1054 switch (flow) {
1055 case FLOW_STOP:
1056 IRDA_DEBUG(1, "%s(), flow stop\n", __FUNCTION__);
1057 self->rx_sdu_busy = TRUE;
1058 break;
1059 case FLOW_START:
1060 IRDA_DEBUG(1, "%s(), flow start\n", __FUNCTION__);
1061 self->rx_sdu_busy = FALSE;
1062
1063 /* Client say he can accept more data, try to free our
1064 * queues ASAP - Jean II */
1065 irttp_run_rx_queue(self);
1066
1067 break;
1068 default:
1069 IRDA_DEBUG(1, "%s(), Unknown flow command!\n", __FUNCTION__);
1070 }
1071}
1072EXPORT_SYMBOL(irttp_flow_request);
1073
1074/*
1075 * Function irttp_connect_request (self, dtsap_sel, daddr, qos)
1076 *
1077 * Try to connect to remote destination TSAP selector
1078 *
1079 */
1080int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
1081 __u32 saddr, __u32 daddr,
1082 struct qos_info *qos, __u32 max_sdu_size,
1083 struct sk_buff *userdata)
1084{
1085 struct sk_buff *tx_skb;
1086 __u8 *frame;
1087 __u8 n;
1088
1089 IRDA_DEBUG(4, "%s(), max_sdu_size=%d\n", __FUNCTION__, max_sdu_size);
1090
1091 IRDA_ASSERT(self != NULL, return -EBADR;);
1092 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return -EBADR;);
1093
1094 if (self->connected) {
1095 if(userdata)
1096 dev_kfree_skb(userdata);
1097 return -EISCONN;
1098 }
1099
1100 /* Any userdata supplied? */
1101 if (userdata == NULL) {
1102 tx_skb = dev_alloc_skb(64);
1103 if (!tx_skb)
1104 return -ENOMEM;
1105
1106 /* Reserve space for MUX_CONTROL and LAP header */
1107 skb_reserve(tx_skb, TTP_MAX_HEADER);
1108 } else {
1109 tx_skb = userdata;
1110 /*
1111 * Check that the client has reserved enough space for
1112 * headers
1113 */
1114 IRDA_ASSERT(skb_headroom(userdata) >= TTP_MAX_HEADER,
1115 { dev_kfree_skb(userdata); return -1; } );
1116 }
1117
1118 /* Initialize connection parameters */
1119 self->connected = FALSE;
1120 self->avail_credit = 0;
1121 self->rx_max_sdu_size = max_sdu_size;
1122 self->rx_sdu_size = 0;
1123 self->rx_sdu_busy = FALSE;
1124 self->dtsap_sel = dtsap_sel;
1125
1126 n = self->initial_credit;
1127
1128 self->remote_credit = 0;
1129 self->send_credit = 0;
1130
1131 /*
1132 * Give away max 127 credits for now
1133 */
1134 if (n > 127) {
1135 self->avail_credit=n-127;
1136 n = 127;
1137 }
1138
1139 self->remote_credit = n;
1140
1141 /* SAR enabled? */
1142 if (max_sdu_size > 0) {
1143 IRDA_ASSERT(skb_headroom(tx_skb) >= (TTP_MAX_HEADER + TTP_SAR_HEADER),
1144 { dev_kfree_skb(tx_skb); return -1; } );
1145
1146 /* Insert SAR parameters */
1147 frame = skb_push(tx_skb, TTP_HEADER+TTP_SAR_HEADER);
1148
1149 frame[0] = TTP_PARAMETERS | n;
1150 frame[1] = 0x04; /* Length */
1151 frame[2] = 0x01; /* MaxSduSize */
1152 frame[3] = 0x02; /* Value length */
1153
1154 put_unaligned(cpu_to_be16((__u16) max_sdu_size),
1155 (__u16 *)(frame+4));
1156 } else {
1157 /* Insert plain TTP header */
1158 frame = skb_push(tx_skb, TTP_HEADER);
1159
1160 /* Insert initial credit in frame */
1161 frame[0] = n & 0x7f;
1162 }
1163
1164 /* Connect with IrLMP. No QoS parameters for now */
1165 return irlmp_connect_request(self->lsap, dtsap_sel, saddr, daddr, qos,
1166 tx_skb);
1167}
1168EXPORT_SYMBOL(irttp_connect_request);
1169
1170/*
1171 * Function irttp_connect_confirm (handle, qos, skb)
1172 *
1173 * Sevice user confirms TSAP connection with peer.
1174 *
1175 */
1176static void irttp_connect_confirm(void *instance, void *sap,
1177 struct qos_info *qos, __u32 max_seg_size,
1178 __u8 max_header_size, struct sk_buff *skb)
1179{
1180 struct tsap_cb *self;
1181 int parameters;
1182 int ret;
1183 __u8 plen;
1184 __u8 n;
1185
1186 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1187
1188 self = (struct tsap_cb *) instance;
1189
1190 IRDA_ASSERT(self != NULL, return;);
1191 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
1192 IRDA_ASSERT(skb != NULL, return;);
1193
1194 self->max_seg_size = max_seg_size - TTP_HEADER;
1195 self->max_header_size = max_header_size + TTP_HEADER;
1196
1197 /*
1198 * Check if we have got some QoS parameters back! This should be the
1199 * negotiated QoS for the link.
1200 */
1201 if (qos) {
1202 IRDA_DEBUG(4, "IrTTP, Negotiated BAUD_RATE: %02x\n",
1203 qos->baud_rate.bits);
1204 IRDA_DEBUG(4, "IrTTP, Negotiated BAUD_RATE: %d bps.\n",
1205 qos->baud_rate.value);
1206 }
1207
1208 n = skb->data[0] & 0x7f;
1209
1210 IRDA_DEBUG(4, "%s(), Initial send_credit=%d\n", __FUNCTION__, n);
1211
1212 self->send_credit = n;
1213 self->tx_max_sdu_size = 0;
1214 self->connected = TRUE;
1215
1216 parameters = skb->data[0] & 0x80;
1217
1218 IRDA_ASSERT(skb->len >= TTP_HEADER, return;);
1219 skb_pull(skb, TTP_HEADER);
1220
1221 if (parameters) {
1222 plen = skb->data[0];
1223
1224 ret = irda_param_extract_all(self, skb->data+1,
1225 IRDA_MIN(skb->len-1, plen),
1226 &param_info);
1227
1228 /* Any errors in the parameter list? */
1229 if (ret < 0) {
1230 IRDA_WARNING("%s: error extracting parameters\n",
1231 __FUNCTION__);
1232 dev_kfree_skb(skb);
1233
1234 /* Do not accept this connection attempt */
1235 return;
1236 }
1237 /* Remove parameters */
1238 skb_pull(skb, IRDA_MIN(skb->len, plen+1));
1239 }
1240
1241 IRDA_DEBUG(4, "%s() send=%d,avail=%d,remote=%d\n", __FUNCTION__,
1242 self->send_credit, self->avail_credit, self->remote_credit);
1243
1244 IRDA_DEBUG(2, "%s(), MaxSduSize=%d\n", __FUNCTION__,
1245 self->tx_max_sdu_size);
1246
1247 if (self->notify.connect_confirm) {
1248 self->notify.connect_confirm(self->notify.instance, self, qos,
1249 self->tx_max_sdu_size,
1250 self->max_header_size, skb);
1251 } else
1252 dev_kfree_skb(skb);
1253}
1254
1255/*
1256 * Function irttp_connect_indication (handle, skb)
1257 *
1258 * Some other device is connecting to this TSAP
1259 *
1260 */
1261void irttp_connect_indication(void *instance, void *sap, struct qos_info *qos,
1262 __u32 max_seg_size, __u8 max_header_size,
1263 struct sk_buff *skb)
1264{
1265 struct tsap_cb *self;
1266 struct lsap_cb *lsap;
1267 int parameters;
1268 int ret;
1269 __u8 plen;
1270 __u8 n;
1271
1272 self = (struct tsap_cb *) instance;
1273
1274 IRDA_ASSERT(self != NULL, return;);
1275 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
1276 IRDA_ASSERT(skb != NULL, return;);
1277
1278 lsap = (struct lsap_cb *) sap;
1279
1280 self->max_seg_size = max_seg_size - TTP_HEADER;
1281 self->max_header_size = max_header_size+TTP_HEADER;
1282
1283 IRDA_DEBUG(4, "%s(), TSAP sel=%02x\n", __FUNCTION__, self->stsap_sel);
1284
1285 /* Need to update dtsap_sel if its equal to LSAP_ANY */
1286 self->dtsap_sel = lsap->dlsap_sel;
1287
1288 n = skb->data[0] & 0x7f;
1289
1290 self->send_credit = n;
1291 self->tx_max_sdu_size = 0;
1292
1293 parameters = skb->data[0] & 0x80;
1294
1295 IRDA_ASSERT(skb->len >= TTP_HEADER, return;);
1296 skb_pull(skb, TTP_HEADER);
1297
1298 if (parameters) {
1299 plen = skb->data[0];
1300
1301 ret = irda_param_extract_all(self, skb->data+1,
1302 IRDA_MIN(skb->len-1, plen),
1303 &param_info);
1304
1305 /* Any errors in the parameter list? */
1306 if (ret < 0) {
1307 IRDA_WARNING("%s: error extracting parameters\n",
1308 __FUNCTION__);
1309 dev_kfree_skb(skb);
1310
1311 /* Do not accept this connection attempt */
1312 return;
1313 }
1314
1315 /* Remove parameters */
1316 skb_pull(skb, IRDA_MIN(skb->len, plen+1));
1317 }
1318
1319 if (self->notify.connect_indication) {
1320 self->notify.connect_indication(self->notify.instance, self,
1321 qos, self->tx_max_sdu_size,
1322 self->max_header_size, skb);
1323 } else
1324 dev_kfree_skb(skb);
1325}
1326
1327/*
1328 * Function irttp_connect_response (handle, userdata)
1329 *
1330 * Service user is accepting the connection, just pass it down to
1331 * IrLMP!
1332 *
1333 */
1334int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
1335 struct sk_buff *userdata)
1336{
1337 struct sk_buff *tx_skb;
1338 __u8 *frame;
1339 int ret;
1340 __u8 n;
1341
1342 IRDA_ASSERT(self != NULL, return -1;);
1343 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
1344
1345 IRDA_DEBUG(4, "%s(), Source TSAP selector=%02x\n", __FUNCTION__,
1346 self->stsap_sel);
1347
1348 /* Any userdata supplied? */
1349 if (userdata == NULL) {
1350 tx_skb = dev_alloc_skb(64);
1351 if (!tx_skb)
1352 return -ENOMEM;
1353
1354 /* Reserve space for MUX_CONTROL and LAP header */
1355 skb_reserve(tx_skb, TTP_MAX_HEADER);
1356 } else {
1357 tx_skb = userdata;
1358 /*
1359 * Check that the client has reserved enough space for
1360 * headers
1361 */
1362 IRDA_ASSERT(skb_headroom(userdata) >= TTP_MAX_HEADER,
1363 { dev_kfree_skb(userdata); return -1; } );
1364 }
1365
1366 self->avail_credit = 0;
1367 self->remote_credit = 0;
1368 self->rx_max_sdu_size = max_sdu_size;
1369 self->rx_sdu_size = 0;
1370 self->rx_sdu_busy = FALSE;
1371
1372 n = self->initial_credit;
1373
1374 /* Frame has only space for max 127 credits (7 bits) */
1375 if (n > 127) {
1376 self->avail_credit = n - 127;
1377 n = 127;
1378 }
1379
1380 self->remote_credit = n;
1381 self->connected = TRUE;
1382
1383 /* SAR enabled? */
1384 if (max_sdu_size > 0) {
1385 IRDA_ASSERT(skb_headroom(tx_skb) >= (TTP_MAX_HEADER + TTP_SAR_HEADER),
1386 { dev_kfree_skb(tx_skb); return -1; } );
1387
1388 /* Insert TTP header with SAR parameters */
1389 frame = skb_push(tx_skb, TTP_HEADER+TTP_SAR_HEADER);
1390
1391 frame[0] = TTP_PARAMETERS | n;
1392 frame[1] = 0x04; /* Length */
1393
1394 /* irda_param_insert(self, IRTTP_MAX_SDU_SIZE, frame+1, */
1395/* TTP_SAR_HEADER, &param_info) */
1396
1397 frame[2] = 0x01; /* MaxSduSize */
1398 frame[3] = 0x02; /* Value length */
1399
1400 put_unaligned(cpu_to_be16((__u16) max_sdu_size),
1401 (__u16 *)(frame+4));
1402 } else {
1403 /* Insert TTP header */
1404 frame = skb_push(tx_skb, TTP_HEADER);
1405
1406 frame[0] = n & 0x7f;
1407 }
1408
1409 ret = irlmp_connect_response(self->lsap, tx_skb);
1410
1411 return ret;
1412}
1413EXPORT_SYMBOL(irttp_connect_response);
1414
1415/*
1416 * Function irttp_dup (self, instance)
1417 *
1418 * Duplicate TSAP, can be used by servers to confirm a connection on a
1419 * new TSAP so it can keep listening on the old one.
1420 */
1421struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance)
1422{
1423 struct tsap_cb *new;
1424 unsigned long flags;
1425
1426 IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
1427
1428 /* Protect our access to the old tsap instance */
1429 spin_lock_irqsave(&irttp->tsaps->hb_spinlock, flags);
1430
1431 /* Find the old instance */
1432 if (!hashbin_find(irttp->tsaps, (long) orig, NULL)) {
1433 IRDA_DEBUG(0, "%s(), unable to find TSAP\n", __FUNCTION__);
1434 spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, flags);
1435 return NULL;
1436 }
1437
1438 /* Allocate a new instance */
1439 new = kmalloc(sizeof(struct tsap_cb), GFP_ATOMIC);
1440 if (!new) {
1441 IRDA_DEBUG(0, "%s(), unable to kmalloc\n", __FUNCTION__);
1442 spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, flags);
1443 return NULL;
1444 }
1445 /* Dup */
1446 memcpy(new, orig, sizeof(struct tsap_cb));
1447
1448 /* We don't need the old instance any more */
1449 spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, flags);
1450
1451 /* Try to dup the LSAP (may fail if we were too slow) */
1452 new->lsap = irlmp_dup(orig->lsap, new);
1453 if (!new->lsap) {
1454 IRDA_DEBUG(0, "%s(), dup failed!\n", __FUNCTION__);
1455 kfree(new);
1456 return NULL;
1457 }
1458
1459 /* Not everything should be copied */
1460 new->notify.instance = instance;
1461 init_timer(&new->todo_timer);
1462
1463 skb_queue_head_init(&new->rx_queue);
1464 skb_queue_head_init(&new->tx_queue);
1465 skb_queue_head_init(&new->rx_fragments);
1466
1467 /* This is locked */
1468 hashbin_insert(irttp->tsaps, (irda_queue_t *) new, (long) new, NULL);
1469
1470 return new;
1471}
1472EXPORT_SYMBOL(irttp_dup);
1473
1474/*
1475 * Function irttp_disconnect_request (self)
1476 *
1477 * Close this connection please! If priority is high, the queued data
1478 * segments, if any, will be deallocated first
1479 *
1480 */
1481int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *userdata,
1482 int priority)
1483{
1484 int ret;
1485
1486 IRDA_ASSERT(self != NULL, return -1;);
1487 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
1488
1489 /* Already disconnected? */
1490 if (!self->connected) {
1491 IRDA_DEBUG(4, "%s(), already disconnected!\n", __FUNCTION__);
1492 if (userdata)
1493 dev_kfree_skb(userdata);
1494 return -1;
1495 }
1496
1497 /* Disconnect already pending ?
1498 * We need to use an atomic operation to prevent reentry. This
1499 * function may be called from various context, like user, timer
1500 * for following a disconnect_indication() (i.e. net_bh).
1501 * Jean II */
1502 if(test_and_set_bit(0, &self->disconnect_pend)) {
1503 IRDA_DEBUG(0, "%s(), disconnect already pending\n",
1504 __FUNCTION__);
1505 if (userdata)
1506 dev_kfree_skb(userdata);
1507
1508 /* Try to make some progress */
1509 irttp_run_tx_queue(self);
1510 return -1;
1511 }
1512
1513 /*
1514 * Check if there is still data segments in the transmit queue
1515 */
1516 if (skb_queue_len(&self->tx_queue) > 0) {
1517 if (priority == P_HIGH) {
1518 /*
1519 * No need to send the queued data, if we are
1520 * disconnecting right now since the data will
1521 * not have any usable connection to be sent on
1522 */
1523 IRDA_DEBUG(1, "%s(): High priority!!()\n", __FUNCTION__);
1524 irttp_flush_queues(self);
1525 } else if (priority == P_NORMAL) {
1526 /*
1527 * Must delay disconnect until after all data segments
1528 * have been sent and the tx_queue is empty
1529 */
1530 /* We'll reuse this one later for the disconnect */
1531 self->disconnect_skb = userdata; /* May be NULL */
1532
1533 irttp_run_tx_queue(self);
1534
1535 irttp_start_todo_timer(self, HZ/10);
1536 return -1;
1537 }
1538 }
1539 /* Note : we don't need to check if self->rx_queue is full and the
1540 * state of self->rx_sdu_busy because the disconnect response will
1541 * be sent at the LMP level (so even if the peer has its Tx queue
1542 * full of data). - Jean II */
1543
1544 IRDA_DEBUG(1, "%s(), Disconnecting ...\n", __FUNCTION__);
1545 self->connected = FALSE;
1546
1547 if (!userdata) {
1548 struct sk_buff *tx_skb;
1549 tx_skb = dev_alloc_skb(64);
1550 if (!tx_skb)
1551 return -ENOMEM;
1552
1553 /*
1554 * Reserve space for MUX and LAP header
1555 */
1556 skb_reserve(tx_skb, TTP_MAX_HEADER);
1557
1558 userdata = tx_skb;
1559 }
1560 ret = irlmp_disconnect_request(self->lsap, userdata);
1561
1562 /* The disconnect is no longer pending */
1563 clear_bit(0, &self->disconnect_pend); /* FALSE */
1564
1565 return ret;
1566}
1567EXPORT_SYMBOL(irttp_disconnect_request);
1568
1569/*
1570 * Function irttp_disconnect_indication (self, reason)
1571 *
1572 * Disconnect indication, TSAP disconnected by peer?
1573 *
1574 */
1575void irttp_disconnect_indication(void *instance, void *sap, LM_REASON reason,
1576 struct sk_buff *skb)
1577{
1578 struct tsap_cb *self;
1579
1580 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1581
1582 self = (struct tsap_cb *) instance;
1583
1584 IRDA_ASSERT(self != NULL, return;);
1585 IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
1586
1587 /* Prevent higher layer to send more data */
1588 self->connected = FALSE;
1589
1590 /* Check if client has already tried to close the TSAP */
1591 if (self->close_pend) {
1592 /* In this case, the higher layer is probably gone. Don't
1593 * bother it and clean up the remains - Jean II */
1594 if (skb)
1595 dev_kfree_skb(skb);
1596 irttp_close_tsap(self);
1597 return;
1598 }
1599
1600 /* If we are here, we assume that is the higher layer is still
1601 * waiting for the disconnect notification and able to process it,
1602 * even if he tried to disconnect. Otherwise, it would have already
1603 * attempted to close the tsap and self->close_pend would be TRUE.
1604 * Jean II */
1605
1606 /* No need to notify the client if has already tried to disconnect */
1607 if(self->notify.disconnect_indication)
1608 self->notify.disconnect_indication(self->notify.instance, self,
1609 reason, skb);
1610 else
1611 if (skb)
1612 dev_kfree_skb(skb);
1613}
1614
1615/*
1616 * Function irttp_do_data_indication (self, skb)
1617 *
1618 * Try to deliver reassembled skb to layer above, and requeue it if that
1619 * for some reason should fail. We mark rx sdu as busy to apply back
1620 * pressure is necessary.
1621 */
1622static void irttp_do_data_indication(struct tsap_cb *self, struct sk_buff *skb)
1623{
1624 int err;
1625
1626 /* Check if client has already closed the TSAP and gone away */
1627 if (self->close_pend) {
1628 dev_kfree_skb(skb);
1629 return;
1630 }
1631
1632 err = self->notify.data_indication(self->notify.instance, self, skb);
1633
1634 /* Usually the layer above will notify that it's input queue is
1635 * starting to get filled by using the flow request, but this may
1636 * be difficult, so it can instead just refuse to eat it and just
1637 * give an error back
1638 */
1639 if (err) {
1640 IRDA_DEBUG(0, "%s() requeueing skb!\n", __FUNCTION__);
1641
1642 /* Make sure we take a break */
1643 self->rx_sdu_busy = TRUE;
1644
1645 /* Need to push the header in again */
1646 skb_push(skb, TTP_HEADER);
1647 skb->data[0] = 0x00; /* Make sure MORE bit is cleared */
1648
1649 /* Put skb back on queue */
1650 skb_queue_head(&self->rx_queue, skb);
1651 }
1652}
1653
1654/*
1655 * Function irttp_run_rx_queue (self)
1656 *
1657 * Check if we have any frames to be transmitted, or if we have any
1658 * available credit to give away.
1659 */
1660void irttp_run_rx_queue(struct tsap_cb *self)
1661{
1662 struct sk_buff *skb;
1663 int more = 0;
1664
1665 IRDA_DEBUG(2, "%s() send=%d,avail=%d,remote=%d\n", __FUNCTION__,
1666 self->send_credit, self->avail_credit, self->remote_credit);
1667
1668 /* Get exclusive access to the rx queue, otherwise don't touch it */
1669 if (irda_lock(&self->rx_queue_lock) == FALSE)
1670 return;
1671
1672 /*
1673 * Reassemble all frames in receive queue and deliver them
1674 */
1675 while (!self->rx_sdu_busy && (skb = skb_dequeue(&self->rx_queue))) {
1676 /* This bit will tell us if it's the last fragment or not */
1677 more = skb->data[0] & 0x80;
1678
1679 /* Remove TTP header */
1680 skb_pull(skb, TTP_HEADER);
1681
1682 /* Add the length of the remaining data */
1683 self->rx_sdu_size += skb->len;
1684
1685 /*
1686 * If SAR is disabled, or user has requested no reassembly
1687 * of received fragments then we just deliver them
1688 * immediately. This can be requested by clients that
1689 * implements byte streams without any message boundaries
1690 */
1691 if (self->rx_max_sdu_size == TTP_SAR_DISABLE) {
1692 irttp_do_data_indication(self, skb);
1693 self->rx_sdu_size = 0;
1694
1695 continue;
1696 }
1697
1698 /* Check if this is a fragment, and not the last fragment */
1699 if (more) {
1700 /*
1701 * Queue the fragment if we still are within the
1702 * limits of the maximum size of the rx_sdu
1703 */
1704 if (self->rx_sdu_size <= self->rx_max_sdu_size) {
1705 IRDA_DEBUG(4, "%s(), queueing frag\n",
1706 __FUNCTION__);
1707 skb_queue_tail(&self->rx_fragments, skb);
1708 } else {
1709 /* Free the part of the SDU that is too big */
1710 dev_kfree_skb(skb);
1711 }
1712 continue;
1713 }
1714 /*
1715 * This is the last fragment, so time to reassemble!
1716 */
1717 if ((self->rx_sdu_size <= self->rx_max_sdu_size) ||
1718 (self->rx_max_sdu_size == TTP_SAR_UNBOUND))
1719 {
1720 /*
1721 * A little optimizing. Only queue the fragment if
1722 * there are other fragments. Since if this is the
1723 * last and only fragment, there is no need to
1724 * reassemble :-)
1725 */
1726 if (!skb_queue_empty(&self->rx_fragments)) {
1727 skb_queue_tail(&self->rx_fragments,
1728 skb);
1729
1730 skb = irttp_reassemble_skb(self);
1731 }
1732
1733 /* Now we can deliver the reassembled skb */
1734 irttp_do_data_indication(self, skb);
1735 } else {
1736 IRDA_DEBUG(1, "%s(), Truncated frame\n", __FUNCTION__);
1737
1738 /* Free the part of the SDU that is too big */
1739 dev_kfree_skb(skb);
1740
1741 /* Deliver only the valid but truncated part of SDU */
1742 skb = irttp_reassemble_skb(self);
1743
1744 irttp_do_data_indication(self, skb);
1745 }
1746 self->rx_sdu_size = 0;
1747 }
1748
1749 /*
1750 * It's not trivial to keep track of how many credits are available
1751 * by incrementing at each packet, because delivery may fail
1752 * (irttp_do_data_indication() may requeue the frame) and because
1753 * we need to take care of fragmentation.
1754 * We want the other side to send up to initial_credit packets.
1755 * We have some frames in our queues, and we have already allowed it
1756 * to send remote_credit.
1757 * No need to spinlock, write is atomic and self correcting...
1758 * Jean II
1759 */
1760 self->avail_credit = (self->initial_credit -
1761 (self->remote_credit +
1762 skb_queue_len(&self->rx_queue) +
1763 skb_queue_len(&self->rx_fragments)));
1764
1765 /* Do we have too much credits to send to peer ? */
1766 if ((self->remote_credit <= TTP_RX_MIN_CREDIT) &&
1767 (self->avail_credit > 0)) {
1768 /* Send explicit credit frame */
1769 irttp_give_credit(self);
1770 /* Note : do *NOT* check if tx_queue is non-empty, that
1771 * will produce deadlocks. I repeat : send a credit frame
1772 * even if we have something to send in our Tx queue.
1773 * If we have credits, it means that our Tx queue is blocked.
1774 *
1775 * Let's suppose the peer can't keep up with our Tx. He will
1776 * flow control us by not sending us any credits, and we
1777 * will stop Tx and start accumulating credits here.
1778 * Up to the point where the peer will stop its Tx queue,
1779 * for lack of credits.
1780 * Let's assume the peer application is single threaded.
1781 * It will block on Tx and never consume any Rx buffer.
1782 * Deadlock. Guaranteed. - Jean II
1783 */
1784 }
1785
1786 /* Reset lock */
1787 self->rx_queue_lock = 0;
1788}
1789
1790#ifdef CONFIG_PROC_FS
1791struct irttp_iter_state {
1792 int id;
1793};
1794
1795static void *irttp_seq_start(struct seq_file *seq, loff_t *pos)
1796{
1797 struct irttp_iter_state *iter = seq->private;
1798 struct tsap_cb *self;
1799
1800 /* Protect our access to the tsap list */
1801 spin_lock_irq(&irttp->tsaps->hb_spinlock);
1802 iter->id = 0;
1803
1804 for (self = (struct tsap_cb *) hashbin_get_first(irttp->tsaps);
1805 self != NULL;
1806 self = (struct tsap_cb *) hashbin_get_next(irttp->tsaps)) {
1807 if (iter->id == *pos)
1808 break;
1809 ++iter->id;
1810 }
1811
1812 return self;
1813}
1814
1815static void *irttp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1816{
1817 struct irttp_iter_state *iter = seq->private;
1818
1819 ++*pos;
1820 ++iter->id;
1821 return (void *) hashbin_get_next(irttp->tsaps);
1822}
1823
1824static void irttp_seq_stop(struct seq_file *seq, void *v)
1825{
1826 spin_unlock_irq(&irttp->tsaps->hb_spinlock);
1827}
1828
1829static int irttp_seq_show(struct seq_file *seq, void *v)
1830{
1831 const struct irttp_iter_state *iter = seq->private;
1832 const struct tsap_cb *self = v;
1833
1834 seq_printf(seq, "TSAP %d, ", iter->id);
1835 seq_printf(seq, "stsap_sel: %02x, ",
1836 self->stsap_sel);
1837 seq_printf(seq, "dtsap_sel: %02x\n",
1838 self->dtsap_sel);
1839 seq_printf(seq, " connected: %s, ",
1840 self->connected? "TRUE":"FALSE");
1841 seq_printf(seq, "avail credit: %d, ",
1842 self->avail_credit);
1843 seq_printf(seq, "remote credit: %d, ",
1844 self->remote_credit);
1845 seq_printf(seq, "send credit: %d\n",
1846 self->send_credit);
1847 seq_printf(seq, " tx packets: %ld, ",
1848 self->stats.tx_packets);
1849 seq_printf(seq, "rx packets: %ld, ",
1850 self->stats.rx_packets);
1851 seq_printf(seq, "tx_queue len: %d ",
1852 skb_queue_len(&self->tx_queue));
1853 seq_printf(seq, "rx_queue len: %d\n",
1854 skb_queue_len(&self->rx_queue));
1855 seq_printf(seq, " tx_sdu_busy: %s, ",
1856 self->tx_sdu_busy? "TRUE":"FALSE");
1857 seq_printf(seq, "rx_sdu_busy: %s\n",
1858 self->rx_sdu_busy? "TRUE":"FALSE");
1859 seq_printf(seq, " max_seg_size: %d, ",
1860 self->max_seg_size);
1861 seq_printf(seq, "tx_max_sdu_size: %d, ",
1862 self->tx_max_sdu_size);
1863 seq_printf(seq, "rx_max_sdu_size: %d\n",
1864 self->rx_max_sdu_size);
1865
1866 seq_printf(seq, " Used by (%s)\n\n",
1867 self->notify.name);
1868 return 0;
1869}
1870
1871static struct seq_operations irttp_seq_ops = {
1872 .start = irttp_seq_start,
1873 .next = irttp_seq_next,
1874 .stop = irttp_seq_stop,
1875 .show = irttp_seq_show,
1876};
1877
1878static int irttp_seq_open(struct inode *inode, struct file *file)
1879{
1880 struct seq_file *seq;
1881 int rc = -ENOMEM;
1882 struct irttp_iter_state *s;
1883
1884 IRDA_ASSERT(irttp != NULL, return -EINVAL;);
1885
1886 s = kmalloc(sizeof(*s), GFP_KERNEL);
1887 if (!s)
1888 goto out;
1889
1890 rc = seq_open(file, &irttp_seq_ops);
1891 if (rc)
1892 goto out_kfree;
1893
1894 seq = file->private_data;
1895 seq->private = s;
1896 memset(s, 0, sizeof(*s));
1897out:
1898 return rc;
1899out_kfree:
1900 kfree(s);
1901 goto out;
1902}
1903
1904struct file_operations irttp_seq_fops = {
1905 .owner = THIS_MODULE,
1906 .open = irttp_seq_open,
1907 .read = seq_read,
1908 .llseek = seq_lseek,
1909 .release = seq_release_private,
1910};
1911
1912#endif /* PROC_FS */
diff --git a/net/irda/parameters.c b/net/irda/parameters.c
new file mode 100644
index 00000000000..1324942f976
--- /dev/null
+++ b/net/irda/parameters.c
@@ -0,0 +1,589 @@
1/*********************************************************************
2 *
3 * Filename: parameters.c
4 * Version: 1.0
5 * Description: A more general way to handle (pi,pl,pv) parameters
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Mon Jun 7 10:25:11 1999
9 * Modified at: Sun Jan 30 14:08:39 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 * MA 02111-1307 USA
28 *
29 ********************************************************************/
30
31#include <linux/types.h>
32#include <linux/module.h>
33
34#include <asm/unaligned.h>
35#include <asm/byteorder.h>
36
37#include <net/irda/irda.h>
38#include <net/irda/parameters.h>
39
40static int irda_extract_integer(void *self, __u8 *buf, int len, __u8 pi,
41 PV_TYPE type, PI_HANDLER func);
42static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi,
43 PV_TYPE type, PI_HANDLER func);
44static int irda_extract_octseq(void *self, __u8 *buf, int len, __u8 pi,
45 PV_TYPE type, PI_HANDLER func);
46static int irda_extract_no_value(void *self, __u8 *buf, int len, __u8 pi,
47 PV_TYPE type, PI_HANDLER func);
48
49static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi,
50 PV_TYPE type, PI_HANDLER func);
51static int irda_insert_no_value(void *self, __u8 *buf, int len, __u8 pi,
52 PV_TYPE type, PI_HANDLER func);
53
54static int irda_param_unpack(__u8 *buf, char *fmt, ...);
55
56/* Parameter value call table. Must match PV_TYPE */
57static PV_HANDLER pv_extract_table[] = {
58 irda_extract_integer, /* Handler for any length integers */
59 irda_extract_integer, /* Handler for 8 bits integers */
60 irda_extract_integer, /* Handler for 16 bits integers */
61 irda_extract_string, /* Handler for strings */
62 irda_extract_integer, /* Handler for 32 bits integers */
63 irda_extract_octseq, /* Handler for octet sequences */
64 irda_extract_no_value /* Handler for no value parameters */
65};
66
67static PV_HANDLER pv_insert_table[] = {
68 irda_insert_integer, /* Handler for any length integers */
69 irda_insert_integer, /* Handler for 8 bits integers */
70 irda_insert_integer, /* Handler for 16 bits integers */
71 NULL, /* Handler for strings */
72 irda_insert_integer, /* Handler for 32 bits integers */
73 NULL, /* Handler for octet sequences */
74 irda_insert_no_value /* Handler for no value parameters */
75};
76
77/*
78 * Function irda_insert_no_value (self, buf, len, pi, type, func)
79 */
80static int irda_insert_no_value(void *self, __u8 *buf, int len, __u8 pi,
81 PV_TYPE type, PI_HANDLER func)
82{
83 irda_param_t p;
84 int ret;
85
86 p.pi = pi;
87 p.pl = 0;
88
89 /* Call handler for this parameter */
90 ret = (*func)(self, &p, PV_GET);
91
92 /* Extract values anyway, since handler may need them */
93 irda_param_pack(buf, "bb", p.pi, p.pl);
94
95 if (ret < 0)
96 return ret;
97
98 return 2; /* Inserted pl+2 bytes */
99}
100
101/*
102 * Function irda_extract_no_value (self, buf, len, type, func)
103 *
104 * Extracts a parameter without a pv field (pl=0)
105 *
106 */
107static int irda_extract_no_value(void *self, __u8 *buf, int len, __u8 pi,
108 PV_TYPE type, PI_HANDLER func)
109{
110 irda_param_t p;
111 int ret;
112
113 /* Extract values anyway, since handler may need them */
114 irda_param_unpack(buf, "bb", &p.pi, &p.pl);
115
116 /* Call handler for this parameter */
117 ret = (*func)(self, &p, PV_PUT);
118
119 if (ret < 0)
120 return ret;
121
122 return 2; /* Extracted pl+2 bytes */
123}
124
125/*
126 * Function irda_insert_integer (self, buf, len, pi, type, func)
127 */
128static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi,
129 PV_TYPE type, PI_HANDLER func)
130{
131 irda_param_t p;
132 int n = 0;
133 int err;
134
135 p.pi = pi; /* In case handler needs to know */
136 p.pl = type & PV_MASK; /* The integer type codes the lenght as well */
137 p.pv.i = 0; /* Clear value */
138
139 /* Call handler for this parameter */
140 err = (*func)(self, &p, PV_GET);
141 if (err < 0)
142 return err;
143
144 /*
145 * If parameter lenght is still 0, then (1) this is an any length
146 * integer, and (2) the handler function does not care which length
147 * we choose to use, so we pick the one the gives the fewest bytes.
148 */
149 if (p.pl == 0) {
150 if (p.pv.i < 0xff) {
151 IRDA_DEBUG(2, "%s(), using 1 byte\n", __FUNCTION__);
152 p.pl = 1;
153 } else if (p.pv.i < 0xffff) {
154 IRDA_DEBUG(2, "%s(), using 2 bytes\n", __FUNCTION__);
155 p.pl = 2;
156 } else {
157 IRDA_DEBUG(2, "%s(), using 4 bytes\n", __FUNCTION__);
158 p.pl = 4; /* Default length */
159 }
160 }
161 /* Check if buffer is long enough for insertion */
162 if (len < (2+p.pl)) {
163 IRDA_WARNING("%s: buffer to short for insertion!\n",
164 __FUNCTION__);
165 return -1;
166 }
167 IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d, pi=%d\n", __FUNCTION__,
168 p.pi, p.pl, p.pv.i);
169 switch (p.pl) {
170 case 1:
171 n += irda_param_pack(buf, "bbb", p.pi, p.pl, (__u8) p.pv.i);
172 break;
173 case 2:
174 if (type & PV_BIG_ENDIAN)
175 p.pv.i = cpu_to_be16((__u16) p.pv.i);
176 else
177 p.pv.i = cpu_to_le16((__u16) p.pv.i);
178 n += irda_param_pack(buf, "bbs", p.pi, p.pl, (__u16) p.pv.i);
179 break;
180 case 4:
181 if (type & PV_BIG_ENDIAN)
182 cpu_to_be32s(&p.pv.i);
183 else
184 cpu_to_le32s(&p.pv.i);
185 n += irda_param_pack(buf, "bbi", p.pi, p.pl, p.pv.i);
186
187 break;
188 default:
189 IRDA_WARNING("%s: length %d not supported\n",
190 __FUNCTION__, p.pl);
191 /* Skip parameter */
192 return -1;
193 }
194
195 return p.pl+2; /* Inserted pl+2 bytes */
196}
197
198/*
199 * Function irda_extract integer (self, buf, len, pi, type, func)
200 *
201 * Extract a possibly variable length integer from buffer, and call
202 * handler for processing of the parameter
203 */
204static int irda_extract_integer(void *self, __u8 *buf, int len, __u8 pi,
205 PV_TYPE type, PI_HANDLER func)
206{
207 irda_param_t p;
208 int n = 0;
209 int extract_len; /* Real lenght we extract */
210 int err;
211
212 p.pi = pi; /* In case handler needs to know */
213 p.pl = buf[1]; /* Extract lenght of value */
214 p.pv.i = 0; /* Clear value */
215 extract_len = p.pl; /* Default : extract all */
216
217 /* Check if buffer is long enough for parsing */
218 if (len < (2+p.pl)) {
219 IRDA_WARNING("%s: buffer to short for parsing! "
220 "Need %d bytes, but len is only %d\n",
221 __FUNCTION__, p.pl, len);
222 return -1;
223 }
224
225 /*
226 * Check that the integer length is what we expect it to be. If the
227 * handler want a 16 bits integer then a 32 bits is not good enough
228 * PV_INTEGER means that the handler is flexible.
229 */
230 if (((type & PV_MASK) != PV_INTEGER) && ((type & PV_MASK) != p.pl)) {
231 IRDA_ERROR("%s: invalid parameter length! "
232 "Expected %d bytes, but value had %d bytes!\n",
233 __FUNCTION__, type & PV_MASK, p.pl);
234
235 /* Most parameters are bit/byte fields or little endian,
236 * so it's ok to only extract a subset of it (the subset
237 * that the handler expect). This is necessary, as some
238 * broken implementations seems to add extra undefined bits.
239 * If the parameter is shorter than we expect or is big
240 * endian, we can't play those tricks. Jean II */
241 if((p.pl < (type & PV_MASK)) || (type & PV_BIG_ENDIAN)) {
242 /* Skip parameter */
243 return p.pl+2;
244 } else {
245 /* Extract subset of it, fallthrough */
246 extract_len = type & PV_MASK;
247 }
248 }
249
250
251 switch (extract_len) {
252 case 1:
253 n += irda_param_unpack(buf+2, "b", &p.pv.i);
254 break;
255 case 2:
256 n += irda_param_unpack(buf+2, "s", &p.pv.i);
257 if (type & PV_BIG_ENDIAN)
258 p.pv.i = be16_to_cpu((__u16) p.pv.i);
259 else
260 p.pv.i = le16_to_cpu((__u16) p.pv.i);
261 break;
262 case 4:
263 n += irda_param_unpack(buf+2, "i", &p.pv.i);
264 if (type & PV_BIG_ENDIAN)
265 be32_to_cpus(&p.pv.i);
266 else
267 le32_to_cpus(&p.pv.i);
268 break;
269 default:
270 IRDA_WARNING("%s: length %d not supported\n",
271 __FUNCTION__, p.pl);
272
273 /* Skip parameter */
274 return p.pl+2;
275 }
276
277 IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d, pi=%d\n", __FUNCTION__,
278 p.pi, p.pl, p.pv.i);
279 /* Call handler for this parameter */
280 err = (*func)(self, &p, PV_PUT);
281 if (err < 0)
282 return err;
283
284 return p.pl+2; /* Extracted pl+2 bytes */
285}
286
287/*
288 * Function irda_extract_string (self, buf, len, type, func)
289 */
290static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi,
291 PV_TYPE type, PI_HANDLER func)
292{
293 char str[33];
294 irda_param_t p;
295 int err;
296
297 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
298
299 p.pi = pi; /* In case handler needs to know */
300 p.pl = buf[1]; /* Extract lenght of value */
301
302 IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d\n", __FUNCTION__,
303 p.pi, p.pl);
304
305 /* Check if buffer is long enough for parsing */
306 if (len < (2+p.pl)) {
307 IRDA_WARNING("%s: buffer to short for parsing! "
308 "Need %d bytes, but len is only %d\n",
309 __FUNCTION__, p.pl, len);
310 return -1;
311 }
312
313 /* Should be safe to copy string like this since we have already
314 * checked that the buffer is long enough */
315 strncpy(str, buf+2, p.pl);
316
317 IRDA_DEBUG(2, "%s(), str=0x%02x 0x%02x\n", __FUNCTION__,
318 (__u8) str[0], (__u8) str[1]);
319
320 /* Null terminate string */
321 str[p.pl+1] = '\0';
322
323 p.pv.c = str; /* Handler will need to take a copy */
324
325 /* Call handler for this parameter */
326 err = (*func)(self, &p, PV_PUT);
327 if (err < 0)
328 return err;
329
330 return p.pl+2; /* Extracted pl+2 bytes */
331}
332
333/*
334 * Function irda_extract_octseq (self, buf, len, type, func)
335 */
336static int irda_extract_octseq(void *self, __u8 *buf, int len, __u8 pi,
337 PV_TYPE type, PI_HANDLER func)
338{
339 irda_param_t p;
340
341 p.pi = pi; /* In case handler needs to know */
342 p.pl = buf[1]; /* Extract lenght of value */
343
344 /* Check if buffer is long enough for parsing */
345 if (len < (2+p.pl)) {
346 IRDA_WARNING("%s: buffer to short for parsing! "
347 "Need %d bytes, but len is only %d\n",
348 __FUNCTION__, p.pl, len);
349 return -1;
350 }
351
352 IRDA_DEBUG(0, "%s(), not impl\n", __FUNCTION__);
353
354 return p.pl+2; /* Extracted pl+2 bytes */
355}
356
357/*
358 * Function irda_param_pack (skb, fmt, ...)
359 *
360 * Format:
361 * 'i' = 32 bits integer
362 * 's' = string
363 *
364 */
365int irda_param_pack(__u8 *buf, char *fmt, ...)
366{
367 irda_pv_t arg;
368 va_list args;
369 char *p;
370 int n = 0;
371
372 va_start(args, fmt);
373
374 for (p = fmt; *p != '\0'; p++) {
375 switch (*p) {
376 case 'b': /* 8 bits unsigned byte */
377 buf[n++] = (__u8)va_arg(args, int);
378 break;
379 case 's': /* 16 bits unsigned short */
380 arg.i = (__u16)va_arg(args, int);
381 put_unaligned((__u16)arg.i, (__u16 *)(buf+n)); n+=2;
382 break;
383 case 'i': /* 32 bits unsigned integer */
384 arg.i = va_arg(args, __u32);
385 put_unaligned(arg.i, (__u32 *)(buf+n)); n+=4;
386 break;
387#if 0
388 case 'c': /* \0 terminated string */
389 arg.c = va_arg(args, char *);
390 strcpy(buf+n, arg.c);
391 n += strlen(arg.c) + 1;
392 break;
393#endif
394 default:
395 va_end(args);
396 return -1;
397 }
398 }
399 va_end(args);
400
401 return 0;
402}
403EXPORT_SYMBOL(irda_param_pack);
404
405/*
406 * Function irda_param_unpack (skb, fmt, ...)
407 */
408static int irda_param_unpack(__u8 *buf, char *fmt, ...)
409{
410 irda_pv_t arg;
411 va_list args;
412 char *p;
413 int n = 0;
414
415 va_start(args, fmt);
416
417 for (p = fmt; *p != '\0'; p++) {
418 switch (*p) {
419 case 'b': /* 8 bits byte */
420 arg.ip = va_arg(args, __u32 *);
421 *arg.ip = buf[n++];
422 break;
423 case 's': /* 16 bits short */
424 arg.ip = va_arg(args, __u32 *);
425 *arg.ip = get_unaligned((__u16 *)(buf+n)); n+=2;
426 break;
427 case 'i': /* 32 bits unsigned integer */
428 arg.ip = va_arg(args, __u32 *);
429 *arg.ip = get_unaligned((__u32 *)(buf+n)); n+=4;
430 break;
431#if 0
432 case 'c': /* \0 terminated string */
433 arg.c = va_arg(args, char *);
434 strcpy(arg.c, buf+n);
435 n += strlen(arg.c) + 1;
436 break;
437#endif
438 default:
439 va_end(args);
440 return -1;
441 }
442
443 }
444 va_end(args);
445
446 return 0;
447}
448
449/*
450 * Function irda_param_insert (self, pi, buf, len, info)
451 *
452 * Insert the specified parameter (pi) into buffer. Returns number of
453 * bytes inserted
454 */
455int irda_param_insert(void *self, __u8 pi, __u8 *buf, int len,
456 pi_param_info_t *info)
457{
458 pi_minor_info_t *pi_minor_info;
459 __u8 pi_minor;
460 __u8 pi_major;
461 int type;
462 int ret = -1;
463 int n = 0;
464
465 IRDA_ASSERT(buf != NULL, return ret;);
466 IRDA_ASSERT(info != 0, return ret;);
467
468 pi_minor = pi & info->pi_mask;
469 pi_major = pi >> info->pi_major_offset;
470
471 /* Check if the identifier value (pi) is valid */
472 if ((pi_major > info->len-1) ||
473 (pi_minor > info->tables[pi_major].len-1))
474 {
475 IRDA_DEBUG(0, "%s(), no handler for parameter=0x%02x\n",
476 __FUNCTION__, pi);
477
478 /* Skip this parameter */
479 return -1;
480 }
481
482 /* Lookup the info on how to parse this parameter */
483 pi_minor_info = &info->tables[pi_major].pi_minor_call_table[pi_minor];
484
485 /* Find expected data type for this parameter identifier (pi)*/
486 type = pi_minor_info->type;
487
488 /* Check if handler has been implemented */
489 if (!pi_minor_info->func) {
490 IRDA_MESSAGE("%s: no handler for pi=%#x\n", __FUNCTION__, pi);
491 /* Skip this parameter */
492 return -1;
493 }
494
495 /* Insert parameter value */
496 ret = (*pv_insert_table[type & PV_MASK])(self, buf+n, len, pi, type,
497 pi_minor_info->func);
498 return ret;
499}
500EXPORT_SYMBOL(irda_param_insert);
501
502/*
503 * Function irda_param_extract (self, buf, len, info)
504 *
505 * Parse all parameters. If len is correct, then everything should be
506 * safe. Returns the number of bytes that was parsed
507 *
508 */
509static int irda_param_extract(void *self, __u8 *buf, int len,
510 pi_param_info_t *info)
511{
512 pi_minor_info_t *pi_minor_info;
513 __u8 pi_minor;
514 __u8 pi_major;
515 int type;
516 int ret = -1;
517 int n = 0;
518
519 IRDA_ASSERT(buf != NULL, return ret;);
520 IRDA_ASSERT(info != 0, return ret;);
521
522 pi_minor = buf[n] & info->pi_mask;
523 pi_major = buf[n] >> info->pi_major_offset;
524
525 /* Check if the identifier value (pi) is valid */
526 if ((pi_major > info->len-1) ||
527 (pi_minor > info->tables[pi_major].len-1))
528 {
529 IRDA_DEBUG(0, "%s(), no handler for parameter=0x%02x\n",
530 __FUNCTION__, buf[0]);
531
532 /* Skip this parameter */
533 return 2 + buf[n + 1]; /* Continue */
534 }
535
536 /* Lookup the info on how to parse this parameter */
537 pi_minor_info = &info->tables[pi_major].pi_minor_call_table[pi_minor];
538
539 /* Find expected data type for this parameter identifier (pi)*/
540 type = pi_minor_info->type;
541
542 IRDA_DEBUG(3, "%s(), pi=[%d,%d], type=%d\n", __FUNCTION__,
543 pi_major, pi_minor, type);
544
545 /* Check if handler has been implemented */
546 if (!pi_minor_info->func) {
547 IRDA_MESSAGE("%s: no handler for pi=%#x\n",
548 __FUNCTION__, buf[n]);
549 /* Skip this parameter */
550 return 2 + buf[n + 1]; /* Continue */
551 }
552
553 /* Parse parameter value */
554 ret = (*pv_extract_table[type & PV_MASK])(self, buf+n, len, buf[n],
555 type, pi_minor_info->func);
556 return ret;
557}
558
559/*
560 * Function irda_param_extract_all (self, buf, len, info)
561 *
562 * Parse all parameters. If len is correct, then everything should be
563 * safe. Returns the number of bytes that was parsed
564 *
565 */
566int irda_param_extract_all(void *self, __u8 *buf, int len,
567 pi_param_info_t *info)
568{
569 int ret = -1;
570 int n = 0;
571
572 IRDA_ASSERT(buf != NULL, return ret;);
573 IRDA_ASSERT(info != 0, return ret;);
574
575 /*
576 * Parse all parameters. Each parameter must be at least two bytes
577 * long or else there is no point in trying to parse it
578 */
579 while (len > 2) {
580 ret = irda_param_extract(self, buf+n, len, info);
581 if (ret < 0)
582 return ret;
583
584 n += ret;
585 len -= ret;
586 }
587 return n;
588}
589EXPORT_SYMBOL(irda_param_extract_all);
diff --git a/net/irda/qos.c b/net/irda/qos.c
new file mode 100644
index 00000000000..df732d56cc5
--- /dev/null
+++ b/net/irda/qos.c
@@ -0,0 +1,774 @@
1/*********************************************************************
2 *
3 * Filename: qos.c
4 * Version: 1.0
5 * Description: IrLAP QoS parameter negotiation
6 * Status: Stable
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Tue Sep 9 00:00:26 1997
9 * Modified at: Sun Jan 30 14:29:16 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
13 * All Rights Reserved.
14 * Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 * MA 02111-1307 USA
30 *
31 ********************************************************************/
32
33#include <linux/config.h>
34#include <asm/byteorder.h>
35
36#include <net/irda/irda.h>
37#include <net/irda/parameters.h>
38#include <net/irda/qos.h>
39#include <net/irda/irlap.h>
40
41/*
42 * Maximum values of the baud rate we negociate with the other end.
43 * Most often, you don't have to change that, because Linux-IrDA will
44 * use the maximum offered by the link layer, which usually works fine.
45 * In some very rare cases, you may want to limit it to lower speeds...
46 */
47int sysctl_max_baud_rate = 16000000;
48/*
49 * Maximum value of the lap disconnect timer we negociate with the other end.
50 * Most often, the value below represent the best compromise, but some user
51 * may want to keep the LAP alive longuer or shorter in case of link failure.
52 * Remember that the threshold time (early warning) is fixed to 3s...
53 */
54int sysctl_max_noreply_time = 12;
55/*
56 * Minimum turn time to be applied before transmitting to the peer.
57 * Nonzero values (usec) are used as lower limit to the per-connection
58 * mtt value which was announced by the other end during negotiation.
59 * Might be helpful if the peer device provides too short mtt.
60 * Default is 10us which means using the unmodified value given by the
61 * peer except if it's 0 (0 is likely a bug in the other stack).
62 */
63unsigned sysctl_min_tx_turn_time = 10;
64/*
65 * Maximum data size to be used in transmission in payload of LAP frame.
66 * There is a bit of confusion in the IrDA spec :
67 * The LAP spec defines the payload of a LAP frame (I field) to be
68 * 2048 bytes max (IrLAP 1.1, chapt 6.6.5, p40).
69 * On the other hand, the PHY mention frames of 2048 bytes max (IrPHY
70 * 1.2, chapt 5.3.2.1, p41). But, this number includes the LAP header
71 * (2 bytes), and CRC (32 bits at 4 Mb/s). So, for the I field (LAP
72 * payload), that's only 2042 bytes. Oups !
73 * My nsc-ircc hardware has troubles receiving 2048 bytes frames at 4 Mb/s,
74 * so adjust to 2042... I don't know if this bug applies only for 2048
75 * bytes frames or all negotiated frame sizes, but you can use the sysctl
76 * to play with this value anyway.
77 * Jean II */
78unsigned sysctl_max_tx_data_size = 2042;
79/*
80 * Maximum transmit window, i.e. number of LAP frames between turn-around.
81 * This allow to override what the peer told us. Some peers are buggy and
82 * don't always support what they tell us.
83 * Jean II */
84unsigned sysctl_max_tx_window = 7;
85
86static int irlap_param_baud_rate(void *instance, irda_param_t *param, int get);
87static int irlap_param_link_disconnect(void *instance, irda_param_t *parm,
88 int get);
89static int irlap_param_max_turn_time(void *instance, irda_param_t *param,
90 int get);
91static int irlap_param_data_size(void *instance, irda_param_t *param, int get);
92static int irlap_param_window_size(void *instance, irda_param_t *param,
93 int get);
94static int irlap_param_additional_bofs(void *instance, irda_param_t *parm,
95 int get);
96static int irlap_param_min_turn_time(void *instance, irda_param_t *param,
97 int get);
98
99#ifndef CONFIG_IRDA_DYNAMIC_WINDOW
100static __u32 irlap_requested_line_capacity(struct qos_info *qos);
101#endif
102
103static __u32 min_turn_times[] = { 10000, 5000, 1000, 500, 100, 50, 10, 0 }; /* us */
104static __u32 baud_rates[] = { 2400, 9600, 19200, 38400, 57600, 115200, 576000,
105 1152000, 4000000, 16000000 }; /* bps */
106static __u32 data_sizes[] = { 64, 128, 256, 512, 1024, 2048 }; /* bytes */
107static __u32 add_bofs[] = { 48, 24, 12, 5, 3, 2, 1, 0 }; /* bytes */
108static __u32 max_turn_times[] = { 500, 250, 100, 50 }; /* ms */
109static __u32 link_disc_times[] = { 3, 8, 12, 16, 20, 25, 30, 40 }; /* secs */
110
111static __u32 max_line_capacities[10][4] = {
112 /* 500 ms 250 ms 100 ms 50 ms (max turn time) */
113 { 100, 0, 0, 0 }, /* 2400 bps */
114 { 400, 0, 0, 0 }, /* 9600 bps */
115 { 800, 0, 0, 0 }, /* 19200 bps */
116 { 1600, 0, 0, 0 }, /* 38400 bps */
117 { 2360, 0, 0, 0 }, /* 57600 bps */
118 { 4800, 2400, 960, 480 }, /* 115200 bps */
119 { 28800, 11520, 5760, 2880 }, /* 576000 bps */
120 { 57600, 28800, 11520, 5760 }, /* 1152000 bps */
121 { 200000, 100000, 40000, 20000 }, /* 4000000 bps */
122 { 800000, 400000, 160000, 80000 }, /* 16000000 bps */
123};
124
125static pi_minor_info_t pi_minor_call_table_type_0[] = {
126 { NULL, 0 },
127/* 01 */{ irlap_param_baud_rate, PV_INTEGER | PV_LITTLE_ENDIAN },
128 { NULL, 0 },
129 { NULL, 0 },
130 { NULL, 0 },
131 { NULL, 0 },
132 { NULL, 0 },
133 { NULL, 0 },
134/* 08 */{ irlap_param_link_disconnect, PV_INT_8_BITS }
135};
136
137static pi_minor_info_t pi_minor_call_table_type_1[] = {
138 { NULL, 0 },
139 { NULL, 0 },
140/* 82 */{ irlap_param_max_turn_time, PV_INT_8_BITS },
141/* 83 */{ irlap_param_data_size, PV_INT_8_BITS },
142/* 84 */{ irlap_param_window_size, PV_INT_8_BITS },
143/* 85 */{ irlap_param_additional_bofs, PV_INT_8_BITS },
144/* 86 */{ irlap_param_min_turn_time, PV_INT_8_BITS },
145};
146
147static pi_major_info_t pi_major_call_table[] = {
148 { pi_minor_call_table_type_0, 9 },
149 { pi_minor_call_table_type_1, 7 },
150};
151
152static pi_param_info_t irlap_param_info = { pi_major_call_table, 2, 0x7f, 7 };
153
154/* ---------------------- LOCAL SUBROUTINES ---------------------- */
155/* Note : we start with a bunch of local subroutines.
156 * As the compiler is "one pass", this is the only way to get them to
157 * inline properly...
158 * Jean II
159 */
160/*
161 * Function value_index (value, array, size)
162 *
163 * Returns the index to the value in the specified array
164 */
165static inline int value_index(__u32 value, __u32 *array, int size)
166{
167 int i;
168
169 for (i=0; i < size; i++)
170 if (array[i] == value)
171 break;
172 return i;
173}
174
175/*
176 * Function index_value (index, array)
177 *
178 * Returns value to index in array, easy!
179 *
180 */
181static inline __u32 index_value(int index, __u32 *array)
182{
183 return array[index];
184}
185
186/*
187 * Function msb_index (word)
188 *
189 * Returns index to most significant bit (MSB) in word
190 *
191 */
192static int msb_index (__u16 word)
193{
194 __u16 msb = 0x8000;
195 int index = 15; /* Current MSB */
196
197 /* Check for buggy peers.
198 * Note : there is a small probability that it could be us, but I
199 * would expect driver authors to catch that pretty early and be
200 * able to check precisely what's going on. If a end user sees this,
201 * it's very likely the peer. - Jean II */
202 if (word == 0) {
203 IRDA_WARNING("%s(), Detected buggy peer, adjust null PV to 0x1!\n",
204 __FUNCTION__);
205 /* The only safe choice (we don't know the array size) */
206 word = 0x1;
207 }
208
209 while (msb) {
210 if (word & msb)
211 break; /* Found it! */
212 msb >>=1;
213 index--;
214 }
215 return index;
216}
217
218/*
219 * Function value_lower_bits (value, array)
220 *
221 * Returns a bit field marking all possibility lower than value.
222 */
223static inline int value_lower_bits(__u32 value, __u32 *array, int size, __u16 *field)
224{
225 int i;
226 __u16 mask = 0x1;
227 __u16 result = 0x0;
228
229 for (i=0; i < size; i++) {
230 /* Add the current value to the bit field, shift mask */
231 result |= mask;
232 mask <<= 1;
233 /* Finished ? */
234 if (array[i] >= value)
235 break;
236 }
237 /* Send back a valid index */
238 if(i >= size)
239 i = size - 1; /* Last item */
240 *field = result;
241 return i;
242}
243
244/*
245 * Function value_highest_bit (value, array)
246 *
247 * Returns a bit field marking the highest possibility lower than value.
248 */
249static inline int value_highest_bit(__u32 value, __u32 *array, int size, __u16 *field)
250{
251 int i;
252 __u16 mask = 0x1;
253 __u16 result = 0x0;
254
255 for (i=0; i < size; i++) {
256 /* Finished ? */
257 if (array[i] <= value)
258 break;
259 /* Shift mask */
260 mask <<= 1;
261 }
262 /* Set the current value to the bit field */
263 result |= mask;
264 /* Send back a valid index */
265 if(i >= size)
266 i = size - 1; /* Last item */
267 *field = result;
268 return i;
269}
270
271/* -------------------------- MAIN CALLS -------------------------- */
272
273/*
274 * Function irda_qos_compute_intersection (qos, new)
275 *
276 * Compute the intersection of the old QoS capabilities with new ones
277 *
278 */
279void irda_qos_compute_intersection(struct qos_info *qos, struct qos_info *new)
280{
281 IRDA_ASSERT(qos != NULL, return;);
282 IRDA_ASSERT(new != NULL, return;);
283
284 /* Apply */
285 qos->baud_rate.bits &= new->baud_rate.bits;
286 qos->window_size.bits &= new->window_size.bits;
287 qos->min_turn_time.bits &= new->min_turn_time.bits;
288 qos->max_turn_time.bits &= new->max_turn_time.bits;
289 qos->data_size.bits &= new->data_size.bits;
290 qos->link_disc_time.bits &= new->link_disc_time.bits;
291 qos->additional_bofs.bits &= new->additional_bofs.bits;
292
293 irda_qos_bits_to_value(qos);
294}
295
296/*
297 * Function irda_init_max_qos_capabilies (qos)
298 *
299 * The purpose of this function is for layers and drivers to be able to
300 * set the maximum QoS possible and then "and in" their own limitations
301 *
302 */
303void irda_init_max_qos_capabilies(struct qos_info *qos)
304{
305 int i;
306 /*
307 * These are the maximum supported values as specified on pages
308 * 39-43 in IrLAP
309 */
310
311 /* Use sysctl to set some configurable values... */
312 /* Set configured max speed */
313 i = value_lower_bits(sysctl_max_baud_rate, baud_rates, 10,
314 &qos->baud_rate.bits);
315 sysctl_max_baud_rate = index_value(i, baud_rates);
316
317 /* Set configured max disc time */
318 i = value_lower_bits(sysctl_max_noreply_time, link_disc_times, 8,
319 &qos->link_disc_time.bits);
320 sysctl_max_noreply_time = index_value(i, link_disc_times);
321
322 /* LSB is first byte, MSB is second byte */
323 qos->baud_rate.bits &= 0x03ff;
324
325 qos->window_size.bits = 0x7f;
326 qos->min_turn_time.bits = 0xff;
327 qos->max_turn_time.bits = 0x0f;
328 qos->data_size.bits = 0x3f;
329 qos->link_disc_time.bits &= 0xff;
330 qos->additional_bofs.bits = 0xff;
331}
332EXPORT_SYMBOL(irda_init_max_qos_capabilies);
333
334/*
335 * Function irlap_adjust_qos_settings (qos)
336 *
337 * Adjust QoS settings in case some values are not possible to use because
338 * of other settings
339 */
340static void irlap_adjust_qos_settings(struct qos_info *qos)
341{
342 __u32 line_capacity;
343 int index;
344
345 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
346
347 /*
348 * Make sure the mintt is sensible.
349 * Main culprit : Ericsson T39. - Jean II
350 */
351 if (sysctl_min_tx_turn_time > qos->min_turn_time.value) {
352 int i;
353
354 IRDA_WARNING("%s(), Detected buggy peer, adjust mtt to %dus!\n",
355 __FUNCTION__, sysctl_min_tx_turn_time);
356
357 /* We don't really need bits, but easier this way */
358 i = value_highest_bit(sysctl_min_tx_turn_time, min_turn_times,
359 8, &qos->min_turn_time.bits);
360 sysctl_min_tx_turn_time = index_value(i, min_turn_times);
361 qos->min_turn_time.value = sysctl_min_tx_turn_time;
362 }
363
364 /*
365 * Not allowed to use a max turn time less than 500 ms if the baudrate
366 * is less than 115200
367 */
368 if ((qos->baud_rate.value < 115200) &&
369 (qos->max_turn_time.value < 500))
370 {
371 IRDA_DEBUG(0,
372 "%s(), adjusting max turn time from %d to 500 ms\n",
373 __FUNCTION__, qos->max_turn_time.value);
374 qos->max_turn_time.value = 500;
375 }
376
377 /*
378 * The data size must be adjusted according to the baud rate and max
379 * turn time
380 */
381 index = value_index(qos->data_size.value, data_sizes, 6);
382 line_capacity = irlap_max_line_capacity(qos->baud_rate.value,
383 qos->max_turn_time.value);
384
385#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
386 while ((qos->data_size.value > line_capacity) && (index > 0)) {
387 qos->data_size.value = data_sizes[index--];
388 IRDA_DEBUG(2, "%s(), reducing data size to %d\n",
389 __FUNCTION__, qos->data_size.value);
390 }
391#else /* Use method described in section 6.6.11 of IrLAP */
392 while (irlap_requested_line_capacity(qos) > line_capacity) {
393 IRDA_ASSERT(index != 0, return;);
394
395 /* Must be able to send at least one frame */
396 if (qos->window_size.value > 1) {
397 qos->window_size.value--;
398 IRDA_DEBUG(2, "%s(), reducing window size to %d\n",
399 __FUNCTION__, qos->window_size.value);
400 } else if (index > 1) {
401 qos->data_size.value = data_sizes[index--];
402 IRDA_DEBUG(2, "%s(), reducing data size to %d\n",
403 __FUNCTION__, qos->data_size.value);
404 } else {
405 IRDA_WARNING("%s(), nothing more we can do!\n",
406 __FUNCTION__);
407 }
408 }
409#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
410 /*
411 * Fix tx data size according to user limits - Jean II
412 */
413 if (qos->data_size.value > sysctl_max_tx_data_size)
414 /* Allow non discrete adjustement to avoid loosing capacity */
415 qos->data_size.value = sysctl_max_tx_data_size;
416 /*
417 * Override Tx window if user request it. - Jean II
418 */
419 if (qos->window_size.value > sysctl_max_tx_window)
420 qos->window_size.value = sysctl_max_tx_window;
421}
422
423/*
424 * Function irlap_negotiate (qos_device, qos_session, skb)
425 *
426 * Negotiate QoS values, not really that much negotiation :-)
427 * We just set the QoS capabilities for the peer station
428 *
429 */
430int irlap_qos_negotiate(struct irlap_cb *self, struct sk_buff *skb)
431{
432 int ret;
433
434 ret = irda_param_extract_all(self, skb->data, skb->len,
435 &irlap_param_info);
436
437 /* Convert the negotiated bits to values */
438 irda_qos_bits_to_value(&self->qos_tx);
439 irda_qos_bits_to_value(&self->qos_rx);
440
441 irlap_adjust_qos_settings(&self->qos_tx);
442
443 IRDA_DEBUG(2, "Setting BAUD_RATE to %d bps.\n",
444 self->qos_tx.baud_rate.value);
445 IRDA_DEBUG(2, "Setting DATA_SIZE to %d bytes\n",
446 self->qos_tx.data_size.value);
447 IRDA_DEBUG(2, "Setting WINDOW_SIZE to %d\n",
448 self->qos_tx.window_size.value);
449 IRDA_DEBUG(2, "Setting XBOFS to %d\n",
450 self->qos_tx.additional_bofs.value);
451 IRDA_DEBUG(2, "Setting MAX_TURN_TIME to %d ms.\n",
452 self->qos_tx.max_turn_time.value);
453 IRDA_DEBUG(2, "Setting MIN_TURN_TIME to %d usecs.\n",
454 self->qos_tx.min_turn_time.value);
455 IRDA_DEBUG(2, "Setting LINK_DISC to %d secs.\n",
456 self->qos_tx.link_disc_time.value);
457 return ret;
458}
459
460/*
461 * Function irlap_insert_negotiation_params (qos, fp)
462 *
463 * Insert QoS negotiaion pararameters into frame
464 *
465 */
466int irlap_insert_qos_negotiation_params(struct irlap_cb *self,
467 struct sk_buff *skb)
468{
469 int ret;
470
471 /* Insert data rate */
472 ret = irda_param_insert(self, PI_BAUD_RATE, skb->tail,
473 skb_tailroom(skb), &irlap_param_info);
474 if (ret < 0)
475 return ret;
476 skb_put(skb, ret);
477
478 /* Insert max turnaround time */
479 ret = irda_param_insert(self, PI_MAX_TURN_TIME, skb->tail,
480 skb_tailroom(skb), &irlap_param_info);
481 if (ret < 0)
482 return ret;
483 skb_put(skb, ret);
484
485 /* Insert data size */
486 ret = irda_param_insert(self, PI_DATA_SIZE, skb->tail,
487 skb_tailroom(skb), &irlap_param_info);
488 if (ret < 0)
489 return ret;
490 skb_put(skb, ret);
491
492 /* Insert window size */
493 ret = irda_param_insert(self, PI_WINDOW_SIZE, skb->tail,
494 skb_tailroom(skb), &irlap_param_info);
495 if (ret < 0)
496 return ret;
497 skb_put(skb, ret);
498
499 /* Insert additional BOFs */
500 ret = irda_param_insert(self, PI_ADD_BOFS, skb->tail,
501 skb_tailroom(skb), &irlap_param_info);
502 if (ret < 0)
503 return ret;
504 skb_put(skb, ret);
505
506 /* Insert minimum turnaround time */
507 ret = irda_param_insert(self, PI_MIN_TURN_TIME, skb->tail,
508 skb_tailroom(skb), &irlap_param_info);
509 if (ret < 0)
510 return ret;
511 skb_put(skb, ret);
512
513 /* Insert link disconnect/threshold time */
514 ret = irda_param_insert(self, PI_LINK_DISC, skb->tail,
515 skb_tailroom(skb), &irlap_param_info);
516 if (ret < 0)
517 return ret;
518 skb_put(skb, ret);
519
520 return 0;
521}
522
523/*
524 * Function irlap_param_baud_rate (instance, param, get)
525 *
526 * Negotiate data-rate
527 *
528 */
529static int irlap_param_baud_rate(void *instance, irda_param_t *param, int get)
530{
531 __u16 final;
532
533 struct irlap_cb *self = (struct irlap_cb *) instance;
534
535 IRDA_ASSERT(self != NULL, return -1;);
536 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
537
538 if (get) {
539 param->pv.i = self->qos_rx.baud_rate.bits;
540 IRDA_DEBUG(2, "%s(), baud rate = 0x%02x\n",
541 __FUNCTION__, param->pv.i);
542 } else {
543 /*
544 * Stations must agree on baud rate, so calculate
545 * intersection
546 */
547 IRDA_DEBUG(2, "Requested BAUD_RATE: 0x%04x\n", (__u16) param->pv.i);
548 final = (__u16) param->pv.i & self->qos_rx.baud_rate.bits;
549
550 IRDA_DEBUG(2, "Final BAUD_RATE: 0x%04x\n", final);
551 self->qos_tx.baud_rate.bits = final;
552 self->qos_rx.baud_rate.bits = final;
553 }
554
555 return 0;
556}
557
558/*
559 * Function irlap_param_link_disconnect (instance, param, get)
560 *
561 * Negotiate link disconnect/threshold time.
562 *
563 */
564static int irlap_param_link_disconnect(void *instance, irda_param_t *param,
565 int get)
566{
567 __u16 final;
568
569 struct irlap_cb *self = (struct irlap_cb *) instance;
570
571 IRDA_ASSERT(self != NULL, return -1;);
572 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
573
574 if (get)
575 param->pv.i = self->qos_rx.link_disc_time.bits;
576 else {
577 /*
578 * Stations must agree on link disconnect/threshold
579 * time.
580 */
581 IRDA_DEBUG(2, "LINK_DISC: %02x\n", (__u8) param->pv.i);
582 final = (__u8) param->pv.i & self->qos_rx.link_disc_time.bits;
583
584 IRDA_DEBUG(2, "Final LINK_DISC: %02x\n", final);
585 self->qos_tx.link_disc_time.bits = final;
586 self->qos_rx.link_disc_time.bits = final;
587 }
588 return 0;
589}
590
591/*
592 * Function irlap_param_max_turn_time (instance, param, get)
593 *
594 * Negotiate the maximum turnaround time. This is a type 1 parameter and
595 * will be negotiated independently for each station
596 *
597 */
598static int irlap_param_max_turn_time(void *instance, irda_param_t *param,
599 int get)
600{
601 struct irlap_cb *self = (struct irlap_cb *) instance;
602
603 IRDA_ASSERT(self != NULL, return -1;);
604 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
605
606 if (get)
607 param->pv.i = self->qos_rx.max_turn_time.bits;
608 else
609 self->qos_tx.max_turn_time.bits = (__u8) param->pv.i;
610
611 return 0;
612}
613
614/*
615 * Function irlap_param_data_size (instance, param, get)
616 *
617 * Negotiate the data size. This is a type 1 parameter and
618 * will be negotiated independently for each station
619 *
620 */
621static int irlap_param_data_size(void *instance, irda_param_t *param, int get)
622{
623 struct irlap_cb *self = (struct irlap_cb *) instance;
624
625 IRDA_ASSERT(self != NULL, return -1;);
626 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
627
628 if (get)
629 param->pv.i = self->qos_rx.data_size.bits;
630 else
631 self->qos_tx.data_size.bits = (__u8) param->pv.i;
632
633 return 0;
634}
635
636/*
637 * Function irlap_param_window_size (instance, param, get)
638 *
639 * Negotiate the window size. This is a type 1 parameter and
640 * will be negotiated independently for each station
641 *
642 */
643static int irlap_param_window_size(void *instance, irda_param_t *param,
644 int get)
645{
646 struct irlap_cb *self = (struct irlap_cb *) instance;
647
648 IRDA_ASSERT(self != NULL, return -1;);
649 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
650
651 if (get)
652 param->pv.i = self->qos_rx.window_size.bits;
653 else
654 self->qos_tx.window_size.bits = (__u8) param->pv.i;
655
656 return 0;
657}
658
659/*
660 * Function irlap_param_additional_bofs (instance, param, get)
661 *
662 * Negotiate additional BOF characters. This is a type 1 parameter and
663 * will be negotiated independently for each station.
664 */
665static int irlap_param_additional_bofs(void *instance, irda_param_t *param, int get)
666{
667 struct irlap_cb *self = (struct irlap_cb *) instance;
668
669 IRDA_ASSERT(self != NULL, return -1;);
670 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
671
672 if (get)
673 param->pv.i = self->qos_rx.additional_bofs.bits;
674 else
675 self->qos_tx.additional_bofs.bits = (__u8) param->pv.i;
676
677 return 0;
678}
679
680/*
681 * Function irlap_param_min_turn_time (instance, param, get)
682 *
683 * Negotiate the minimum turn around time. This is a type 1 parameter and
684 * will be negotiated independently for each station
685 */
686static int irlap_param_min_turn_time(void *instance, irda_param_t *param,
687 int get)
688{
689 struct irlap_cb *self = (struct irlap_cb *) instance;
690
691 IRDA_ASSERT(self != NULL, return -1;);
692 IRDA_ASSERT(self->magic == LAP_MAGIC, return -1;);
693
694 if (get)
695 param->pv.i = self->qos_rx.min_turn_time.bits;
696 else
697 self->qos_tx.min_turn_time.bits = (__u8) param->pv.i;
698
699 return 0;
700}
701
702/*
703 * Function irlap_max_line_capacity (speed, max_turn_time, min_turn_time)
704 *
705 * Calculate the maximum line capacity
706 *
707 */
708__u32 irlap_max_line_capacity(__u32 speed, __u32 max_turn_time)
709{
710 __u32 line_capacity;
711 int i,j;
712
713 IRDA_DEBUG(2, "%s(), speed=%d, max_turn_time=%d\n",
714 __FUNCTION__, speed, max_turn_time);
715
716 i = value_index(speed, baud_rates, 10);
717 j = value_index(max_turn_time, max_turn_times, 4);
718
719 IRDA_ASSERT(((i >=0) && (i <10)), return 0;);
720 IRDA_ASSERT(((j >=0) && (j <4)), return 0;);
721
722 line_capacity = max_line_capacities[i][j];
723
724 IRDA_DEBUG(2, "%s(), line capacity=%d bytes\n",
725 __FUNCTION__, line_capacity);
726
727 return line_capacity;
728}
729
730#ifndef CONFIG_IRDA_DYNAMIC_WINDOW
731static __u32 irlap_requested_line_capacity(struct qos_info *qos)
732{
733 __u32 line_capacity;
734
735 line_capacity = qos->window_size.value *
736 (qos->data_size.value + 6 + qos->additional_bofs.value) +
737 irlap_min_turn_time_in_bytes(qos->baud_rate.value,
738 qos->min_turn_time.value);
739
740 IRDA_DEBUG(2, "%s(), requested line capacity=%d\n",
741 __FUNCTION__, line_capacity);
742
743 return line_capacity;
744}
745#endif
746
747void irda_qos_bits_to_value(struct qos_info *qos)
748{
749 int index;
750
751 IRDA_ASSERT(qos != NULL, return;);
752
753 index = msb_index(qos->baud_rate.bits);
754 qos->baud_rate.value = baud_rates[index];
755
756 index = msb_index(qos->data_size.bits);
757 qos->data_size.value = data_sizes[index];
758
759 index = msb_index(qos->window_size.bits);
760 qos->window_size.value = index+1;
761
762 index = msb_index(qos->min_turn_time.bits);
763 qos->min_turn_time.value = min_turn_times[index];
764
765 index = msb_index(qos->max_turn_time.bits);
766 qos->max_turn_time.value = max_turn_times[index];
767
768 index = msb_index(qos->link_disc_time.bits);
769 qos->link_disc_time.value = link_disc_times[index];
770
771 index = msb_index(qos->additional_bofs.bits);
772 qos->additional_bofs.value = add_bofs[index];
773}
774EXPORT_SYMBOL(irda_qos_bits_to_value);
diff --git a/net/irda/timer.c b/net/irda/timer.c
new file mode 100644
index 00000000000..0e17f976add
--- /dev/null
+++ b/net/irda/timer.c
@@ -0,0 +1,233 @@
1/*********************************************************************
2 *
3 * Filename: timer.c
4 * Version:
5 * Description:
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Sat Aug 16 00:59:29 1997
9 * Modified at: Wed Dec 8 12:50:34 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 *
12 * Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>,
13 * All Rights Reserved.
14 * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version.
20 *
21 * Neither Dag Brattli nor University of Tromsø admit liability nor
22 * provide warranty for any of this software. This material is
23 * provided "AS-IS" and at no charge.
24 *
25 ********************************************************************/
26
27#include <asm/system.h>
28#include <linux/config.h>
29#include <linux/delay.h>
30
31#include <net/irda/timer.h>
32#include <net/irda/irda.h>
33#include <net/irda/irda_device.h>
34#include <net/irda/irlap.h>
35#include <net/irda/irlmp.h>
36
37extern int sysctl_slot_timeout;
38
39static void irlap_slot_timer_expired(void* data);
40static void irlap_query_timer_expired(void* data);
41static void irlap_final_timer_expired(void* data);
42static void irlap_wd_timer_expired(void* data);
43static void irlap_backoff_timer_expired(void* data);
44static void irlap_media_busy_expired(void* data);
45
46void irlap_start_slot_timer(struct irlap_cb *self, int timeout)
47{
48 irda_start_timer(&self->slot_timer, timeout, (void *) self,
49 irlap_slot_timer_expired);
50}
51
52void irlap_start_query_timer(struct irlap_cb *self, int S, int s)
53{
54 int timeout;
55
56 /* Calculate when the peer discovery should end. Normally, we
57 * get the end-of-discovery frame, so this is just in case
58 * we miss it.
59 * Basically, we multiply the number of remaining slots by our
60 * slot time, plus add some extra time to properly receive the last
61 * discovery packet (which is longer due to extra discovery info),
62 * to avoid messing with for incomming connections requests and
63 * to accomodate devices that perform discovery slower than us.
64 * Jean II */
65 timeout = ((sysctl_slot_timeout * HZ / 1000) * (S - s)
66 + XIDEXTRA_TIMEOUT + SMALLBUSY_TIMEOUT);
67
68 /* Set or re-set the timer. We reset the timer for each received
69 * discovery query, which allow us to automatically adjust to
70 * the speed of the peer discovery (faster or slower). Jean II */
71 irda_start_timer( &self->query_timer, timeout, (void *) self,
72 irlap_query_timer_expired);
73}
74
75void irlap_start_final_timer(struct irlap_cb *self, int timeout)
76{
77 irda_start_timer(&self->final_timer, timeout, (void *) self,
78 irlap_final_timer_expired);
79}
80
81void irlap_start_wd_timer(struct irlap_cb *self, int timeout)
82{
83 irda_start_timer(&self->wd_timer, timeout, (void *) self,
84 irlap_wd_timer_expired);
85}
86
87void irlap_start_backoff_timer(struct irlap_cb *self, int timeout)
88{
89 irda_start_timer(&self->backoff_timer, timeout, (void *) self,
90 irlap_backoff_timer_expired);
91}
92
93void irlap_start_mbusy_timer(struct irlap_cb *self, int timeout)
94{
95 irda_start_timer(&self->media_busy_timer, timeout,
96 (void *) self, irlap_media_busy_expired);
97}
98
99void irlap_stop_mbusy_timer(struct irlap_cb *self)
100{
101 /* If timer is activated, kill it! */
102 del_timer(&self->media_busy_timer);
103
104 /* If we are in NDM, there is a bunch of events in LAP that
105 * that be pending due to the media_busy condition, such as
106 * CONNECT_REQUEST and SEND_UI_FRAME. If we don't generate
107 * an event, they will wait forever...
108 * Jean II */
109 if (self->state == LAP_NDM)
110 irlap_do_event(self, MEDIA_BUSY_TIMER_EXPIRED, NULL, NULL);
111}
112
113void irlmp_start_watchdog_timer(struct lsap_cb *self, int timeout)
114{
115 irda_start_timer(&self->watchdog_timer, timeout, (void *) self,
116 irlmp_watchdog_timer_expired);
117}
118
119void irlmp_start_discovery_timer(struct irlmp_cb *self, int timeout)
120{
121 irda_start_timer(&self->discovery_timer, timeout, (void *) self,
122 irlmp_discovery_timer_expired);
123}
124
125void irlmp_start_idle_timer(struct lap_cb *self, int timeout)
126{
127 irda_start_timer(&self->idle_timer, timeout, (void *) self,
128 irlmp_idle_timer_expired);
129}
130
131void irlmp_stop_idle_timer(struct lap_cb *self)
132{
133 /* If timer is activated, kill it! */
134 del_timer(&self->idle_timer);
135}
136
137/*
138 * Function irlap_slot_timer_expired (data)
139 *
140 * IrLAP slot timer has expired
141 *
142 */
143static void irlap_slot_timer_expired(void *data)
144{
145 struct irlap_cb *self = (struct irlap_cb *) data;
146
147 IRDA_ASSERT(self != NULL, return;);
148 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
149
150 irlap_do_event(self, SLOT_TIMER_EXPIRED, NULL, NULL);
151}
152
153/*
154 * Function irlap_query_timer_expired (data)
155 *
156 * IrLAP query timer has expired
157 *
158 */
159static void irlap_query_timer_expired(void *data)
160{
161 struct irlap_cb *self = (struct irlap_cb *) data;
162
163 IRDA_ASSERT(self != NULL, return;);
164 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
165
166 irlap_do_event(self, QUERY_TIMER_EXPIRED, NULL, NULL);
167}
168
169/*
170 * Function irda_final_timer_expired (data)
171 *
172 *
173 *
174 */
175static void irlap_final_timer_expired(void *data)
176{
177 struct irlap_cb *self = (struct irlap_cb *) data;
178
179 IRDA_ASSERT(self != NULL, return;);
180 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
181
182 irlap_do_event(self, FINAL_TIMER_EXPIRED, NULL, NULL);
183}
184
185/*
186 * Function irda_wd_timer_expired (data)
187 *
188 *
189 *
190 */
191static void irlap_wd_timer_expired(void *data)
192{
193 struct irlap_cb *self = (struct irlap_cb *) data;
194
195 IRDA_ASSERT(self != NULL, return;);
196 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
197
198 irlap_do_event(self, WD_TIMER_EXPIRED, NULL, NULL);
199}
200
201/*
202 * Function irda_backoff_timer_expired (data)
203 *
204 *
205 *
206 */
207static void irlap_backoff_timer_expired(void *data)
208{
209 struct irlap_cb *self = (struct irlap_cb *) data;
210
211 IRDA_ASSERT(self != NULL, return;);
212 IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
213
214 irlap_do_event(self, BACKOFF_TIMER_EXPIRED, NULL, NULL);
215}
216
217
218/*
219 * Function irtty_media_busy_expired (data)
220 *
221 *
222 */
223void irlap_media_busy_expired(void* data)
224{
225 struct irlap_cb *self = (struct irlap_cb *) data;
226
227 IRDA_ASSERT(self != NULL, return;);
228
229 irda_device_set_media_busy(self->netdev, FALSE);
230 /* Note : the LAP event will be send in irlap_stop_mbusy_timer(),
231 * to catch other cases where the flag is cleared (for example
232 * after a discovery) - Jean II */
233}
diff --git a/net/irda/wrapper.c b/net/irda/wrapper.c
new file mode 100644
index 00000000000..87130c1c869
--- /dev/null
+++ b/net/irda/wrapper.c
@@ -0,0 +1,491 @@
1/*********************************************************************
2 *
3 * Filename: wrapper.c
4 * Version: 1.2
5 * Description: IrDA SIR async wrapper layer
6 * Status: Stable
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Mon Aug 4 20:40:53 1997
9 * Modified at: Fri Jan 28 13:21:09 2000
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 * Modified at: Fri May 28 3:11 CST 1999
12 * Modified by: Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
13 *
14 * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
15 * All Rights Reserved.
16 * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
17 *
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License as
20 * published by the Free Software Foundation; either version 2 of
21 * the License, or (at your option) any later version.
22 *
23 * Neither Dag Brattli nor University of Tromsø admit liability nor
24 * provide warranty for any of this software. This material is
25 * provided "AS-IS" and at no charge.
26 *
27 ********************************************************************/
28
29#include <linux/skbuff.h>
30#include <linux/string.h>
31#include <linux/module.h>
32#include <asm/byteorder.h>
33
34#include <net/irda/irda.h>
35#include <net/irda/wrapper.h>
36#include <net/irda/crc.h>
37#include <net/irda/irlap.h>
38#include <net/irda/irlap_frame.h>
39#include <net/irda/irda_device.h>
40
41/************************** FRAME WRAPPING **************************/
42/*
43 * Unwrap and unstuff SIR frames
44 *
45 * Note : at FIR and MIR, HDLC framing is used and usually handled
46 * by the controller, so we come here only for SIR... Jean II
47 */
48
49/*
50 * Function stuff_byte (byte, buf)
51 *
52 * Byte stuff one single byte and put the result in buffer pointed to by
53 * buf. The buffer must at all times be able to have two bytes inserted.
54 *
55 * This is in a tight loop, better inline it, so need to be prior to callers.
56 * (2000 bytes on P6 200MHz, non-inlined ~370us, inline ~170us) - Jean II
57 */
58static inline int stuff_byte(__u8 byte, __u8 *buf)
59{
60 switch (byte) {
61 case BOF: /* FALLTHROUGH */
62 case EOF: /* FALLTHROUGH */
63 case CE:
64 /* Insert transparently coded */
65 buf[0] = CE; /* Send link escape */
66 buf[1] = byte^IRDA_TRANS; /* Complement bit 5 */
67 return 2;
68 /* break; */
69 default:
70 /* Non-special value, no transparency required */
71 buf[0] = byte;
72 return 1;
73 /* break; */
74 }
75}
76
77/*
78 * Function async_wrap (skb, *tx_buff, buffsize)
79 *
80 * Makes a new buffer with wrapping and stuffing, should check that
81 * we don't get tx buffer overflow.
82 */
83int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
84{
85 struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
86 int xbofs;
87 int i;
88 int n;
89 union {
90 __u16 value;
91 __u8 bytes[2];
92 } fcs;
93
94 /* Initialize variables */
95 fcs.value = INIT_FCS;
96 n = 0;
97
98 /*
99 * Send XBOF's for required min. turn time and for the negotiated
100 * additional XBOFS
101 */
102
103 if (cb->magic != LAP_MAGIC) {
104 /*
105 * This will happen for all frames sent from user-space.
106 * Nothing to worry about, but we set the default number of
107 * BOF's
108 */
109 IRDA_DEBUG(1, "%s(), wrong magic in skb!\n", __FUNCTION__);
110 xbofs = 10;
111 } else
112 xbofs = cb->xbofs + cb->xbofs_delay;
113
114 IRDA_DEBUG(4, "%s(), xbofs=%d\n", __FUNCTION__, xbofs);
115
116 /* Check that we never use more than 115 + 48 xbofs */
117 if (xbofs > 163) {
118 IRDA_DEBUG(0, "%s(), too many xbofs (%d)\n", __FUNCTION__,
119 xbofs);
120 xbofs = 163;
121 }
122
123 memset(tx_buff + n, XBOF, xbofs);
124 n += xbofs;
125
126 /* Start of packet character BOF */
127 tx_buff[n++] = BOF;
128
129 /* Insert frame and calc CRC */
130 for (i=0; i < skb->len; i++) {
131 /*
132 * Check for the possibility of tx buffer overflow. We use
133 * bufsize-5 since the maximum number of bytes that can be
134 * transmitted after this point is 5.
135 */
136 if(n >= (buffsize-5)) {
137 IRDA_ERROR("%s(), tx buffer overflow (n=%d)\n",
138 __FUNCTION__, n);
139 return n;
140 }
141
142 n += stuff_byte(skb->data[i], tx_buff+n);
143 fcs.value = irda_fcs(fcs.value, skb->data[i]);
144 }
145
146 /* Insert CRC in little endian format (LSB first) */
147 fcs.value = ~fcs.value;
148#ifdef __LITTLE_ENDIAN
149 n += stuff_byte(fcs.bytes[0], tx_buff+n);
150 n += stuff_byte(fcs.bytes[1], tx_buff+n);
151#else /* ifdef __BIG_ENDIAN */
152 n += stuff_byte(fcs.bytes[1], tx_buff+n);
153 n += stuff_byte(fcs.bytes[0], tx_buff+n);
154#endif
155 tx_buff[n++] = EOF;
156
157 return n;
158}
159EXPORT_SYMBOL(async_wrap_skb);
160
161/************************* FRAME UNWRAPPING *************************/
162/*
163 * Unwrap and unstuff SIR frames
164 *
165 * Complete rewrite by Jean II :
166 * More inline, faster, more compact, more logical. Jean II
167 * (16 bytes on P6 200MHz, old 5 to 7 us, new 4 to 6 us)
168 * (24 bytes on P6 200MHz, old 9 to 10 us, new 7 to 8 us)
169 * (for reference, 115200 b/s is 1 byte every 69 us)
170 * And reduce wrapper.o by ~900B in the process ;-)
171 *
172 * Then, we have the addition of ZeroCopy, which is optional
173 * (i.e. the driver must initiate it) and improve final processing.
174 * (2005 B frame + EOF on P6 200MHz, without 30 to 50 us, with 10 to 25 us)
175 *
176 * Note : at FIR and MIR, HDLC framing is used and usually handled
177 * by the controller, so we come here only for SIR... Jean II
178 */
179
180/*
181 * We can also choose where we want to do the CRC calculation. We can
182 * do it "inline", as we receive the bytes, or "postponed", when
183 * receiving the End-Of-Frame.
184 * (16 bytes on P6 200MHz, inlined 4 to 6 us, postponed 4 to 5 us)
185 * (24 bytes on P6 200MHz, inlined 7 to 8 us, postponed 5 to 7 us)
186 * With ZeroCopy :
187 * (2005 B frame on P6 200MHz, inlined 10 to 25 us, postponed 140 to 180 us)
188 * Without ZeroCopy :
189 * (2005 B frame on P6 200MHz, inlined 30 to 50 us, postponed 150 to 180 us)
190 * (Note : numbers taken with irq disabled)
191 *
192 * From those numbers, it's not clear which is the best strategy, because
193 * we end up running through a lot of data one way or another (i.e. cache
194 * misses). I personally prefer to avoid the huge latency spike of the
195 * "postponed" solution, because it come just at the time when we have
196 * lot's of protocol processing to do and it will hurt our ability to
197 * reach low link turnaround times... Jean II
198 */
199//#define POSTPONE_RX_CRC
200
201/*
202 * Function async_bump (buf, len, stats)
203 *
204 * Got a frame, make a copy of it, and pass it up the stack! We can try
205 * to inline it since it's only called from state_inside_frame
206 */
207static inline void
208async_bump(struct net_device *dev,
209 struct net_device_stats *stats,
210 iobuff_t *rx_buff)
211{
212 struct sk_buff *newskb;
213 struct sk_buff *dataskb;
214 int docopy;
215
216 /* Check if we need to copy the data to a new skb or not.
217 * If the driver doesn't use ZeroCopy Rx, we have to do it.
218 * With ZeroCopy Rx, the rx_buff already point to a valid
219 * skb. But, if the frame is small, it is more efficient to
220 * copy it to save memory (copy will be fast anyway - that's
221 * called Rx-copy-break). Jean II */
222 docopy = ((rx_buff->skb == NULL) ||
223 (rx_buff->len < IRDA_RX_COPY_THRESHOLD));
224
225 /* Allocate a new skb */
226 newskb = dev_alloc_skb(docopy ? rx_buff->len + 1 : rx_buff->truesize);
227 if (!newskb) {
228 stats->rx_dropped++;
229 /* We could deliver the current skb if doing ZeroCopy Rx,
230 * but this would stall the Rx path. Better drop the
231 * packet... Jean II */
232 return;
233 }
234
235 /* Align IP header to 20 bytes (i.e. increase skb->data)
236 * Note this is only useful with IrLAN, as PPP has a variable
237 * header size (2 or 1 bytes) - Jean II */
238 skb_reserve(newskb, 1);
239
240 if(docopy) {
241 /* Copy data without CRC (lenght already checked) */
242 memcpy(newskb->data, rx_buff->data, rx_buff->len - 2);
243 /* Deliver this skb */
244 dataskb = newskb;
245 } else {
246 /* We are using ZeroCopy. Deliver old skb */
247 dataskb = rx_buff->skb;
248 /* And hook the new skb to the rx_buff */
249 rx_buff->skb = newskb;
250 rx_buff->head = newskb->data; /* NOT newskb->head */
251 //printk(KERN_DEBUG "ZeroCopy : len = %d, dataskb = %p, newskb = %p\n", rx_buff->len, dataskb, newskb);
252 }
253
254 /* Set proper length on skb (without CRC) */
255 skb_put(dataskb, rx_buff->len - 2);
256
257 /* Feed it to IrLAP layer */
258 dataskb->dev = dev;
259 dataskb->mac.raw = dataskb->data;
260 dataskb->protocol = htons(ETH_P_IRDA);
261
262 netif_rx(dataskb);
263
264 stats->rx_packets++;
265 stats->rx_bytes += rx_buff->len;
266
267 /* Clean up rx_buff (redundant with async_unwrap_bof() ???) */
268 rx_buff->data = rx_buff->head;
269 rx_buff->len = 0;
270}
271
272/*
273 * Function async_unwrap_bof(dev, byte)
274 *
275 * Handle Beginning Of Frame character received within a frame
276 *
277 */
278static inline void
279async_unwrap_bof(struct net_device *dev,
280 struct net_device_stats *stats,
281 iobuff_t *rx_buff, __u8 byte)
282{
283 switch(rx_buff->state) {
284 case LINK_ESCAPE:
285 case INSIDE_FRAME:
286 /* Not supposed to happen, the previous frame is not
287 * finished - Jean II */
288 IRDA_DEBUG(1, "%s(), Discarding incomplete frame\n",
289 __FUNCTION__);
290 stats->rx_errors++;
291 stats->rx_missed_errors++;
292 irda_device_set_media_busy(dev, TRUE);
293 break;
294
295 case OUTSIDE_FRAME:
296 case BEGIN_FRAME:
297 default:
298 /* We may receive multiple BOF at the start of frame */
299 break;
300 }
301
302 /* Now receiving frame */
303 rx_buff->state = BEGIN_FRAME;
304 rx_buff->in_frame = TRUE;
305
306 /* Time to initialize receive buffer */
307 rx_buff->data = rx_buff->head;
308 rx_buff->len = 0;
309 rx_buff->fcs = INIT_FCS;
310}
311
312/*
313 * Function async_unwrap_eof(dev, byte)
314 *
315 * Handle End Of Frame character received within a frame
316 *
317 */
318static inline void
319async_unwrap_eof(struct net_device *dev,
320 struct net_device_stats *stats,
321 iobuff_t *rx_buff, __u8 byte)
322{
323#ifdef POSTPONE_RX_CRC
324 int i;
325#endif
326
327 switch(rx_buff->state) {
328 case OUTSIDE_FRAME:
329 /* Probably missed the BOF */
330 stats->rx_errors++;
331 stats->rx_missed_errors++;
332 irda_device_set_media_busy(dev, TRUE);
333 break;
334
335 case BEGIN_FRAME:
336 case LINK_ESCAPE:
337 case INSIDE_FRAME:
338 default:
339 /* Note : in the case of BEGIN_FRAME and LINK_ESCAPE,
340 * the fcs will most likely not match and generate an
341 * error, as expected - Jean II */
342 rx_buff->state = OUTSIDE_FRAME;
343 rx_buff->in_frame = FALSE;
344
345#ifdef POSTPONE_RX_CRC
346 /* If we haven't done the CRC as we receive bytes, we
347 * must do it now... Jean II */
348 for(i = 0; i < rx_buff->len; i++)
349 rx_buff->fcs = irda_fcs(rx_buff->fcs,
350 rx_buff->data[i]);
351#endif
352
353 /* Test FCS and signal success if the frame is good */
354 if (rx_buff->fcs == GOOD_FCS) {
355 /* Deliver frame */
356 async_bump(dev, stats, rx_buff);
357 break;
358 } else {
359 /* Wrong CRC, discard frame! */
360 irda_device_set_media_busy(dev, TRUE);
361
362 IRDA_DEBUG(1, "%s(), crc error\n", __FUNCTION__);
363 stats->rx_errors++;
364 stats->rx_crc_errors++;
365 }
366 break;
367 }
368}
369
370/*
371 * Function async_unwrap_ce(dev, byte)
372 *
373 * Handle Character Escape character received within a frame
374 *
375 */
376static inline void
377async_unwrap_ce(struct net_device *dev,
378 struct net_device_stats *stats,
379 iobuff_t *rx_buff, __u8 byte)
380{
381 switch(rx_buff->state) {
382 case OUTSIDE_FRAME:
383 /* Activate carrier sense */
384 irda_device_set_media_busy(dev, TRUE);
385 break;
386
387 case LINK_ESCAPE:
388 IRDA_WARNING("%s: state not defined\n", __FUNCTION__);
389 break;
390
391 case BEGIN_FRAME:
392 case INSIDE_FRAME:
393 default:
394 /* Stuffed byte coming */
395 rx_buff->state = LINK_ESCAPE;
396 break;
397 }
398}
399
400/*
401 * Function async_unwrap_other(dev, byte)
402 *
403 * Handle other characters received within a frame
404 *
405 */
406static inline void
407async_unwrap_other(struct net_device *dev,
408 struct net_device_stats *stats,
409 iobuff_t *rx_buff, __u8 byte)
410{
411 switch(rx_buff->state) {
412 /* This is on the critical path, case are ordered by
413 * probability (most frequent first) - Jean II */
414 case INSIDE_FRAME:
415 /* Must be the next byte of the frame */
416 if (rx_buff->len < rx_buff->truesize) {
417 rx_buff->data[rx_buff->len++] = byte;
418#ifndef POSTPONE_RX_CRC
419 rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
420#endif
421 } else {
422 IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n",
423 __FUNCTION__);
424 rx_buff->state = OUTSIDE_FRAME;
425 }
426 break;
427
428 case LINK_ESCAPE:
429 /*
430 * Stuffed char, complement bit 5 of byte
431 * following CE, IrLAP p.114
432 */
433 byte ^= IRDA_TRANS;
434 if (rx_buff->len < rx_buff->truesize) {
435 rx_buff->data[rx_buff->len++] = byte;
436#ifndef POSTPONE_RX_CRC
437 rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
438#endif
439 rx_buff->state = INSIDE_FRAME;
440 } else {
441 IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n",
442 __FUNCTION__);
443 rx_buff->state = OUTSIDE_FRAME;
444 }
445 break;
446
447 case OUTSIDE_FRAME:
448 /* Activate carrier sense */
449 if(byte != XBOF)
450 irda_device_set_media_busy(dev, TRUE);
451 break;
452
453 case BEGIN_FRAME:
454 default:
455 rx_buff->data[rx_buff->len++] = byte;
456#ifndef POSTPONE_RX_CRC
457 rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
458#endif
459 rx_buff->state = INSIDE_FRAME;
460 break;
461 }
462}
463
464/*
465 * Function async_unwrap_char (dev, rx_buff, byte)
466 *
467 * Parse and de-stuff frame received from the IrDA-port
468 *
469 * This is the main entry point for SIR drivers.
470 */
471void async_unwrap_char(struct net_device *dev,
472 struct net_device_stats *stats,
473 iobuff_t *rx_buff, __u8 byte)
474{
475 switch(byte) {
476 case CE:
477 async_unwrap_ce(dev, stats, rx_buff, byte);
478 break;
479 case BOF:
480 async_unwrap_bof(dev, stats, rx_buff, byte);
481 break;
482 case EOF:
483 async_unwrap_eof(dev, stats, rx_buff, byte);
484 break;
485 default:
486 async_unwrap_other(dev, stats, rx_buff, byte);
487 break;
488 }
489}
490EXPORT_SYMBOL(async_unwrap_char);
491